Creating credentials for Kubernetes users
It is considered best practice to create a new credential for each user of the cluster. This topic covers how to create a kubeconfig file for a user, which enables the user to connect into the cluster using their own credential.
z/OS® security administrator
Kubernetes administrator
The IBM® z/OS Control Plane Appliance (zCPA) supports X509 certificates to enable users of the cluster to be authenticated. The following example demonstrates how an X509 certificate for a new user can be signed by the cluster's certificate authority and embedded in a kubeconfig file, which the user can then use with the Kubectl for IBM z/OS (kubectl) command line utility, to interact with the cluster.
The example uses tools available on Linux® to generate a certificate signing request and create the kubeconfig file. Alternative tools are available for different operating systems. For more information, see https://kubernetes.io/docs/tasks/administer-cluster/certificates/.
- cfssl (generates a certificate signing request (CSR) and private key for the certificate)
- cfssljson (takes the JSON output from the cfssl tool and writes the private key and CSR to disk)
- base64 (converts output to/from base64)
- kubectl (CLI to manage the kubernetes cluster. Typically the kubectl user will need cluster administrator level access to add additional users to the cluster.)
Create a certificate signing request and private key
Run the following commands on a Linux system. The commands construct a certificate signing request for the user zos-user1 to add the user to a group called zos-admins. The output from the commands is two files: zos-user1.csr and zos-user1-key.pem (the certificate signing request and private key).
mkdir -p /tmp/zoscp/csrs
chmod 700 /tmp/zoscp
cd /tmp/zoscp/csrs
cat <<EOF >zos-user1-csr.json
{
"CN": "zos-user1",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"O": "zos-admins"
}
]
}
EOF
cfssl genkey zos-user1-csr.json | cfssljson -bare zos-user1
# cfssl genkey zos-user1-csr.json | cfssljson -bare zos-user1
2023/06/13 09:33:22 [INFO] generate received request
2023/06/13 09:33:22 [INFO] received CSR
2023/06/13 09:33:22 [INFO] generating key: rsa-2048
2023/06/13 09:33:24 [INFO] encoded CSR
# ls -l
-rw-r--r-- 1 root root 920 Jun 13 09:33 zos-user1.csr
-rw-r--r-- 1 root root 131 Jun 13 09:33 zos-user1-csr.json
-rw------- 1 root root 1679 Jun 13 09:33 zos-user1-key.pem
You have now created a certificate that has added the zos-user1 to the group called zos-admins.
Sign the certificate with the cluster's certificate authority
-
Example output:CSR=$(cat zos-user1.csr | base64 -w 0) cat <<EOF | kubectl apply -f - apiVersion: certificates.k8s.io/v1 kind: CertificateSigningRequest metadata: name: zos-user1 spec: request: $CSR signerName: kubernetes.io/kube-apiserver-client usages: - client auth EOFcertificatesigningrequest.certificates.k8s.io/zos-user1 created - Issue the following kubectl commands to view
the certificate signing request (note that its in Pending state) and then to approve the certificate
signing request. Wait until the csr is shown as Approved, Issued.
kubectl get csrkubectl certificate approve zos-user1
Example output:kubectl get csr# kubectl get csr NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION zos-user1 98s kubernetes.io/kube-apiserver-client kubernetes-admin <none> Pending # kubectl certificate approve zos-user1 certificatesigningrequest.certificates.k8s.io/zos-user1 approved # kubectl get csr NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION zos-user1 111s kubernetes.io/kube-apiserver-client kubernetes-admin <none> Approved,Issued
Create a kubeconfig file for zos-user1
- Run the following commands to setup environment variables containing the signed certificate,
the private key (base64 encoded), and cluster information from the current users kubeconfig file,
then create a new kubeconfig file for zos-user1, using the contents of those
environment variables.
CERTIFICATE=$(kubectl get csr zos-user1 -o go-template='{{index .status "certificate" }}') PRIVATE_KEY=$(cat /tmp/zoscp/csrs/zos-user1-key.pem | base64 -w 0) CLUSTER_NAME=$(kubectl config view --raw -o=go-template='{{range .contexts}}{{if eq .name "'''$(kubectl config current-context)'''"}}{{.context.cluster}}{{end}}{{end}}') CLUSTER_CERT_AUTH_DATA=$(kubectl config view --raw -o=go-template='{{range .clusters}}{{if eq .name "'''${CLUSTER_NAME}'''"}}{{index .cluster "certificate-authority-data" }}{{end}}{{end}}') CLUSTER_SERVER=$(kubectl config view --raw -o=go-template='{{range .clusters}}{{if eq .name "'''${CLUSTER_NAME}'''"}}{{.cluster.server}}{{end}}{{end}}') cat << EOF >/tmp/zoscp/zos-user1.kubeconfig apiVersion: v1 kind: Config clusters: - name: ${CLUSTER_NAME} cluster: certificate-authority-data: ${CLUSTER_CERT_AUTH_DATA} server: ${CLUSTER_SERVER} contexts: - name: ${CLUSTER_NAME} context: cluster: ${CLUSTER_NAME} user: zos-user1 current-context: ${CLUSTER_NAME} users: - name: zos-user1 user: client-certificate-data: $CERTIFICATE client-key-data: $PRIVATE_KEY EOF chmod 700 /tmp/zoscp/zos-user1.kubeconfig - The file /tmp/zoscp/zos-user1.kubeconfig should now exist. Check that it
exists by using the following command:
Example output:ls -l /tmp/zoscp/zos-user1.kubeconfig-rw------- 1 root root 5540 Jun 13 09:49 /tmp/zoscp/zos-user1.kubeconfig
Test the new kubeconfig file
- Run the following command to try out the new kubeconfig file and check if the user is authorized to view pods in the cluster.
Example output:kubectl --kubeconfig /tmp/zoscp/zos-user1.kubeconfig auth can-i get pods# kubectl --kubeconfig /tmp/zoscp/zos-user1.kubeconfig auth can-i get pods no
You have now created an additional kubeconfig file for the user zos-user1. The kubeconfig file should be provided to the user who then makes a copy within ~/.kube/config on their system, and ensure the permissions are restricted to only their user ID. This kubeconfig enables the user to use kubectl to connect into the cluster using their own credential.
You should now configure zos-user1 to be part of a group. For more information, see Giving role based access control.