Cyber Deals - Get up to 65% off on CKA, CKAD, CKS, KCNA, KCSA exams and courses!

kubectl and oc Cheat Sheet

oc (OpenShift CLI) and kubectl share most commands. oc extends Kubernetes with OpenShift-specific features — cluster login, projects, routes, builds, image streams, DeploymentConfig, and oc adm administration. Where a command works identically in both tools, a single block is shown. All commands validated against official docs: OCP 4.18 CLI reference and kubectl quick-reference.

Also see: Docker & Podman Cheatsheet



Installation

oc:

# Download from the cluster web console (?  menu → Command-line tools)
# or from mirror.openshift.com

# RHEL / Fedora
sudo dnf install openshift-clients

# macOS
brew install openshift-cli

kubectl:

# Linux (latest stable)
curl -LO "https://dl.k8s.io/release/$(curl -sL https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl && sudo mv kubectl /usr/local/bin/

# RHEL / Fedora
sudo dnf install kubernetes-client

# macOS
brew install kubectl

Version & Help

oc:

oc version                        # client and server versions
oc help
oc <command> --help
oc explain <resource>             # API docs for a resource type
oc explain pod.spec.containers    # docs for a nested field
oc types                          # list all OCP resource types and concepts

kubectl:

kubectl version
kubectl version --client          # client version only
kubectl version -o yaml
kubectl cluster-info
kubectl help
kubectl <command> --help
kubectl explain <resource>
kubectl explain pod.spec.containers
kubectl explain deployment --recursive
kubectl api-resources             # list all available resource types
kubectl api-resources --namespaced=true
kubectl api-resources --api-group=apps
kubectl api-versions              # list all API versions

Login & Authentication

oc login is OCP-specific. kubectl uses kubeconfig directly.

oc:

oc login <cluster-url>                              # prompt for user/pass
oc login <cluster-url> -u <user> -p <password>
oc login <cluster-url> --token=<token>
oc login <cluster-url> --insecure-skip-tls-verify
oc logout

oc whoami                         # current user
oc whoami -t                      # current OAuth token
oc whoami --show-server           # API server URL
oc whoami --show-console          # web console URL

kubectl — check current identity:

kubectl auth whoami               # user, groups, and extra attributes (k8s 1.28+)

Context & Config

oc:

oc config view
oc config get-contexts
oc config current-context
oc config use-context <name>

kubectl:

kubectl config view
kubectl config view --raw
kubectl config get-contexts
kubectl config get-contexts -o name
kubectl config current-context
kubectl config use-context <context-name>
kubectl config set-context --current --namespace=<namespace>
kubectl config set-context <name> --namespace=<ns> --cluster=<c> --user=<u>
kubectl config rename-context <old> <new>
kubectl config delete-context <name>
kubectl config delete-cluster <name>
kubectl config delete-user <name>
kubectl config set-credentials <name> --token=<token>
kubectl config unset users.foo

Namespaces / Projects

OpenShift Projects wrap Kubernetes namespaces with added metadata, quota defaults, and network policy.

oc:

oc projects                       # list all projects (note: plural)
oc project <name>                 # switch to a project
oc new-project <name>
oc new-project <name> --display-name='Name' --description='text'
oc status
oc status -v

oc adm (admin only):

oc adm new-project <name>
oc adm new-project <name> --admin=<user>
oc adm new-project <name> --node-selector=<selector>

kubectl:

kubectl get namespaces            # alias: ns
kubectl create namespace <name>
kubectl delete namespace <name>
kubectl config set-context --current --namespace=<name>

Viewing Resources

Both tools share the same verbs: get, describe, edit, delete, patch, apply.

oc get all                        # all common resources in current project
kubectl get all -n <namespace>

# Output formats
kubectl get pods -o wide          # extra columns: node, IP
kubectl get pods -o yaml
kubectl get pods -o json
kubectl get pods -o name          # resource/name pairs
kubectl get pods -o jsonpath='{.items[*].metadata.name}'
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}'
kubectl get pods -o custom-columns=NAME:.metadata.name,STATUS:.status.phase

