--- title: How to create Users in Kubernetes the right way? url: https://devopstales.github.io/kubernetes/k8s-user-accounts/ date: 2022-03-22 keywords: Kubernetes, User, RBAC --- I this post I will show you how you can create Users in Kubernetes the right way. <!--more--> {{< content "/filedir/k8s-sec.html" >}} ### Users in Kubernetes All Kubernetes clusters have two categories of users: service accounts managed by Kubernetes, and normal users. Kubernetes does not have objects which represent normal user accounts. Normal users cannot be added to a cluster through an API call. ### So how we choud create an user account? Any user that presents a valid certificate signed by the cluster's certificate authority (CA) is considered authenticated. So you need to create a certificate for you username. ### Why I need a user account insted of service account? A service account is wisible and its token can be mounted in to a pod so theat pod has the same privileges as you. ### Generate new certificate First, we have to generate a private key and a certificate signing request: ```bash openssl genrsa -out devopstales.pem openssl req -new -key devopstales.pem -out devopstales.csr -subj "/CN=devopstales" ``` `devopstales` well be my username. You can add your user to specific groups by addin them as groups like `devops-groupe`: ```bash openssl req -new -key ivnilv.pem -out ivnilv.csr -subj "/CN=devopstales/O=devops-groupe" ``` ### Signing the certificate Use the csr file for generating a `CertificateSigningRequest` object n Kubernetes: ```bash cat devopstales.csr | base64 | tr -d '\n' cat <<'EOF'> devopstales-csr.yaml apiVersion: certificates.k8s.io/v1beta1 kind: CertificateSigningRequest metadata: name: user-request-devopstales spec: groups: - system:authenticated request: LS0tLS1CRUdJTi... usages: - digital signature - key encipherment - client auth EOF ``` OR from Kubernetes v1.22 (in this example it will expire after 10 years): ```bash cat devopstales.csr | base64 | tr -d '\n' cat <<'EOF'> devopstales-csr.yaml apiVersion: certificates.k8s.io/v1 kind: CertificateSigningRequest metadata: name: user-request-devopstales spec: groups: - system:authenticated request: LS0tLS1CRUdJTi... signerName: kubernetes.io/kube-apiserver-client expirationSeconds: 315569260 usages: - digital signature - key encipherment - client auth EOF ``` Create the `CertificateSigningRequest` and approve it. Then the Kubernetes api server will generate the certificate theat you can use to authentication. ```bash kubectl create -f devopstales-csr.yaml kubectl certificate approve user-request-devopstales kubectl get csr NAME AGE REQUESTOR CONDITION user-request-devopstales 1m admin Approved,Issued ``` Now the certificate should be signed. You can download the new signed public key from the csr resource: ```bash kubectl get csr user-request-devopstales -o jsonpath='{.status.certificate}' | base64 -d > devopstales-user.crt ``` ### Create new user config file ```bash kubectl --kubeconfig ~/.kube/config-devopstales config set-cluster preprod --insecure-skip-tls-verify=true --server=https://KUBERNETES-API-ADDRESS kubectl --kubeconfig ~/.kube/config-devopstales config set-credentials devopstales --client-certificate=devopstales-user.crt --client-key=devopstales.pem --embed-certs=true kubectl --kubeconfig ~/.kube/config-devopstales config set-context default --cluster=preprod --user=devopstales kubectl --kubeconfig ~/.kube/config-devopstales config use-context default ``` Ofcourse you need rbac for this user: ```yaml cat <<'EOF'> devopstales-rbac.yaml apiVersion: v1 kind: Namespace metadata: name: devopstales-ns spec: {} status: {} --- kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: name: devopstales namespace: devopstales-ns rules: - apiGroups: ["", "extensions", "apps"] resources: ["*"] verbs: ["*"] - apiGroups: ["batch"] resources: - jobs - cronjobs verbs: ["*"] --- kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: devopstales namespace: devopstales-ns subjects: - kind: User name: devopstales apiGroup: rbac.authorization.k8s.io roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: devopstales EOF kubectl apply -f devopstales-rbac.yaml ``` Let’s test if the new kubeconfig we generated worked fine: ```bash kubectl --kubeconfig ~/.kube/config-devopstales get pods ``` ### Conclusion As we can see creating certificate for all the users is a hard task for the administratos if we hawe many users. A better solution to use an sso based authentication proxy like my [Kubectl OpenID Connect](/kubernetes/kube-openid-connect-1.0/).