Skip to main content

5 tips for using oc to work faster in Kubernetes

Swap the kubectl command for OpenShift's oc tool to speed up daily tasks and testing in Kubernetes.
A ball with light rays coming out from it

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 oc and kubectl?

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
Mysql-ffb7… 0/1  CrashLoopBackOff 1 (2s ago) 31s

I need to create a secret:

$ cat > mysql.env <<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
mysql-56db5fbf6c-52ptv   1/1 	Running   0      	10s

$ oc describe deploy/mysql | grep Environment: -A4
      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
  pvc/pvc-b5vlg (allocated 1GiB) as volume-xxj6r
    mounted at /var/lib/mysql

$ oc describe deploy/mysql | grep Volumes: -A4
    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 --configmap-name.

[ 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:


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 exec:

$ kubectl exec -ti deploy/mysql -- sh

If your intention is just that, you can do it a bit faster with oc:

$ oc rsh deploy/mysql

The remote shell (rsh) command allocates a pseudo tty, keeps 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 oc.

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>' \
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

Wrap up

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:

  • 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)

Check out these related articles on Enable Sysadmin

Topics:   Kubernetes   OpenShift  
Author’s photo

Hector Vido

Hector Vido serves as a consultant on the Red Hat delivery team. He started in 2006 working with development and later on implementation, architecture, and problem-solving involving databases and other solutions, always based on free software. More about me

Red Hat Summit 2022: On Demand

Get the latest on Ansible, Red Hat Enterprise Linux, OpenShift, and more from our virtual event on demand.

Related Content


Privacy Statement