# Filtering
kubectl get pods --show-labels
kubectl get pods -l app=nginx
kubectl get pods -l 'env in (production,staging)'
kubectl get pods --selector=app=nginx
kubectl get pods --field-selector=status.phase=Running
kubectl get pods --field-selector=spec.nodeName=node1
kubectl get pods --no-headers

# Watching & scope
kubectl get pods -w               # watch for changes
kubectl get pods -A               # all namespaces (--all-namespaces)
kubectl get pods -A -o wide
kubectl get pods --sort-by='.status.containerStatuses[0].restartCount'

Nodes

oc:

oc get nodes
oc get nodes --show-labels
oc get nodes -L region -L env     # show specific labels as columns
oc get node/<node-name> -o yaml
oc describe node <node-name>

oc adm cordon <node-name>
oc adm uncordon <node-name>
oc adm drain <node-name> --ignore-daemonsets --delete-emptydir-data
oc adm drain <node-name> --force
oc adm drain <node-name> --timeout=120s --grace-period=30

oc adm taint nodes <node-name> key=value:NoSchedule
oc adm taint nodes <node-name> key=value:NoExecute
oc adm taint nodes <node-name> key=value:PreferNoSchedule
oc adm taint nodes <node-name> key:NoSchedule-      # remove taint (trailing -)

kubectl:

kubectl get nodes
kubectl get nodes --show-labels
kubectl describe node <node-name>

kubectl cordon <node-name>
kubectl uncordon <node-name>
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data
kubectl drain <node-name> --force
kubectl drain <node-name> --timeout=120s --grace-period=30

kubectl taint nodes <node-name> key=value:NoSchedule
kubectl taint nodes <node-name> key=value:NoExecute
kubectl taint nodes <node-name> key=value:PreferNoSchedule
kubectl taint nodes <node-name> key:NoSchedule-     # remove taint (trailing -)

Pods

oc:

oc get pods
oc get pods -n <project> -o wide
oc get pods --show-labels
oc get pods -l app=myapp
oc describe pod <pod-name>

oc logs <pod-name>
oc logs <pod-name> -c <container>
oc logs <pod-name> --previous
oc logs -f <pod-name>
oc logs <pod-name> --tail=100
oc logs <pod-name> --since=1h
oc logs <pod-name> --timestamps

oc rsh <pod-name>                 # remote shell (OCP-specific)
oc rsh -c <container> <pod-name>
oc exec <pod-name> -- <command>
oc exec <pod-name> -c <container> -it -- /bin/bash

oc cp <pod-name>:/remote/path ./local
oc cp ./local <pod-name>:/remote/path
oc cp -c <container> <pod-name>:/remote/path ./local

oc port-forward <pod-name> 8080:80
oc port-forward svc/<name> 8080:80

oc debug pod/<pod-name>
oc debug node/<node-name>
oc debug deployment/<name> --as-root

oc delete pod <pod-name>
oc delete pod <pod-name> --grace-period=0 --force

kubectl:

kubectl get pods
kubectl get pods -n <namespace> -o wide
kubectl get pods --show-labels
kubectl get pods -l app=myapp
kubectl describe pod <pod-name>

kubectl logs <pod-name>
kubectl logs <pod-name> -c <container>
kubectl logs <pod-name> --previous
kubectl logs -f <pod-name>
kubectl logs <pod-name> --tail=100
kubectl logs <pod-name> --since=1h
kubectl logs <pod-name> --since-time=2024-01-01T00:00:00Z
kubectl logs <pod-name> --timestamps
kubectl logs -l app=nginx --all-containers=true

kubectl exec <pod-name> -- <command>
kubectl exec <pod-name> -c <container> -- <command>
kubectl exec -it <pod-name> -- /bin/bash
kubectl exec -it <pod-name> -c <container> -- /bin/sh

kubectl cp <pod-name>:/remote/path ./local
kubectl cp ./local <pod-name>:/remote/path
kubectl cp ./local <pod-name>:/remote/path -c <container>

kubectl port-forward <pod-name> 8080:80
kubectl port-forward <pod-name> 8080          # host port same as container port
kubectl port-forward deployment/<name> 8080:80
kubectl port-forward svc/<name> 8080:80
kubectl port-forward <pod-name> 8080:80 --address 0.0.0.0

