OCP Interview Questions — Complete Guide


Level 1 — Fundamentals


Q1. What is OpenShift and how does it differ from vanilla Kubernetes?

Answer:

OpenShift is Red Hat’s enterprise Kubernetes distribution. It builds on top of upstream Kubernetes and adds:

Kubernetes gives you: OpenShift adds on top:
───────────────────── ──────────────────────
Container orchestration → Everything Kubernetes + opinionated defaults
Manual TLS setup → Automatic TLS everywhere (service mesh ready)
No built-in registry → Integrated image registry
No built-in CI/CD → OpenShift Pipelines (Tekton) built in
No web console → Full-featured web console
Manual RBAC setup → SCCs (Security Context Constraints)
No OS management → RHCOS + MachineConfig operator
No upgrade automation → Cluster Version Operator (CVO)

Key philosophical difference: Kubernetes is a framework, OpenShift is a complete platform. OpenShift makes opinionated choices so you don’t have to.


Q2. What is the control plane in OCP and what components does it consist of?

Answer:

Control Plane Components:
│
├── etcd
│ └── Distributed key-value store — the cluster database
│ Stores ALL cluster state (every object ever created)
│ Requires 3 or 5 members for quorum (majority must agree)
│
├── kube-apiserver
│ └── The front door — all oc/kubectl commands hit this
│ Validates and persists objects to etcd
│ Enforces authentication + authorization (RBAC)
│
├── kube-controller-manager
│ └── The reconciliation engine
│ Runs control loops: deployment controller, node controller,
│ endpoint controller, namespace controller, etc.
│ Constantly compares desired state vs actual state
│
└── kube-scheduler
└── Decides WHICH node a pod runs on
Evaluates: resource requests, affinity, taints/tolerations,
topology spread, PriorityClass

In OCP all four run as static pods on master nodes, managed by kubelet.


Q3. What is a Static Pod and why does OCP use them for the control plane?

Answer:

A static pod is a pod defined by a YAML file on disk that kubelet reads directly — without needing the API server:

/etc/kubernetes/manifests/
├── etcd-pod.yaml
├── kube-apiserver-pod.yaml
├── kube-controller-manager-pod.yaml
└── kube-scheduler-pod.yaml

Why static pods for the control plane:

Problem: API server needs etcd to start.
etcd needs to be scheduled somehow.
Scheduler needs the API server.
→ Classic chicken-and-egg problem.
Solution: kubelet reads manifests directly from disk.
No API server needed to start the control plane.
kubelet bootstraps the entire control plane itself.

Q4. What is etcd and why is quorum important?

Answer:

etcd is a distributed, consistent key-value store. It uses the Raft consensus algorithm — all writes must be agreed upon by a majority (quorum) of members before being committed.

3-member cluster: quorum = 2 (can lose 1 member)
5-member cluster: quorum = 3 (can lose 2 members)
2-member cluster: quorum = 2 (can lose 0 — never do this)
Formula: quorum = floor(N/2) + 1

If quorum is lost:

etcd stops accepting writes
→ API server returns 503
→ No new pods scheduled
→ No config changes possible
→ Cluster is read-only at best, completely down at worst

Q5. What is the difference between a Deployment and a DeploymentConfig?

Answer:

DeploymentConfig (DC) Deployment
───────────────────── ──────────
OCP-specific resource Native Kubernetes resource
Managed by OCP DC controller Managed by kube-controller-manager
Supports image change triggers No built-in image triggers
Supports config change triggers Use Kyverno/ArgoCD for policy-driven rollouts
Lifecycle hooks (pre/mid/post) No lifecycle hooks
Being deprecated in OCP 4.x Recommended going forward

Red Hat recommends migrating from DeploymentConfig to Deployment for all new workloads. DeploymentConfig is a legacy OCP 3.x concept.


Q6. What is a Route in OCP and how does it differ from an Ingress?

Answer:

Both expose services externally, but:

Route (OCP-native) Ingress (Kubernetes-native)
────────────────── ───────────────────────────
OCP-specific resource Standard Kubernetes resource
Handled by HAProxy router Requires Ingress controller
Supports edge/passthrough/reencrypt Only HTTP/HTTPS
TLS termination built-in TLS via annotations (controller-specific)
Wildcard routes supported Wildcard support varies
Fine-grained timeout/LB control Limited, annotation-based

In OCP 4.x, Routes are still the primary way to expose services. OCP also supports standard Kubernetes Ingress objects — they are automatically converted to Routes internally by the Ingress Operator.


