If you have a lot of Kubernetes clusters, sometimes you need to use the straightforward
kubectl command to access your cluster. This might be because a simple command-line tool is often better or faster, but some operations, even inside other more advanced tools, are slow or can lead to syntax errors in YAML.
[ Get the YAML cheat sheet. ]
Did you know you can use the OpenShift command line tool
oc instead of
kubectl to access your Kubernetes cluster? With
oc, you can inject a secret, configmap, or volume directly inside a deployment with a single command, open an interactive shell faster with
rsh, inspect a plain decoded secret, or link a secret to a ServiceAccount for authentication.
If you want to follow these examples, you can download the OpenShift client from the Red Hat Portal (login required) or the okd client from the OKD repository. I ran the examples in this tutorial inside a minikube running Kubernetes version 1.24.
[ For more on minikube, read Start learning Kubernetes from your local machine. ]
You probably notice that
oc is shorter than
kubectl, so it is faster to type. But you can always create an alias to overcome this "problem." What are some useful differences between
Inject a secret or configmap into a deployment
How often do you need to edit your manifest to add some environment variables? You can use this
oc trick: Inject a secret or a configmap into an existing pod or deployment's pod environment variables with a single command.
I'll create a MySQL deployment using the
oc client and purposely forget to set the required variables:
$ oc create deploy mysql --image mysql:5.7 deployment.apps/mysql created
The deployment fails to start:
$ oc get pods NAME READY STATUS RESTARTS AGE Mysql-ffb7… 0/1 CrashLoopBackOff 1 (2s ago) 31s
I need to create a secret:
$ cat > mysql.env <<EOF MYSQL_ROOT_PASSWORD=k8s MYSQL_USER=k8s MYSQL_PASSWORD=k8s MYSQL_DATABASE=k8s EOF $ oc create secret generic mysql.env --from-env-file mysql.env
Now that the secret exists inside Kubernetes, use the subcommand
set env to attach it to the MySQL deployment:
$ oc set env --from secret/mysql.env deploy/mysql
Wait several seconds and observe that the deployment is running and the specified environment variables are configured:
$ oc set env --from secret/mysql.env deploy/mysql deployment.apps/mysql updated $ oc get pods NAME READY STATUS RESTARTS AGE mysql-56db5fbf6c-52ptv 1/1 Running 0 10s $ oc describe deploy/mysql | grep Environment: -A4 Environment: MYSQL_ROOT_PASSWORD: <set to the key 'MYSQL_ROOT_PASSWORD' in secret 'mysql.env'> Optional: false MYSQL_USER: <set to the key 'MYSQL_USER' in secret 'mysql.env'> Optional: false MYSQL_DATABASE: <set to the key 'MYSQL_DATABASE' in secret 'mysql.env'> Optional: false MYSQL_PASSWORD: <set to the key 'MYSQL_PASSWORD' in secret 'mysql.env'> Optional: false
You can do the same thing with a configmap.
[ Get the Kubernetes basics cheat sheet. ]
Attach a volume to a deployment
This tip is very powerful and useful when you are testing. Attach a volume to a pod or deployment with a single command. The attached volume can be an existing secret, configmap, or persistentvolumeclaim (PVC), or you can even create a new PVC. Here's an example:
$ oc set volume --add --claim-size 1Gi --mount-path /var/lib/mysql deploy/mysql info: Generated volume name: volume-xxj6r deployment.apps/mysql volume updated
Wait several seconds, and you can describe the deployment or use a more elegant method with
oc set volumes deploy/mysql --all to see the volume. Here are some examples:
$ oc set volumes deploy/mysql --all mysql pvc/pvc-b5vlg (allocated 1GiB) as volume-xxj6r mounted at /var/lib/mysql $ oc describe deploy/mysql | grep Volumes: -A4 Volumes: volume-xxj6r: Type: PersistentVolumeClaim (a reference to a PVC in the same namespace) ClaimName: pvc-b5vlg ReadOnly: false
You can specify an existing PVC with
--claim-name, a secret with
--secret-name, or a configmap with
[ Get this complimentary eBook from Red Hat: Managing your Kubernetes clusters for dummies. ]
Inspect a secret
This is one of my favorite tricks to verify secrets. To see a secret with
kubectl, I first need to display the secret and then convert it from Base64. With
oc, I can see it directly in the terminal or put it inside a file:
$ oc extract secret/mysql.env --to=-
In this case, because I am using
--to=-, the output is displayed in the terminal:
# MYSQL_ROOT_PASSWORD k8s # MYSQL_USER k8s # MYSQL_DATABASE k8s # MYSQL_PASSWORD k8s
This method is very useful to quickly inspect a secret with a frequently used password or a token.
[ Getting started with containers? Check out Deploying containerized applications: A technical overview. ]
Enter a container
To enter a container or access a shell inside a container, use the command
$ kubectl exec -ti deploy/mysql -- sh
If your intention is just that, you can do it a bit faster with
$ oc rsh deploy/mysql
The remote shell (
rsh) command allocates a pseudo
stdin open, and initializes the
sh command. You can change the default command to any other; just specify it as the last argument.
Link or unlink an authentication to a ServiceAccount
This tip is more specific but can be helpful if you use a lot of private external registries. You can attach a secret to a Kubernetes ServiceAccount (SA) for authentication purposes with
First, I'll create a deployment with a private image. If you want to follow along, you will need your own private image:
$ oc create deploy lua --image hectorvido/lua-app deployment.apps/lua created
There is a problem downloading the image:
$ oc get pods NAME READY STATUS RESTARTS AGE lua-7df97f9c94-4zjr6 0/1 ImagePullBackOff 0 20s mysql-769f4d56b7-95p5z 1/1 Running 0 5m1s
To solve this, add a
docker-registry secret to the default ServiceAccount. Do this by creating a secret and editing the ServiceAccount or using the
oc client. Of course, I will not share my credentials here; the sensitive information is hidden:
$ oc create secret docker-registry dockerhub \ --docker-username hectorvido \ --docker-password '<hidden>' \ --docker-server docker.io secret/dockerhub created $ oc secrets link default dockerhub --for=pull
The magic here is the
oc secrets link command. It will add the secret to the SA, telling it that this secret is used exclusively to download images from image repositories. After that, I delete the pod to force another download try:
$ oc delete pod -l app=lua pod "lua-7df97f9c94-4zjr6" deleted $ oc get pods NAME READY STATUS RESTARTS AGE lua-7df97f9c94-msjzp 1/1 Running 0 22s mysql-769f4d56b7-95p5z 1/1 Running 0 8m18s
As you can see, the
oc command can be used with OpenShift and Kubernetes and is faster to type. This interoperability is just a minor detail. I gave five tips that can speed up your tests or even daily tasks with
oc set env- Inject a secret or configmap into a container environment.
oc set volume- Attach a PVC, configmap, or secret into a pod.
oc extract- Easily display secrets.
oc rsh- Enter a container with fewer parameters.
oc secrets link- Link a secret to a ServiceAccount for authentication purposes.
There are more options, but they are exclusive to OpenShift administration, whereas these work in Kubernetes as well. Knowing this, why not try
oc in your work starting today?
[ Learning path: Getting started with Red Hat OpenShift Service on AWS (ROSA) ]