kubectl debug <pod-name> -it --image=busybox
kubectl debug <pod-name> --copy-to=debug-pod --image=busybox
kubectl debug <pod-name> -it --target=<container>
kubectl debug node/<node-name> -it --image=ubuntu

kubectl delete pod <pod-name>
kubectl delete pod <pod-name> --grace-period=0 --force
kubectl delete pods -l app=myapp
kubectl delete pods --all

Static Pods — managed by kubelet directly from a manifest file:

kubectl run static-pod \
  --restart=Never \
  --image=busybox \
  --dry-run=client -o yaml \
  -- sleep 3600 \
  > /etc/kubernetes/manifests/static-pod.yaml

Deployments

oc — DeploymentConfig (OCP-specific resource):

oc get dc                         # list DeploymentConfigs
oc describe dc <name>
oc rollout latest dc/<name>       # trigger a new deployment (DC equivalent of restart)
oc rollout status dc/<name>
oc rollout history dc/<name>
oc rollout undo dc/<name>
oc rollout undo dc/<name> --to-revision=2
oc rollout pause dc/<name>
oc rollout resume dc/<name>
oc rollout cancel dc/<name>
oc set image dc/<name> <container>=<image>:<tag>
oc scale dc/<name> --replicas=3

oc & kubectl — Deployment (standard Kubernetes):

oc get deployments
kubectl get deployments           # alias: deploy

kubectl create deployment myapp --image=nginx:1.27
kubectl apply -f deployment.yaml
kubectl replace -f deployment.yaml
kubectl replace --force -f deployment.yaml

kubectl set image deployment/<name> <container>=<image>:<tag>

kubectl rollout status deployment/<name>
kubectl rollout status daemonset/<name>
kubectl rollout history deployment/<name>
kubectl rollout history deployment/<name> --revision=2
kubectl rollout undo deployment/<name>
kubectl rollout undo deployment/<name> --to-revision=2
kubectl rollout restart deployment/<name>   # Deployment / DaemonSet / StatefulSet ONLY
                                            # NOT valid for DeploymentConfig
kubectl rollout pause deployment/<name>
kubectl rollout resume deployment/<name>

kubectl delete deployment <name>

kubectl run nginx --image=nginx               # creates a Deployment
kubectl run nginx --image=nginx --restart=Never  # creates a Pod (not Deployment)
kubectl run -it busybox --image=busybox -- sh
kubectl run nginx --image=nginx --dry-run=client -o yaml

Services

oc get svc
kubectl get services              # alias: svc

kubectl expose deployment myapp --port=80 --target-port=8080
kubectl expose deployment myapp --port=80 --type=NodePort

kubectl describe svc <name>
kubectl delete svc <name>

Routes (OCP) / Ingress (K8s)

oc — Routes:

oc expose svc/<name>
oc expose svc/<name> --hostname=myapp.apps.example.com --port=<port>
oc expose dc/<name>

oc get routes
oc describe route <name>
oc delete route <name>

# A/B traffic splitting
oc set route-backends <route> app-v1=80 app-v2=20

kubectl — Ingress:

kubectl get ingress               # alias: ing
kubectl describe ingress <name>
kubectl apply -f ingress.yaml
kubectl delete ingress <name>

Storage — PV & PVC

oc get pv                         # PersistentVolumes (cluster-wide)
kubectl get pv

oc get pvc -n <project>           # PersistentVolumeClaims
kubectl get pvc -n <namespace>

oc get storageclass
kubectl get storageclass          # alias: sc

kubectl apply -f pv.yaml
kubectl apply -f pvc.yaml
kubectl describe pvc <name>
kubectl delete pvc <name>

Add a PVC to a deployment (oc):

oc set volumes deployment/<name> \
  --add \
  --name my-pv-storage \
  --type pvc \
  --claim-class nfs-storage \
  --claim-mode rwo \
  --claim-size 10Gi \
  --mount-path /var/data \
  --claim-name my-pv-claim

ConfigMaps