Q7. What are Security Context Constraints (SCCs)?

Answer:

SCCs are OCP’s admission mechanism that controls what a pod is allowed to do at the OS level. They are more powerful than Kubernetes PodSecurityAdmission:

SCC controls:
- Can the pod run as root?
- Which UID range is allowed?
- Can it use privileged containers?
- Which Linux capabilities are allowed?
- Can it mount hostPath volumes?
- Can it use the host network/PID/IPC namespace?
- Which SELinux labels are allowed?

Built-in SCCs (least to most permissive):

restricted-v2 → default, no root, random UID, most secure
restricted → legacy default
baseline → some relaxations
nonroot → any non-root UID
anyuid → any UID including root (use carefully)
hostmount-anyuid→ + host volume mounts
hostnetwork-v2 → + host network
hostaccess → host network + host filesystem
privileged → everything allowed (only for system pods)

Level 2 — Architecture & Operations


Q8. Explain the role of the Cluster Version Operator (CVO)

Answer:

The CVO is the top-level operator that manages OCP itself. It:

1. Watches clusterversion object for desired version
2. Downloads the release image from the update graph
3. Extracts manifests for every cluster operator
4. Applies them in dependency order
5. Waits for each operator to become Available before proceeding
6. Manages the upgrade of ALL cluster operators
7. Reports overall cluster version status
# The CVO's source of truth:
oc get clusterversion -o yaml
# Key fields:
spec.channel → which update channel (stable-4.14)
spec.desiredUpdate → target version
status.history → all past versions
status.conditions → Available / Progressing / Degraded

The CVO itself runs as a deployment in openshift-cluster-version namespace. It is the first thing that comes up after etcd and the API server.


Q9. What is RHCOS and why is it required for OCP master nodes?

Answer:

RHCOS (Red Hat CoreOS) is an immutable, container-optimized OS purpose-built for OCP:

RHCOS characteristics:
- Immutable root filesystem (no yum install, no manual changes)
- All changes via MachineConfig operator
- Atomic upgrades (entire OS image, not package-by-package)
- Built-in CRI-O (no Docker)
- Ignition for first-boot configuration
- Automatic updates coordinated by OCP upgrade
- SELinux enforcing by default
- Transactional updates via rpm-ostree

Why required for masters:
The MachineConfig Operator directly manages RHCOS. It writes kernel arguments, systemd units, files, and certificates. This tight integration is what allows oc adm upgrade to upgrade the OS alongside the Kubernetes components atomically.

Workers can use RHEL (for baremetal worker flexibility) but masters must be RHCOS.


Q10. What is the MachineConfig Operator (MCO) and how does it work?

Answer:

The MCO manages the configuration of RHCOS nodes. Instead of SSH-ing into nodes and editing files manually, you declare the desired state as a MachineConfig object:

apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
metadata:
name: worker-custom-chrony
labels:
machineconfiguration.openshift.io/role: worker
spec:
config:
ignition:
version: 3.2.0
storage:
files:
- path: /etc/chrony.conf
contents:
source: data:,server%20ntp.example.com%20iburst

How it works:

You apply MachineConfig
│
▼
MCO renders a new MachineConfig (merged composite)
│
▼
MachineConfigPool detects rendered config changed
│
▼
MachineConfigDaemon on each node:
- Downloads new config
- Drains the node
- Writes files / systemd units to disk
- Updates kernel arguments via rpm-ostree
- Reboots node
│
▼
Node comes back with new config applied

MachineConfigPool = which nodes get which MachineConfigs:

oc get mcp # master pool, worker pool, custom pools
oc get mc # all MachineConfig objects
oc get mcd -n openshift-machine-config-operator # daemon pods

Q11. How does pod scheduling work in OCP?

Answer:

The scheduler selects a node for each pod through a multi-step filtering + scoring process:

New Pod Created
│
▼
FILTERING PHASE (eliminate ineligible nodes)
├── Node has enough CPU/Memory? (resource requests)
├── Node matches nodeSelector?
├── Node satisfies all node affinity rules?
├── Node is not tainted (or pod tolerates it)?
├── Pod fits within PodTopologySpread constraints?
└── Ports available? Volume can be attached?
│
▼
SCORING PHASE (rank remaining nodes 0-100)
├── LeastAllocated → prefer nodes with most free resources
├── BalancedAllocation → prefer balanced CPU/memory ratio
├── NodeAffinity → preferred affinity rules get points
├── PodTopologySpread → prefer spreading across zones
└── ImageLocality → prefer nodes that already have the image
│
▼
Node with highest score wins → Pod bound to that node
│
▼
kubelet on winning node starts the pod

