| name | openshift-debug |
| description | OpenShift (OCP) troubleshooting - Security Context Constraints (SCC), Routes, Projects, OperatorHub/OLM operator failures, DeploymentConfig, cluster operators, image streams, and oc CLI diagnostics. |
| metadata | {"emoji":"🔴","requires":{"bins":["oc","kubectl","bash"]}} |
OpenShift Debug — OCP Troubleshooting Runbook
OpenShift-specific diagnostics covering the unique resources and constraints that differ from upstream Kubernetes. Uses the oc CLI and covers SCCs, Routes, OLM operators, cluster operators, and image streams.
Inspired by: Red Hat OpenShift documentation, OpenShift SRE runbooks, must-gather analysis, OpenShift 4.x operations guide.
When to Activate
Activate when the user asks about:
- OpenShift SCC, Security Context Constraints, runAsUser
- OpenShift Route, edge/passthrough/reencrypt TLS
- OLM operator failure, OperatorHub, Subscription
- OpenShift cluster operator degraded
- DeploymentConfig vs Deployment in OpenShift
- oc commands, OpenShift-specific CLI
- OpenShift image stream, internal registry
- OpenShift Projects (namespaces)
- OpenShift BuildConfig, S2I (source-to-image)
- must-gather, oc adm commands
- OpenShift oauth, authentication, htpasswd
- OpenShift MachineConfig, MachineConfigPool
Troubleshooting Runbook
OpenShift vs Kubernetes Key Differences
| Concept | Kubernetes | OpenShift |
|---|
| Namespace | kubectl get namespace | oc get project (Project = Namespace) |
| Ingress | Ingress resource | Route (OCP-native) |
| RBAC | Role/ClusterRole | Same + additional SCC layer |
| Operators | manual | OLM (Operator Lifecycle Manager) |
| Image pull | Any registry | Integrated image registry + image streams |
| Build | External CI | BuildConfig, S2I |
| Node config | manual | MachineConfig / MachineConfigPool |
| Auth | OIDC/webhook | OAuth proxy + HTPasswd/LDAP/GitHub |
Step 1 — Cluster Operator Health
Cluster operators manage all OpenShift platform components. All must be Available=True, Degraded=False.
oc get co
oc get co | grep -E "False|True.*True"
oc describe co <operator-name>
oc get clusterversion
oc get clusterversion -o yaml | grep -A10 "conditions:"
Failure Mode: SCC Violation (Pod Rejected)
Security Context Constraints (SCCs) are OpenShift's security admission layer — more powerful than Kubernetes PodSecurityAdmission. A pod that works in upstream k8s may be rejected in OpenShift because of SCC restrictions.
Symptom: Pod stuck in ContainerCreating or Error, events show SCC-related rejection
oc describe pod <pod-name> -n <project>
oc get scc
oc get pod <pod-name> -n <project> \
-o jsonpath='{.metadata.annotations.openshift\.io/scc}'
oc adm policy who-can use scc anyuid
oc policy scc-subject-review -z <service-account> -n <project>
oc adm policy who-can use scc restricted
oc adm policy add-scc-to-user anyuid -z <service-account> -n <project>
oc adm policy add-scc-to-user privileged -z <service-account> -n <project>
oc adm policy remove-scc-from-user anyuid -z <service-account> -n <project>
oc get project <project> -o yaml | grep -A5 "annotations:"
Creating a custom SCC (preferred over using built-in privileged):
apiVersion: security.openshift.io/v1
kind: SecurityContextConstraints
metadata:
name: my-app-scc
allowPrivilegedContainer: false
allowPrivilegeEscalation: false
runAsUser:
type: RunAsAny
seLinuxContext:
type: MustRunAs
fsGroup:
type: RunAsAny
users: []
groups: []
Failure Mode: Route Not Working
Routes expose services externally in OpenShift (analogous to Ingress + LoadBalancer).
oc get routes -n <project>
oc get routes -A
oc describe route <route-name> -n <project>
oc get pods -n openshift-ingress
oc get pods -n openshift-ingress-operator
oc logs -n openshift-ingress \
$(oc get pod -n openshift-ingress -l ingresscontroller.operator.openshift.io/deployment-ingresscontroller=default -o name | head -1) \
--tail=30
curl -v https://<route-hostname>/
oc expose svc/<service-name> --hostname=myapp.apps.mycluster.example.com
oc create route edge <route-name> \
--service=<service-name> \
--hostname=myapp.apps.mycluster.example.com \
-n <project>
oc get ingresses.config cluster -o jsonpath='{.spec.domain}'
Failure Mode: OLM Operator Installation Failure
The Operator Lifecycle Manager (OLM) manages operator installation via Subscriptions, CSVs, and CatalogSources.
oc get pods -n openshift-operator-lifecycle-manager
oc get pods -n openshift-marketplace
oc get subscription -A
oc describe subscription <name> -n <namespace>
oc get csv -n <namespace>
oc describe csv <csv-name> -n <namespace>
oc get installplan -n <namespace>
oc describe installplan <name> -n <namespace>
oc get catalogsource -n openshift-marketplace
oc logs -n openshift-marketplace \
$(oc get pod -n openshift-marketplace -l olm.catalogSource=<cs-name> -o name)
oc patch installplan <name> -n <namespace> \
--type='json' -p='[{"op":"replace","path":"/spec/approved","value":true}]'
oc delete subscription <name> -n <namespace>
oc delete csv <csv-name> -n <namespace>
Common OLM error: CatalogSource not reachable
oc logs -n openshift-marketplace \
$(oc get pod -n openshift-marketplace -l olm.catalogSource=redhat-operators -o name) | tail -20
oc get proxy cluster -o yaml
Failure Mode: MachineConfig Issues
MachineConfig applies OS-level configuration to nodes (files, systemd units, kernel args).
oc get mcp
oc describe mcp <pool-name>
oc get nodes | grep -E "SchedulingDisabled|NotReady"
oc get pod -n openshift-machine-config-operator \
-l k8s-app=machine-config-daemon \
--field-selector="spec.nodeName=<node-name>"
oc logs -n openshift-machine-config-operator \
<machine-config-daemon-pod> -c machine-config-daemon --tail=50
oc patch mcp <pool-name> --type='json' \
-p='[{"op":"replace","path":"/spec/paused","value":true}]'
oc patch mcp <pool-name> --type='json' \
-p='[{"op":"replace","path":"/spec/paused","value":false}]'
OpenShift Image Streams and Internal Registry
oc get imagestream -n <project>
oc describe imagestream <name> -n <project>
oc get pods -n openshift-image-registry
oc logs -n openshift-image-registry \
$(oc get pod -n openshift-image-registry -l docker-registry=default -o name | head -1) \
--tail=30
oc get configs.imageregistry.operator.openshift.io cluster -o yaml | grep -A5 "storage:"
docker pull \
$(oc get route default-route -n openshift-image-registry -o jsonpath='{.spec.host}')/<project>/<image>:<tag>
oc registry login
OpenShift must-gather (Diagnostic Data Collection)
must-gather collects full diagnostic data — use when opening a Red Hat support case.
oc adm must-gather
oc adm must-gather --image=<operator-must-gather-image>
kubectl --kubeconfig=must-gather.local.<ts>/registry-.../<cluster>/kubeconfig get pods -A
Quick oc Command Reference
oc get co
oc get mcp
oc get nodes
oc get pods -A | grep -v Running
oc get routes -A
oc get csv -A
oc get subscription -A
oc get scc
oc new-project <name>
oc project <name>
oc get project
oc describe node <node>
oc adm top nodes
oc adm top pods -A
oc get oauth cluster -o yaml
oc get oauthaccesstoken
oc whoami
oc whoami --show-token
oc debug node/<node-name>
oc debug deployment/<name> -n <project>
oc rsh <pod-name>
oc rsync <pod>:/remote/path /local/path
References