# Create
kubectl create configmap <name> --from-literal=key1=value1
kubectl create configmap <name> --from-literal=key1=val1 --from-literal=key2=val2
kubectl create configmap <name> --from-file=app.properties
kubectl create configmap <name> --from-env-file=./env.txt

oc create configmap <name> --from-literal=key1=value1 --from-file=config.txt

# View
kubectl get configmap             # alias: cm
kubectl get configmap <name> -o yaml
kubectl describe configmap <name>

# Delete
kubectl delete configmap <name>

# Mount as volume on a DC (oc)
oc set volumes dc/<name> \
  --add \
  --type configmap \
  --mount-path /etc/config \
  --configmap-name <configmap-name> \
  --name app-config

# Set as env vars
oc set env dc/<name> --from=configmap/<configmap-name>
kubectl set env deployment/<name> --from=configmap/<configmap-name>

Secrets

# Create
kubectl create secret generic <name> --from-literal=username=admin --from-literal=password=s3cr3t
kubectl create secret generic <name> --from-file=./secret.txt
kubectl create secret docker-registry <name> \
  --docker-server=myregistry.example.com \
  --docker-username=myuser \
  --docker-password=mypassword
kubectl create secret tls <name> --cert=tls.crt --key=tls.key

oc create secret generic <name> --from-literal=key=value

# View (values are base64-encoded)
kubectl get secrets
kubectl get secret <name> -o yaml
kubectl describe secret <name>    # does not reveal values

# Delete
kubectl delete secret <name>

# Reference in a pod spec — at same level as 'containers'
#   imagePullSecrets:
#   - name: <secret-name>

# Mount as volume (oc)
oc set volumes dc/<name> \
  --add \
  --type secret \
  --secret-name <secret-name> \
  --mount-path /etc/secrets \
  --name my-secret-vol

# Set as env vars
oc set env dc/<name> --from=secret/<secret-name>
kubectl set env deployment/<name> --from=secret/<secret-name>

Labels & Annotations

# Add / update labels
kubectl label pod/<name> key=value
kubectl label pod/<name> key=value --overwrite
kubectl label node/<name> disktype=ssd
kubectl label pod/<name> key-                 # remove label (trailing -)

oc label <resource> <name> key=value --overwrite
oc label pod <name> env-                      # remove label

# Filter by label
kubectl get pods -l env=dev
kubectl get pods -l 'env in (dev,staging)'
kubectl get pods --show-labels

# Patch
kubectl patch node <node-name> -p '{"metadata":{"labels":{"project":"myapp"}}}'
kubectl patch pod <pod-name> --type='json' \
  -p='[{"op":"replace","path":"/spec/containers/0/image","value":"nginx:1.27"}]'

# Annotations
kubectl annotate pod/<name> description="my pod"
kubectl annotate pod/<name> description="my pod" --overwrite
kubectl annotate pod/<name> description-      # remove annotation

oc annotate <resource> <name> key=value --overwrite
oc annotate <resource> <name> key-           # remove annotation

Environment Variables

oc:

oc set env dc/<name> KEY=VALUE
oc set env dc/<name> KEY1=VAL1 KEY2=VAL2
oc set env dc/<name> KEY-                    # remove (trailing -)
oc set env dc/<name> --from=configmap/<name>
oc set env dc/<name> --from=secret/<name>

kubectl:

kubectl set env deployment/<name> KEY=VALUE
kubectl set env deployment/<name> KEY-
kubectl set env deployment/<name> --from=configmap/<name>
kubectl set env deployment/<name> --from=secret/<name>

RBAC & Access Control

# Create roles
kubectl create role <name> --verb=get,list,watch --resource=pods -n <ns>
kubectl create clusterrole <name> --verb=get,list,watch --resource=pods,services

# Create bindings
kubectl create rolebinding <name> --role=<role> --user=<user> -n <ns>
kubectl create rolebinding <name> --role=<role> --serviceaccount=<ns>:<sa> -n <ns>
kubectl create clusterrolebinding <name> --clusterrole=<role> --user=<user>
kubectl create clusterrolebinding <name> --clusterrole=<role> --group=<group>
kubectl create clusterrolebinding <name> --clusterrole=<role> --serviceaccount=<ns>:<sa>