Q12. What are Taints and Tolerations?

Answer:

Taints repel pods from nodes. Tolerations allow pods to land on tainted nodes.

# Taint a node — no pods without toleration can schedule here
oc adm taint node worker-3 dedicated=gpu:NoSchedule
# Pod must have this toleration to schedule on tainted node
spec:
tolerations:
- key: "dedicated"
operator: "Equal"
value: "gpu"
effect: "NoSchedule"

Taint effects:

NoSchedule → new pods without toleration won't schedule here
PreferNoSchedule → scheduler tries to avoid, but not hard block
NoExecute → existing pods without toleration are EVICTED

Common OCP uses:

node-role.kubernetes.io/master:NoSchedule → keeps workloads off masters
node.kubernetes.io/not-ready:NoExecute → evicts pods from NotReady nodes
node.kubernetes.io/unreachable:NoExecute → evicts pods from unreachable nodes

Q13. What is the difference between ConfigMap and Secret?

Answer:

ConfigMap Secret
───────── ──────
Non-sensitive configuration Sensitive data (passwords, tokens, certs)
Stored as plaintext in etcd Stored base64-encoded in etcd (NOT encrypted by default)
No size limit (practical: <1MB) 1MB size limit
Visible in oc describe Values hidden in oc describe
Can be mounted as files or env Same
No automatic rotation Can integrate with Vault/external secrets

Critical point: Secrets are NOT encrypted at rest by default in OCP. You must enable etcd encryption:

# Enable etcd encryption
oc patch apiserver cluster \
--type merge \
--patch '{"spec":{"encryption":{"type":"aescbc"}}}'
# Verify encryption status
oc get apiserver -o jsonpath='{.items[0].status.encryption}'

Q14. Explain PersistentVolumes, PersistentVolumeClaims, and StorageClasses

Answer:

StorageClass (SC)
└── Defines HOW storage is provisioned
(which provisioner, IOPS tier, reclaim policy)
Example: aws-ebs-gp3, nfs-client, ceph-rbd
PersistentVolume (PV)
└── A piece of actual storage
Can be pre-provisioned (static) or
auto-created by SC (dynamic provisioning)
PersistentVolumeClaim (PVC)
└── A pod's REQUEST for storage
Specifies: size, accessMode, storageClassName
Binds to a matching PV
Pod
└── Mounts the PVC as a volume

Access modes:

ReadWriteOnce (RWO) → one node can mount read-write (block storage: EBS, iSCSI)
ReadOnlyMany (ROX) → many nodes can mount read-only
ReadWriteMany (RWX) → many nodes can mount read-write (NFS, CephFS, Azure File)
ReadWriteOncePod → only ONE pod can mount read-write (strongest isolation)

Level 3 — Advanced Topics


Q15. How does OCP networking work? Explain the CNI and OVN-Kubernetes

Answer:

OCP uses CNI (Container Network Interface) plugins for pod networking. The default since OCP 4.12 is OVN-Kubernetes:

OVN-Kubernetes architecture:
├── OVN (Open Virtual Network) — control plane
│ Maintains a logical network topology database
│
├── OVS (Open vSwitch) — data plane
│ Fast kernel-level packet switching on each node
│
├── ovnkube-master (on control plane)
│ Watches Kubernetes API for pods, services, network policies
│ Translates into OVN logical flows
│
└── ovnkube-node (on each node)
Programs OVS with flows for local pod traffic
Handles VXLAN/Geneve encapsulation for cross-node traffic

Pod-to-pod traffic flow:

Pod A (node-1) → OVS on node-1 → Geneve tunnel → OVS on node-2 → Pod B (node-2)

Network Policy is enforced at the OVS level — packets that violate policy are dropped in kernel space before they ever reach the destination pod.


Q16. What is the difference between NodePort, ClusterIP, and LoadBalancer services?

Answer:

ClusterIP (default)
└── Internal cluster IP only
Accessible only from inside the cluster
Used for service-to-service communication
Example: my-service.my-namespace.svc.cluster.local
NodePort
└── Opens a port (30000-32767) on EVERY node
External traffic → NodeIP:NodePort → Service → Pod
Not recommended for production (exposes all nodes)
LoadBalancer
└── Provisions an external load balancer (cloud provider)
Gets a public IP automatically (AWS ELB, Azure LB, etc.)
Best for cloud deployments needing external access
Route (OCP-specific)
└── Goes through the HAProxy Ingress Controller
DNS-based routing (hostname → service)
TLS termination built in
Preferred method in OCP

