If you found value in this post, consider following me on X @davidpuplava for more valuable information about Game Dev, OrchardCore, C#/.NET and other topics.
If you routinely access a kubernetes cluster but often first need to ssh into a node within the cluster to run kubectl
commands, then this post is for you. It covers the steps necessary for you to configure kubectl
cli to remotely control a cluster from your own machine. Ideally, you are the person who setup but the kubernetes cluster and have admin privileges to configure access. If not, this article will be of little help.
First, you must install the kubectl
command line tool for your envrinoment.
On macOS, you can use install kubectl
using Homebrew with the following command
brew install kubectl
If you use another platform, or don't want to use Homebrew, you can find other ways to install kubectl
in kubernetes official documentation: https://kubernetes.io/docs/tasks/tools/install-kubectl/
Once installed, you can ensure the everything is running correctly by executing
kubectl version --client
You should see output similar to
Client Version: version.Info{Major:"1", Minor:"16+", GitVersion:"v1.16.6-beta.0", GitCommit:"e7f962ba86f4ce7033828210ca3556393c377bcc", GitTreeState:"clean", BuildDate:"2020-01-15T08:26:26Z", GoVersion:"go1.13.5", Compiler:"gc", Platform:"darwin/amd64"}
First, check your current configuration. If you just installed kubectl
as part of this tutorial then you likely have a basic configuration.
Run the following command
kubectl config view
You should see output similar to
apiVersion: v1
clusters:
- cluster:
certificate-authority: /Users/david/.minikube/ca.crt
server: https://192.168.64.3:8443
name: minikube
contexts:
- context:
cluster: minikube
user: minikube
name: minikube
current-context: ""
kind: Config
preferences: {}
users:
- name: minikube
user:
client-certificate: /Users/david/.minikube/cli
Here you see that my kubectl
configuration is already aware of a minikube
cluster which was previously setup.
Before you can configure kubectl
, you must ensure you have user credentials for accessing your remote cluster through the Kubernetes API. For more information, you can read the full Kubernetes Documentation.
There are multiple ways you can configure your cluster for authenticating human users e.g. certificates, tokens, basic auth etc. See the Kubernetes document on Authentication strategies for more information.
In this post, you will configure a client certificate for user authentication.
To complete this step, you'll use openssl
to generate the certificate signing request (CSR). Feel free to use any other tool you like to generate the CSR.
Run the following command to generate a new key for your new user. Here the name david
is just the name of the user you will create, but feel free to change it for your particular use case.
openssl genrsa -out david.key 2048
This generates a 2048 bit RSA private key and stores it in the file named david.key
. You can use whatever file name you want and any greater number of bits if you'd like (e.g. 4096).
Now that you have a private key stored in a file, you can use it to create a certificate signing request and submit it to your kubernetes cluster for approval.
Run the following command to create the certificate signing request using the filename of the key you created in the previous step as the input for the -key
parameter.
openssl req -new -key david.key -out david.csr -subj "/CN=david/O=system:masters"
This creates a file david.csr
that stores the contents of the certificate signing request. You can use any name that makes sense for your use case.
By using the -subj
flag, you can set the values necessary for your new user account. The value for the /CN
attribute is the username you want, in this case david
. The value for the /O
attribute is the group in which to place the user. In this case system:masters
; note, this is the cluster admin group so beware! For more information on groups, check out https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles.
In this section, you'll create a kubernetes certificate signing request object and apply it to your cluster for appoval by a kubernetes admin user. First, you'll draft a yaml file with the k8s object and then apply it to the cluster.
If you are using a bash shell, you can follow these steps exactly. If you are not using bash, you will have to encode the contents of the david.csr
file as a base64 string and manually add it to the request
part of the yaml file.
cat <<EOF > david-csr.yaml
apiVersion: certificates.k8s.io/v1beta1
kind: CertificateSigningRequest
metadata:
name: david
spec:
groups:
- system:authenticated
request: $(cat david.csr | base64 | tr -d '\n')
usages:
- client auth
EOF
You can copy/paste this to a text editor and modify the values to match your use case. You can also type it out line by line. The key is the request: $(cat david.csr | base64 | tr -d '\n')
which is what base64 encodes the actual CSR and put's it into the kubernetes yaml file. This file david-csr.yaml
can now be applied to the cluster to submit the CSR request.
You can run the following to submit the CSR request object to kubernetes
kubectl apply -f david-csr.yaml
You will something similiar to the following to let you know everything was submitted.
certificatesigningrequest.certificates.k8s.io/david created
You can check the status of the request by running this and getting the following output.
$ kubectl get csr
NAME AGE REQUESTOR CONDITION
david 9s kubernetes-admin Pending
You can approve the user's CSR by doing the following
$ kubectl certificate approve david
certificatesigningrequest.certificates.k8s.io/david approved
Ensure your request was approved correctly, run the following
kubectl get csr/david -o yaml
If you do not see any output, or receive a No resources found
messages, then the request approval failed. You'll have to retrace your steps and figure out what is wrong with the request. The first time I attempted this, I used the cluster role cluster-admin
instead of the cluster role binding system:masters
for the /O=
attribute of the CSR.
Now that the certificate request is approved and fulfilled, you can pull down the certificate onto your local machine and configure your kubectl to use it.
After running the following command
kubectl get csr/david -o jsonpath='{.status.certificate}' | base64 --decode > david-access.crt
you'll have the user certificate for david
in a file named david-access.crt
. This will allow you to set a credential in kubectl.
Run the following to set the credential for user david
$ kubectl config set-credentials david --client-key=./david.key --client-certificate=./david-access.crt --embed-certs=true
User "david" set.
Next, you can create a context in which you can operate on your cluster as that user.
$ kubectl config set-context david --cluster=kubernetes --user=david
Context "david" created.
Test it out by running the following
$ kubectl config use-context david
Switched to context "david".
Try running a few commands to see if it works!
If you found value in this post, consider following me on X @davidpuplava for more valuable information about Game Dev, OrchardCore, C#/.NET and other topics.