# View
kubectl get rolebinding -n <namespace>
kubectl get clusterrolebinding
kubectl describe rolebinding <name> -n <namespace>

# oc adm policy shortcuts
oc adm policy add-role-to-user <role> <user> -n <project>
oc adm policy add-role-to-group <role> <group> -n <project>
oc adm policy remove-role-from-user <role> <user> -n <project>
oc adm policy add-cluster-role-to-user <cluster-role> <user>
oc adm policy add-cluster-role-to-group <cluster-role> <group>
oc adm policy remove-cluster-role-from-user <cluster-role> <user>
oc adm policy remove-cluster-role-from-group <cluster-role> <group>
oc adm policy who-can <verb> <resource> -n <project>
oc adm policy who-can <verb> <resource> --all-namespaces

oc get serviceaccounts            # alias: sa
oc get clusterrole

# Check access
kubectl auth can-i create pods
kubectl auth can-i create pods --as=user1
kubectl auth can-i create pods -n <namespace>
kubectl auth can-i '*' '*'
kubectl auth can-i list secrets --as=system:serviceaccount:default:my-sa
kubectl auth reconcile -f rbac.yaml

Security Context Constraints (OCP)

OCP-specific. Kubernetes equivalent is Pod Security Admission (PSA).

oc get scc                        # list all SCCs
oc describe scc <scc-name>

oc adm policy add-scc-to-user <scc> <user>
oc adm policy add-scc-to-user <scc> -z <serviceaccount> -n <project>
oc adm policy remove-scc-from-user <scc> <user>

Scaling & HPA

oc:

oc scale dc/<name> --replicas=3
oc scale deployment/<name> --replicas=3
oc scale --replicas=0 -f file.yaml

oc autoscale dc/<name> --min=2 --max=10 --cpu-percent=80
oc autoscale deployment/<name> --min=2 --max=10 --cpu-percent=80
oc get hpa
oc describe hpa <name>

kubectl:

kubectl scale deployment/<name> --replicas=3
kubectl scale replicaset/<name> --replicas=3
kubectl scale statefulset/<name> --replicas=3
kubectl scale -f manifest.yaml --replicas=3
kubectl scale deployment/<name> --current-replicas=2 --replicas=3
kubectl scale deployment/<name> --replicas=0     # scale to zero

kubectl autoscale deployment/<name> --min=2 --max=10 --cpu-percent=80
kubectl autoscale replicaset/<name> --max=5
kubectl get hpa
kubectl describe hpa <name>
kubectl delete hpa <name>

Events & Troubleshooting

# Events
kubectl events -n <namespace>           # k8s 1.26+
kubectl events --for=pod/<pod-name>
kubectl events --for=deployment/<name>
kubectl events --types=Warning
kubectl events --watch
kubectl get events --sort-by=.lastTimestamp   # older form, always works

oc get events

# Resource usage
kubectl top nodes
kubectl top pods
kubectl top pods --all-namespaces
kubectl top pods -l app=myapp
kubectl top pod <pod-name> --containers

oc adm top nodes
oc adm top nodes --selector=<label>
oc adm top pods -n <project>
oc adm top pods --all-namespaces --containers

# Resource quotas
kubectl describe resourcequota -n <namespace>
kubectl get quota -n <namespace>
oc describe quota -n <project>
oc get quota -n <project>

# Limit ranges
kubectl get limitrange -n <namespace>
kubectl describe limitrange -n <namespace>
oc get limits -n <project>

# Cluster resource quotas (OCP)
oc get clusterresourcequota
oc describe clusterresourcequota <name>

# Dry run
kubectl apply -f resource.yaml --dry-run=client
kubectl apply -f resource.yaml --dry-run=server
oc apply -f resource.yaml --dry-run=client

# Verbose output
kubectl get pods -v=6
oc get pods --loglevel=6

# Must-gather (OCP) — collect diagnostic data
oc adm must-gather
oc adm must-gather --image=<custom-image>
oc adm must-gather --dest-dir=./must-gather-output

