Commands · Reference

⛑️OpenShift Commands

The oc set, grouped by what you are trying to find out. Every kubectl command works here too — these are the ones that only exist on OpenShift, or that answer an OpenShift question faster.

Login, context & projects

14 commands

A Project is a namespace with a template and a lifecycle. oc project switches the active one, which is what most resource not found confusion comes down to — you are looking in the wrong namespace.

CommandWhat it does Typical use
oc login -u user --server=URLAuthenticate; writes context into ~/.kube/configoc login -u kubeadmin --server=https://api.ocp.example.com:6443
oc login --token=...Log in with a token rather than a passwordoc login --token=sha256~xxx --server=https://api.ocp:6443
oc whoamiWhich identity is this context usingoc whoami
oc whoami -tPrint the current token — for curl against the APITOKEN=$(oc whoami -t)
oc whoami --show-consoleThe web console URL for this clusteroc whoami --show-console
oc whoami --show-serverThe API endpoint you are actually talking tooc whoami --show-server
oc projectWhich project is active right nowoc project
oc project <name>Switch the active projectoc project prod
oc projectsEvery project you can see — never leaks ones you cannotoc projects
oc new-projectCreate a project THROUGH the template, with its quota and policyoc new-project prod --description='Production'
oc delete projectDelete a project and everything in it, PVCs includedoc delete project scratch
oc statusA readable summary of what is running in this projectoc status -n prod
oc config get-contextsEvery cluster/user/namespace combination you haveoc config get-contexts
oc config use-contextSwitch clusters without logging in againoc config use-context prod/api-ocp:6443/admin

Deploying, builds & image streams

22 commands

S2I builds an image from source without a Dockerfile. An ImageStream is a pointer with history — which is what gives you a rollback target and a redeploy trigger.

CommandWhat it does Typical use
oc new-appCreate a full application from source, image or templateoc new-app python:3.11~https://github.com/org/app.git
oc new-app --name=x --image=From an existing image rather than sourceoc new-app --name=api --image=quay.io/org/api:v2
oc new-app --dry-run -o yamlSee what it WOULD create before it creates itoc new-app nginx --dry-run -o yaml
oc new-app -e KEY=valueSet environment variables at creationoc new-app mysql -e MYSQL_ROOT_PASSWORD=x
oc new-buildA BuildConfig without deploying itoc new-build --binary --name=api -l app=api
oc start-buildRun a build nowoc start-build api
oc start-build --from-dir=. --followBinary build from a local directory, streaming logsoc start-build api --from-dir=. --follow
oc start-build --from-file=Build from a single local fileoc start-build api --from-file=app.jar
oc logs -f bc/<name>Follow the latest build's logsoc logs -f bc/api
oc cancel-buildStop a running buildoc cancel-build api-7
oc get bc,buildsBuildConfigs and the builds they producedoc get bc,builds -n prod
oc get isImage streams and the tags they exposeoc get is -n prod
oc describe isTag history — every digest this tag has pointed atoc describe is/api
oc tag src:tag dst:tagMove or copy a tag; this is how you promote a buildoc tag api:latest api:prod
oc tag --scheduledRe-check an external image periodically. Without it, imported once, never againoc tag quay.io/org/api:latest api:latest --scheduled
oc import-image --confirmForce an import check right nowoc import-image api:latest --confirm
oc rollout latestTrigger a new deployment from the current imageoc rollout latest deploy/api
oc rollout undoRoll back to the previous revisionoc rollout undo deploy/api
oc rollout statusBlock until the rollout finishes or failsoc rollout status deploy/api --timeout=5m
oc set imageChange a container image in placeoc set image deploy/api api=quay.io/org/api:v3
oc set envAdd, change or list environment variablesoc set env deploy/api LOG_LEVEL=debug
oc set env --from=secret/xInject a whole secret as environment variablesoc set env deploy/api --from=secret/db-creds

Routes & exposing services

12 commands

A Route is OpenShift's ingress object. Admitted=False is the single most useful field on one — an unadmitted route returns 503 from the router and looks exactly like a broken backend.

