TL;DR: OpenShift is certified Kubernetes plus an integrated registry, build system, Routes, an operator catalogue and a much stricter default security posture. The commonly used
restricted-v2security context constraint runs your container as an arbitrary non-root UID, and images that assume root or a fixed UID break on arrival.
How to approach it
Lead with the security difference, because it is the practical answer to "why did my manifest stop working": the default security context policy rejects containers that run as root, which most upstream images do. Then cover the additions briefly. Being able to say what to change in the Dockerfile is what makes this useful rather than descriptive.
A strong answer
OpenShift is Kubernetes underneath, certified conformant, so the API objects you know all work. What it adds is a supported distribution with opinions.
Security context constraints, the part that matters day one. An SCC is an OpenShift object that controls what a pod may do: which UID it can run as, whether it can be privileged, which capabilities and volume types it can use, whether it can use host networking. The default for ordinary workloads is restricted-v2, and it does something specific: its UID strategy requires a value in the namespace's allocated range and can supply a default. Treat that UID as arbitrary from the image's perspective, not as a promised random value. Inspect effective groups and filesystem permissions.
So an image that does any of these breaks:
Explicitly requests a root UID that the applicable SCC does not permit. An image's default USER alone does not describe the final admitted security context.
Writes to a directory owned by a specific user, because the random UID does not own it.
Assumes a particular UID exists in /etc/passwd, which it will not. Tools that call getpwuid() fail.
Assumes it can bind a privileged port. Check the runtime settings and capabilities; restricted-v2 allows explicitly adding NET_BIND_SERVICE.
The fixes are ordinary image hygiene and they make the image better on plain Kubernetes too. For images using OpenShift's group-0 permission convention, make only required data directories group-writable, for example RUN chgrp -R 0 /app/cache && chmod -R g=u /app/cache, after creating that directory. Declare a non-root USER. Listen on 8080 rather than 80. Do not depend on a username existing.
The wrong fix, which is common, is granting the workload the anyuid SCC so it can run as root. That works and throws away the property the platform was chosen for, and on a regulated cluster it is the sort of exception that appears in an audit.
The other additions:
Routes predate Ingress and do the same job with a simpler object, including automatic TLS with the cluster's certificate and edge, passthrough or re-encrypt termination. Ingress objects also work and are converted to Routes behind the scenes.
Projects are namespaces with extra metadata and a self-service creation workflow, so a developer can request one within quota rather than filing a ticket.
BuildConfig and ImageStream are the integrated build system: source-to-image can take a git repository and produce a runnable image without a Dockerfile, and an ImageStream tracks image tags so a new push can trigger a redeploy. Useful, and something to be deliberate about, because it is OpenShift-specific and building in your normal CI keeps you portable.
Operator Hub, an integrated catalogue of operators, plus integrated platform monitoring and console capabilities. Registry and logging installation, storage and support choices depend on the environment and enabled operators.
DeploymentConfig is the older OpenShift-native object with triggers and lifecycle hooks. New work should use a standard Deployment; you will meet DeploymentConfig in existing clusters.
Separate admission rejection from a runtime permission failure
In one example, a Deployment explicitly sets runAsUser: 0 and the service account cannot use an SCC permitting that UID. No pod starts. Inspect the ReplicaSet events and the account's permitted SCCs before changing the image.
In another example, admission assigns an allowed non-root UID and the pod starts, but the application cannot write /app/cache. Inspect the effective UID, group membership and permissions on that specific directory. Make only the required writable path compatible with the assigned identity; recursively granting write permission to the whole application also makes executable code writable.
Retest with the same service account and project policy as production. Confirm the pod's openshift.io/scc annotation and effective security context rather than inferring them from the Dockerfile alone. If a workload needs an exception, document the specific capability or UID requirement and scope access to its identity. OpenShift 4.20 SCC documentation describes defaults and allowed capabilities.
What interviewers probe next
"How do you debug a pod that will not start on OpenShift?" Look at the events for an SCC denial, then oc get pod -o yaml to see which SCC was admitted and what UID was assigned. The annotation openshift.io/scc on the pod names the one that allowed it.
"When is OpenShift worth the licence?" When you want a supported, opinionated platform with the security posture, monitoring and lifecycle already assembled, and particularly where a vendor support relationship is a requirement. Assembling the equivalent on vanilla Kubernetes is a real team.
"Is oc different from kubectl?" A superset. Everything kubectl does plus OpenShift-specific verbs like oc new-app and oc adm.
Common mistakes
Granting anyuid to make an image work, which removes the control rather than fixing the image.
Assuming a Dockerfile that works locally will run, when running as root is the default almost everywhere else and refused here.
Using chown to a specific UID in the Dockerfile instead of making paths group-0 writable.
Adopting source-to-image and ImageStreams for everything, then finding the build process does not move to another platform.