OCP — Applications, Builds & Templates

Creating Applications

oc new-app <image>
oc new-app <image> -e KEY=VAL --strategy=docker
oc new-app <repo-url> --name=<name>
oc new-app --template=<template-name> -p PARAM=value

BuildConfigs & Builds

oc get bc                         # list BuildConfigs
oc get builds

oc new-build <repo> --name=<name> --strategy=docker
oc new-build <repo> --name=<name> --strategy=source

oc start-build <bc-name>
oc start-build <bc-name> --follow --wait
oc start-build <bc-name> --from-file=<local-file>
oc cancel-build <build-name>

oc logs bc/<name> -f
oc logs build/<build-name>

oc set env bc/<name> BUILD_LOGLEVEL=5

Image Streams

oc get is                         # list image streams
oc describe is <name>

Templates

oc process <template-name> -p KEY=VAL | oc apply -f -
oc process -f template.yaml -p KEY=VAL
oc process --parameters <template-name>
oc get template -n openshift      # cluster templates

OCP 4 — Cluster Administration

oc get clusterversion             # cluster version and update history
oc get clusteroperators           # status of all cluster operators

# Node logs via oc adm
oc adm node-logs <node-name>
oc adm node-logs <node-name> --unit=kubelet
oc adm node-logs <node-name> --unit=crio
oc adm node-logs <node-name> --tail=50 --since=1h

# Debug a node
oc debug node/<node-name>
# Inside the shell:
#   chroot /host
#   systemctl is-active kubelet
#   toolbox               # start toolbox container for host tools

# Cluster network configuration
oc get network/cluster -o yaml    # pod network, service network, SDN plugin

Resource Definition Basics

Every Kubernetes/OCP resource shares the same top-level structure:

apiVersion: v1          # group/version — use 'kubectl api-versions' to list
kind: Service
metadata:
  name: my-service
  namespace: my-project
  labels:
    app: myapp
spec:                   # resource-specific spec — use 'kubectl explain' to browse
  selector:
    app: myapp
  ports:
    - port: 80
      targetPort: 8080
  type: ClusterIP

Create / update / delete:

kubectl apply -f resource.yaml      # create or update (preferred)
kubectl create -f resource.yaml     # create only — fails if already exists
kubectl replace -f resource.yaml    # replace existing resource
kubectl delete -f resource.yaml
kubectl edit <resource> <name>      # live edit in $EDITOR

oc apply -f resource.yaml
oc create -f resource.yaml
oc delete -f resource.yaml

Export a live resource to YAML:

kubectl get deployment myapp -o yaml > myapp.yaml
oc get deployment myapp -o yaml > myapp.yaml

References: oc developer commands · oc administrator commands · kubectl quick-reference

Disclaimer: Views expressed in articles are those of the respective authors and do not necessarily reflect the views of their employers or this site. While we aim for accuracy, please verify information before relying on it, and let us know if you spot an error.
Share:

Related Posts

Ansible for Security

Ansible for Security

Ansible Security Hardening Playbook content RedHatOfficial/ansible-role-rhel7-cis RedHatOfficial/ansible-role-rhel8-cis …

Ansible Labs

Ansible Labs

Ansible Automation Platform Enable RHEL and AAP Subscriptions Red Hat Container Registry Authentication AAP Download Options Extract the AAP …

Container

Falco - Open source container security

Runtime Security Installing Falco Running Falco in Docker Falco Installation with Kubernetes Falco Rules Falco macros Falco lists Falco default rules …

Ansible Automation Platform - Disaster Recovery

Ansible Automation Platform - Disaster Recovery

These are official references to implement Disaster Recovery (DR) designs for Ansible Automation Platform.

Ansible Automation Platform - CLI Cheat Sheet

Ansible Automation Platform - CLI Cheat Sheet

AAP CLI Commands $ aap-gateway-manage update_password --username='<username>' --password='<password>' # For containerized …

Awesome DevSecSysOps Tools on Internet

Awesome DevSecSysOps Tools on Internet

This is a page where I keep all those list of tools on internet, which we use for our day-to-day tasks.