CommandWhat it does Typical use
oc expose svcCreate a Route for a Serviceoc expose svc/api
oc expose svc --hostname=Route with a specific hostoc expose svc/api --hostname=api.example.com
oc create route edgeTLS terminated at the router, HTTP to the podoc create route edge api --service=api
oc create route passthroughRouter forwards bytes; the pod terminates TLSoc create route passthrough api --service=api
oc create route reencryptTerminate, then re-encrypt to the podoc create route reencrypt api --service=api --dest-ca-cert=ca.crt
oc get routeEvery route and the host it claimsoc get route -n prod
oc get route -o jsonpath statusWhether the router admitted it — check this before anything elseoc get route api -o jsonpath='{.status.ingress[*].conditions[*].reason}'
oc annotate route timeoutPer-route backend timeoutoc annotate route api haproxy.router.openshift.io/timeout=60s
oc annotate route rate-limitPer-route connection limitingoc annotate route api haproxy.router.openshift.io/rate-limit-connections=true
oc set route-backendsWeighted backends — canary splits at the routeroc set route-backends api api=90 api-next=10
oc -n openshift-ingress get podsWhere the routers actually runoc -n openshift-ingress get pods -o wide
oc -n openshift-ingress rsh ... haproxy.configWhat the router configured for realoc -n openshift-ingress rsh deploy/router-default cat haproxy.config

Security context constraints & RBAC

15 commands

SCC decides what a POD may ask for; RBAC decides what a USER may do. Both refuse in writing, and the wording tells you which one it was.

CommandWhat it does Typical use
oc get sccEvery constraint on the cluster, and what it permitsoc get scc
oc describe scc restricted-v2The default: no root, dropped capabilities, random UIDoc describe scc restricted-v2
oc get pod -o jsonpath sccWhich SCC actually admitted this podoc get pod api-7d9f -o jsonpath='{.metadata.annotations.openshift\.io/scc}'
oc adm policy scc-subject-reviewWhich SCC WOULD admit this workload — before granting anythingoc adm policy scc-subject-review -z api-sa -f deploy.yaml
oc adm policy scc-reviewWhich service accounts could run this pod specoc adm policy scc-review -f deploy.yaml
oc adm policy add-scc-to-userGrant an SCC. Prefer a custom SCC over anyuidoc adm policy add-scc-to-user anyuid -z build-sa
oc adm policy remove-scc-from-userTake it away againoc adm policy remove-scc-from-user anyuid -z build-sa
oc auth can-iCan this identity do this, resolved rather than guessedoc auth can-i create deploy -n prod --as=jane
oc auth can-i --listEverything an identity can do in a namespaceoc auth can-i --list -n prod --as=jane
oc auth can-i --as=system:serviceaccount:The service-account form, where this usually bitesoc auth can-i list secrets --as=system:serviceaccount:prod:api-sa
oc adm policy who-canThe reverse question — who can do this?oc adm policy who-can delete pods -n prod
oc adm policy add-role-to-userGrant a namespace roleoc adm policy add-role-to-user edit jane -n prod
oc adm policy add-cluster-role-to-userGrant a cluster roleoc adm policy add-cluster-role-to-user cluster-reader auditor
oc adm groups newCreate a group to bind roles to, rather than to usersoc adm groups new platform-team jane bob
oc adm policy remove-cluster-role-from-groupStop everyone self-provisioning projectsoc adm policy remove-cluster-role-from-group self-provisioner system:authenticated:oauth

Cluster operators, version & upgrades

18 commands

The ownership chain is ClusterVersion → ClusterOperator → the operator's workload. Start at the top: a degraded cluster operator names its own problem in a way a pod list never will.

CommandWhat it does Typical use
oc get clusteroperatorsThe first command of any OpenShift incidentoc get co
oc get co | grep -v 'True.*False.*False'Only the unhealthy onesoc get co | grep -v 'True.*False.*False'
oc describe co <name>The Degraded condition names the failing resourceoc describe co/ingress
oc get clusterversionCurrent version, and what an upgrade is waiting onoc get clusterversion
oc adm upgradeWhich versions are actually on offeroc adm upgrade
oc adm upgrade --to=Start an upgrade to a specific versionoc adm upgrade --to=4.16.11
oc adm upgrade channelChange the update channeloc adm upgrade channel stable-4.16
oc get clusterversion UpgradeableThe cluster's own opinion, before you startoc get clusterversion -o jsonpath='{.items[0].status.conditions[?(@.type=="Upgradeable")].message}'
oc get apirequestcountWho is still calling a deprecated APIoc get apirequestcount | grep -v ' 0 '
oc get mcpWhether node config is mid-rollout or wedgedoc get mcp
oc get machineconfigEvery node-level config objectoc get mc
oc get nodes -o wideNode state, roles, kernel and runtime versionsoc get nodes -o wide
oc adm top nodesActual node CPU and memory pressureoc adm top nodes
oc adm cordon / uncordonStop or resume scheduling on a nodeoc adm cordon worker-04
oc adm drainEvict everything, respecting PodDisruptionBudgetsoc adm drain worker-04 --ignore-daemonsets --delete-emptydir-data
oc get pdb -AThe budget that will block the next drainoc get pdb -A
oc get subscription,installplan,csv -AOLM operator state, end to endoc get sub,ip,csv -A
oc get installplan -AThe unapproved plan keeping an operator on an old versionoc get installplan -A