Q17. How does image management work in OCP? What is the ImageStream?

Answer:

An ImageStream is an OCP abstraction over container images. Instead of referencing image tags directly (which are mutable), you reference an ImageStream tag (which tracks the underlying digest):

Without ImageStream:
Deployment → image: myapp:latest
→ "latest" can change anytime → unpredictable
With ImageStream:
Deployment → image: myapp:prod (ImageStreamTag)
→ ImageStreamTag points to sha256:abc123 (immutable digest)
→ When new image pushed: tag updates, can trigger auto-redeploy
# Create ImageStream
oc create imagestream myapp
# Import an image into the stream
oc import-image myapp:latest \
--from=registry.example.com/myapp:latest \
--confirm
# See what digest the tag points to
oc get istag myapp:latest -o jsonpath='{.image.dockerImageReference}'

Q18. What is Operator Framework and how do Operators work?

Answer:

An Operator is a Kubernetes controller that encodes human operational knowledge into software. It extends the Kubernetes API with Custom Resources and watches them to manage complex applications:

Standard Kubernetes:
You: create Deployment + Service + ConfigMap manually
You: handle upgrades, backups, failover manually
With an Operator:
You: create a single CR e.g. kind: PostgreSQLCluster
Operator: creates Deployment + Service + ConfigMap + PVC
handles upgrades, backups, failover automatically

Operator Maturity Model:

Level 1 — Basic Install → installs the application
Level 2 — Seamless Upgrades → handles version upgrades
Level 3 — Full Lifecycle → backup, restore, failure recovery
Level 4 — Deep Insights → metrics, alerts, log integration
Level 5 — Auto Pilot → horizontal/vertical autoscaling

OCP ships many Level 5 operators (etcd operator, DNS operator, ingress operator, etc.) for platform components.


Q19. How does RBAC work in OCP?

Answer:

RBAC building blocks:
Role / ClusterRole
└── WHAT can be done
List of rules: [verbs] on [resources]
Role = namespace-scoped
ClusterRole = cluster-wide
RoleBinding / ClusterRoleBinding
└── WHO gets to do it
Binds a Role to a Subject (User / Group / ServiceAccount)
RoleBinding = in one namespace
ClusterRoleBinding = across all namespaces
# Create a role that allows reading pods
oc create role pod-reader \
--verb=get,list,watch \
--resource=pods \
-n my-namespace
# Bind it to a user
oc create rolebinding pod-reader-binding \
--role=pod-reader \
--user=john \
-n my-namespace
# Check what a user can do
oc auth can-i --list --as=john -n my-namespace
# Check specific permission
oc auth can-i delete pods --as=john -n my-namespace

OCP adds Project-level RBAC on top — admin, edit, view are built-in roles per project.


Q20. What happens when a node goes NotReady?

Answer:

Node stops sending heartbeats to API server
│
▼ (after 40 seconds default)
Node Controller marks node as Unknown/NotReady
│
▼ (after node-monitor-grace-period: 40s)
Node gets taint:
node.kubernetes.io/not-ready:NoExecute
node.kubernetes.io/unreachable:NoExecute
│
▼ (after pod-eviction-timeout: 5 minutes)
Pods on the node get eviction tolerations expire
→ Pods marked for deletion
→ Scheduler reschedules them on healthy nodes
│
▼
ReplicaSets/Deployments detect pod count is low
→ New pods created on other nodes
│
▼
If node comes back:
→ kubelet re-registers
→ CSR issued and approved
→ Node returns to Ready
→ Orphaned pods cleaned up

Q21. How do you troubleshoot a pod stuck in Pending state?

Answer:

Pending means the scheduler cannot place the pod. Work through these causes:

# Step 1 — describe the pod, read Events section
oc describe pod <pod-name> -n <namespace>
# Look for: "0/3 nodes are available: ..."
# Common causes and fixes:
# Insufficient resources
"0/3 nodes available: 3 Insufficient cpu"
→ oc adm top nodes # check actual usage
→ reduce pod resource requests
→ add more nodes
# Node selector mismatch
"0/3 nodes available: 3 node(s) didn't match node selector"
→ oc get nodes --show-labels
→ fix nodeSelector in pod spec
# Taint not tolerated
"0/3 nodes available: 3 node(s) had taint that pod didn't tolerate"
→ oc describe node <node> | grep Taint
→ add toleration to pod spec
# PVC not bound
"0/3 nodes available: 3 pod has unbound immediate PersistentVolumeClaims"
→ oc get pvc -n <namespace>
→ check StorageClass provisioner
→ check available PVs
# Topology constraints
"0/3 nodes: 3 node(s) didn't match pod topology spread constraints"
→ review topologySpreadConstraints
→ may need more nodes in different zones