Debugging, must-gather & node access

18 commands

must-gather is the supported dump. Scope it when you already know the area — the full collection runs to several GB and 15+ minutes.

CommandWhat it does Typical use
oc adm must-gatherThe full supported cluster dumpoc adm must-gather --dest-dir=./mg
oc adm must-gather -- gather_network_logsNetwork only, in a fraction of the timeoc adm must-gather --dest-dir=./mg -- /usr/bin/gather_network_logs
oc adm must-gather -- gather_audit_logsAPI audit logs onlyoc adm must-gather -- /usr/bin/gather_audit_logs
oc adm must-gather --image=One operator's deep state instead of everythingoc adm must-gather --image=registry.redhat.io/openshift-logging/cluster-logging-rhel9-operator:latest
oc adm inspectEverything about one namespace or resource, structuredoc adm inspect ns/openshift-ingress
oc debug node/<node>A root shell on a node without SSHoc debug node/worker-04
oc debug node/ -- chroot /hostRun a host command directlyoc debug node/worker-04 -- chroot /host journalctl -u kubelet -n 200
oc debug deploy/<name>A copy of the pod with the entrypoint replaced by a shelloc debug deploy/api
oc debug --as-rootDebug pod as root, when the SCC allows itoc debug deploy/api --as-root
oc adm node-logs --role=masterJournal or file logs from every masteroc adm node-logs --role=master -u kubelet
oc adm node-logs --path=Read a log file off the node, e.g. the audit logoc adm node-logs --role=master --path=kube-apiserver/audit.log
oc get events -A --sort-by=What the cluster just complained about. Expires in an houroc get events -A --sort-by=.lastTimestamp | tail -40
oc logs -f --tail=100Follow a pod's logsoc logs -f deploy/api --tail=100
oc logs -pThe PREVIOUS container — what a CrashLoop actually saidoc logs -p api-7d9f
oc rshShell into a running containeroc rsh deploy/api
oc port-forwardReach a pod's port locally without a Routeoc port-forward svc/api 8080:8080
oc cpCopy a file in or out of a containeroc cp api-7d9f:/tmp/heap.hprof ./heap.hprof
oc rsyncSync a directory in or outoc rsync ./config api-7d9f:/etc/app/

Storage, quota & limits

10 commands

A Pending PVC is either waiting for a consumer, which is correct, or the backend refused — and only describe tells you which.

CommandWhat it does Typical use
oc get pvc -A --field-selectorEvery stuck claim on the clusteroc get pvc -A --field-selector=status.phase=Pending
oc describe pvcThe provisioner's own error messageoc describe pvc data-0
oc get scBinding mode, reclaim policy and expansion — check before committingoc get sc -o custom-columns=NAME:.metadata.name,BIND:.volumeBindingMode,RECLAIM:.reclaimPolicy
oc get pv | grep ReleasedRetained volumes still holding data, waiting to be reboundoc get pv | grep Released
oc get volumeattachmentWhether a volume is attached, and to which nodeoc get volumeattachment
oc set volume deploy/x --addAttach a new volume to a workloadoc set volume deploy/api --add --name=data --claim-name=data-0 --mount-path=/data
oc set volume deploy/xWhat is mounted where, in one line per volumeoc set volume deploy/api
oc get quota,limitrangeThe project's ceilings — a common cause of Pendingoc get quota,limitrange -n prod
oc describe quotaUsed versus hard, per resourceoc describe quota -n prod
oc adm top podsLive CPU and memory per podoc adm top pods -n prod --sort-by=memory
← PreviousDocker Commands