Q22. How do you perform a blue-green deployment in OCP?

Answer:

# Current state: blue is live
oc get svc my-app # selector: version=blue
# 1. Deploy green alongside blue
oc apply -f green-deployment.yaml
# Both blue and green pods running
# 2. Verify green is healthy
oc get pods -l version=green
oc rollout status deployment/my-app-green
# 3. Run smoke tests against green directly
oc expose deployment my-app-green \
--name=my-app-green-test \
--port=8080
# Test via the test route
# 4. Switch traffic: patch the service selector
oc patch service my-app \
--type merge \
--patch '{"spec":{"selector":{"version":"green"}}}'
# 100% traffic now on green — instant cutover
# 5. Monitor for issues
# If problems: instant rollback
oc patch service my-app \
--type merge \
--patch '{"spec":{"selector":{"version":"blue"}}}'
# 6. Once stable, remove blue
oc delete deployment my-app-blue

Q23. How does etcd backup and restore work in OCP?

Answer:

# BACKUP — run on one master node
sudo /usr/local/bin/cluster-backup.sh /home/core/backup
# Produces:
# snapshot_<timestamp>.db — full etcd database dump
# static_kuberesources_<ts>.tar.gz — control plane certs + manifests
# RESTORE — run when all control plane is lost
sudo /usr/local/bin/cluster-restore.sh /home/core/backup
# Process:
# 1. Validates snapshot integrity
# 2. Stops etcd (moves manifest out of /etc/kubernetes/manifests/)
# 3. Backs up old /var/lib/etcd/member
# 4. Extracts static pod resources (certs + manifests)
# 5. Starts restore-etcd pod (special one-time pod)
# 6. restore-etcd pod: runs etcdutl snapshot restore
# bumps revision (prevents Raft confusion)
# swaps in normal etcd-pod.yaml
# 7. etcd comes up as single member
# 8. API server becomes available
# 9. etcd operator re-adds master-1 and master-2 as members

Key rule: backup before every upgrade, store off-cluster, test restores regularly.


Rapid-Fire Questions


Q: What is a Namespace vs a Project?
A Project is an OCP wrapper around a Namespace. It adds annotations for display name, description, and requester. Every Project creates a Namespace underneath. From a Kubernetes perspective they are identical.

Q: What is oc debug node?
Starts a privileged pod on a node with the host filesystem mounted at /host — allows you to inspect/modify node-level configuration without SSH.

oc debug node/worker-0
chroot /host
systemctl status kubelet

Q: What is a DaemonSet used for in OCP?
Runs exactly one pod on every node (or selected nodes). Used for: log collectors (Fluentd), monitoring agents (node-exporter), CNI plugins, MachineConfig daemon, CSI drivers.

Q: What is the difference between oc delete and oc scale --replicas=0?
oc scale --replicas=0 terminates all pods but keeps the Deployment object — easy to scale back up. oc delete deployment removes the Deployment entirely — pods are gone and you must recreate the Deployment.

Q: What is a HorizontalPodAutoscaler (HPA)?
Automatically scales pod replicas based on CPU/memory/custom metrics. Requires the metrics-server. Configured with min/max replicas and a target utilization threshold.

Q: What port does the OCP API server listen on?
6443 — all oc and kubectl commands go here.

Q: What is oc adm must-gather?
Collects comprehensive diagnostic data from a cluster for Red Hat support:

oc adm must-gather
# Collects: logs, events, resource configs, network info
# Creates: must-gather.tar.gz

Q: What is the difference between RollingUpdate and Recreate deployment strategies?
RollingUpdate replaces pods gradually (new pods up before old pods down) — zero downtime. Recreate kills all existing pods first, then starts new ones — causes downtime but avoids running mixed versions simultaneously.

Q: Where are etcd certificates stored on a master node?
/etc/kubernetes/static-pod-resources/etcd-certs/ — peer certs, server certs, client certs, CA bundles.

Q: What command approves all pending CSRs?

oc get csr -o name | xargs oc adm certificate approve

Leave a Reply