OpenShift
OpenShift (Red Hat OpenShift Container Platform, OCP) is Red Hat’s enterprise Kubernetes distribution and application platform. It is Kubernetes — certified CNCF-conformant, running unmodified upstream Kubernetes APIs — wrapped in a large, opinionated layer that turns the bare orchestrator into a full Platform-as-a-Service (Red Hat — OCP Architecture). That layer includes stricter security defaults (Security Context Constraints, non-root containers by default), Routes (OpenShift’s pre-Ingress Layer-7 object), an integrated image registry with ImageStreams and Source-to-Image (S2I) builds, a baked-in OperatorHub and Operator Lifecycle Manager, the OpenShift web console, Projects (namespaces with extra RBAC), CRI-O as the container runtime, and MachineConfig/Machine API for declarative node management. OpenShift Container Platform is the commercially-supported product; OKD is its free community upstream. Enterprises pick OpenShift for the vendor support, the opinionated-secure defaults, and the developer-facing PaaS experience — and pay for it with a heavier, more opinionated, Red Hat-licensed platform.
Mental Model
flowchart TB subgraph K8S["Vanilla Kubernetes (conformant core)"] API["kube-apiserver · etcd · scheduler · controllers"] WL["Pods · Deployments · Services · Ingress"] end subgraph OCP["OpenShift opinionated layer (on top)"] SCC["Security Context Constraints<br/>(non-root by default)"] ROUTE["Routes (L7 ingress object)"] REG["Integrated registry + ImageStreams"] S2I["Source-to-Image / BuildConfig"] OLM["OperatorHub + OLM"] CONSOLE["OpenShift web console"] MC["MachineConfig / Machine API"] CVO["Cluster Version Operator<br/>(operators run the cluster)"] end OCP -->|"adds enterprise PaaS layer onto"| K8S CRIO["CRI-O runtime"] --- WL HS["HyperShift<br/>hosted control planes"] -. "control plane as Pods" .-> API
What this shows. The bottom box is plain, conformant Kubernetes — your Deployment and Service manifests work unchanged. Everything in the upper box is OpenShift’s additive opinionated layer: it does not replace Kubernetes, it constrains and enriches it. The single most important architectural fact is the Cluster Version Operator at the bottom of the OCP box — OpenShift 4 is operator-driven: the cluster itself, every core component included, is reconciled by operators, so OpenShift upgrades are a single declarative version bump rather than a manual choreography.
Mechanical Walk-through
OpenShift 4 is operator-driven all the way down
The defining architectural choice of OpenShift 4 is that the entire cluster is managed by operators (Operator Pattern). A top-level Cluster Version Operator (CVO) reconciles a set of ~30 cluster operators, each owning one platform component — the API server, the ingress controller, the image registry, the monitoring stack, the console. Upgrading OpenShift is therefore declarative: you set a desired version, the CVO rolls every component (and the underlying OS) forward. This is a sharper version of the controller philosophy from Kubernetes Control Loop Pattern — applied not just to workloads but to the platform itself.
Each OCP 4.x minor release pins to a specific upstream Kubernetes release, and Red Hat publishes the mapping (Red Hat — k8s version per OCP release). As of writing (May 2026): OCP 4.18 → Kubernetes 1.31, and OCP 4.20 → Kubernetes 1.33 / CRI-O 1.33 (OCP 4.20 reached general availability on 21 October 2025 and is the current default channel; Red Hat Developer — OpenShift 4.20). OpenShift typically trails the upstream Kubernetes release by a few months because each OCP minor must take an upstream Kubernetes minor, integrate the full operator set on top, and pass Red Hat’s qualification — so “which Kubernetes am I really on?” is answered by the OCP version, not by the latest upstream tag.
Stricter security defaults — Security Context Constraints
OpenShift’s most operationally visible difference from vanilla Kubernetes is that it is secure by default in ways that break naive container images. The mechanism is Security Context Constraints (SCCs) — a security.openshift.io/v1 cluster resource that governs what a Pod’s SecurityContext is allowed to request: whether it may run as root, which UID ranges it may use, which Linux capabilities, whether it may use host networking or host paths (Red Hat — Managing SCCs).
SCCs are Red Hat’s predecessor to upstream Kubernetes’s Pod Security Standards / Pod Security Admission. They date from before PSS existed and are finer-grained — SCCs are bound to users/ServiceAccounts via RBAC, not labelled per namespace. The default restricted-v2 SCC forces Pods to run as a non-root, randomly-assigned UID and drops most capabilities. The practical consequence: a container image that hardcodes USER root or assumes UID 0 — common in Docker Hub images — fails to start on OpenShift until either the image is fixed to run rootless or an admin grants a more permissive SCC. This “OpenShift won’t run my image” experience is the single most common first encounter with the platform, and it is by design.
How SCCs coexist with upstream Pod Security Admission. Since OCP 4.11, OpenShift runs both SCCs and upstream Kubernetes Pod Security Admission (PSA) in parallel — PSA does not replace SCCs (Red Hat — PSA in OpenShift 4.11). The mechanism that keeps them from fighting is a label-synchronization controller: it introspects which SCCs the ServiceAccounts in each namespace are permitted (via RBAC) to “use”, maps the most-privileged of those SCCs to the equivalent Pod Security Standard, and automatically applies the matching PSA warn and audit labels to the namespace. That way PSA’s advisory output mirrors what the SCCs already allow, instead of emitting spurious warnings. Crucially, the cluster-wide PSA enforcement level is left at privileged (only warn/audit are set to restricted), so SCCs remain the authoritative admission gate while PSA is, by default, advisory. In short: SCCs do the real enforcement and are the layer to reason about for an OpenShift security design; PSA is synchronized to track them and provides the upstream-compatible label vocabulary. (Red Hat has signalled an intent to move PSA global enforcement to restricted in a future release; until that ships, treat SCCs as the binding control.)
Routes — OpenShift’s pre-Ingress L7 object
Before Kubernetes had Ingress, OpenShift already had Routes — a route.openshift.io/v1 resource that exposes a Service at an external hostname with Layer-7 (HTTP/HTTPS) routing, TLS termination, and edge/passthrough/re-encrypt TLS modes (Red Hat — Routes). Routes are served by an OpenShift Router (an HAProxy-based ingress controller, managed by a cluster operator). OpenShift today also supports standard Ingress and Gateway API — and in fact synthesizes a Route from an Ingress object — but Routes remain the native, more feature-rich object on the platform. Knowing that a Route is “OpenShift’s Ingress that predates Ingress” disambiguates the two objects you will see in any OpenShift cluster.
Integrated registry, ImageStreams, BuildConfig, and S2I
OpenShift bundles a full build-and-image pipeline that vanilla Kubernetes lacks entirely:
- An integrated container image registry runs inside the cluster.
- ImageStreams are an OpenShift abstraction over container images — a stable, namespaced pointer to image tags, with the property that updating an ImageStream tag can automatically trigger dependent builds and deployments. ImageStreams decouple “the name a Deployment refers to” from “the specific image digest currently behind it.”
- BuildConfig is a resource describing how to build an image inside the cluster.
- Source-to-Image (S2I) is OpenShift’s flagship build strategy: given a source-code repository and a language builder image, S2I produces a runnable application image without a Dockerfile (Red Hat — image builds). A developer pushes Java/Python/Node source; OpenShift detects the language, injects the source into the builder image, and emits a deployable image. This is the “PaaS” in OpenShift — the platform takes source and produces running Pods, not just orchestrates pre-built images.
OperatorHub and Operator Lifecycle Manager
OpenShift bakes in OperatorHub (a catalog of installable operators) and the Operator Lifecycle Manager (OLM) — the OLM is in fact a Red Hat project that OpenShift ships by default (Red Hat — Operators). An admin browses OperatorHub in the console, subscribes to an operator (databases, messaging, monitoring, service mesh), and OLM installs and keeps it upgraded via a Subscription resource. On vanilla Kubernetes you install operators by hand; on OpenShift the catalog-and-subscription workflow is first-class.
Projects, the console, CRI-O, MachineConfig
- Projects are OpenShift’s wrapper around namespaces — a namespace plus additional annotations and a self-service request workflow, with per-project RBAC defaults so developers can be granted “a project of their own.”
- The OpenShift web console is a full-featured admin and developer GUI — vanilla Kubernetes ships only the optional, minimal dashboard.
- CRI-O is OpenShift’s container runtime — a minimal, Kubernetes-only CRI runtime that Red Hat develops specifically as the OpenShift default, in place of the more general-purpose containerd.
- MachineConfig and the Machine API make node management declarative: a
MachineConfigobject describes node OS configuration (kernel args, files, systemd units), and the Machine API treats nodes as scalable, reconciled resources — OpenShift nodes run Red Hat CoreOS, an immutable, operator-updated OS.
HyperShift — hosted control planes
HyperShift is OpenShift’s hosted-control-plane offering: instead of running the control plane on dedicated machines per cluster, HyperShift runs each hosted cluster’s control plane as ordinary Pods inside a shared management cluster (GitHub — openshift/hypershift). This slashes the cost and provisioning time of new clusters and gives strong separation between management and tenant workloads — it is OpenShift’s instance of the “control plane as a service” pattern, the same idea as Kamaji and the Cluster API-adjacent hosted-control-plane approaches.
OKD — the community upstream
OKD is the free, community-supported distribution that OpenShift Container Platform is built from — the OpenShift analog of the Fedora-to-RHEL relationship (OKD). OKD has the same architecture, SCCs, Routes, S2I, and operator model; it lacks Red Hat’s commercial support, certified errata cadence, and some proprietary components.
Configuration / API Surface
# A Route — OpenShift's native L7 ingress object, with edge TLS termination.
apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: webapp
namespace: team-alpha
spec:
host: webapp.apps.ocp.example.com # external hostname the Router serves
to:
kind: Service
name: webapp # the in-cluster Service to expose
port:
targetPort: 8080
tls:
termination: edge # TLS terminated at the Router (vs passthrough/reencrypt)
---
# A custom SCC granting one ServiceAccount the right to run as a fixed UID.
apiVersion: security.openshift.io/v1
kind: SecurityContextConstraints
metadata:
name: allow-uid-1001
runAsUser:
type: MustRunAs # pin the UID rather than the random default
uid: 1001
allowPrivilegedContainer: false # still no privileged containers
allowHostNetwork: false
requiredDropCapabilities: [ALL] # drop every Linux capability
users:
- system:serviceaccount:team-alpha:legacy-app # who may use this SCC# Source-to-Image: build a runnable image straight from source — no Dockerfile.
oc new-app python:3.12~https://github.com/team-alpha/webapp.git
# ^builder image ^the '~' separates builder image from the source repo URL
# OpenShift creates an ImageStream, a BuildConfig, runs the S2I build,
# pushes to the integrated registry, and creates a Deployment + Service.
# Expose it through a Route in one command:
oc expose service/webappLine-by-line. The Route is route.openshift.io/v1, not networking.k8s.io/v1 — it is an OpenShift-specific kind; tls.termination: edge is a Route feature (TLS terminated at the Router) more ergonomic than the equivalent Ingress annotations. The custom SCC shows the platform’s security philosophy made concrete: by default a Pod gets a random non-root UID; this SCC, granted explicitly to one ServiceAccount, is what you write when a legacy app genuinely needs a fixed UID — note it still drops all capabilities and forbids privilege. The oc new-app line is the PaaS payoff: the python:3.12~<git-url> syntax hands OpenShift a builder image and a source repo, and S2I produces a deployed application — the single command that vanilla Kubernetes has no equivalent for.
Failure Modes
Docker Hub images that run as root fail to start. The number-one OpenShift surprise: an image with USER root or an implicit UID 0 is rejected by the default restricted-v2 SCC and the Pod never starts. Symptom: CreateContainerConfigError or a permission-denied crash. The correct fix is to rebuild the image rootless (arbitrary-UID-friendly: group-writable directories, no hardcoded UID); the lazy fix — granting the anyuid SCC — works but discards OpenShift’s security posture.
Confusing Routes and Ingress. A cluster has both Route and Ingress objects; teams editing one expecting the other’s behavior get confused. OpenShift synthesizes Routes from Ingress objects, so a stale synthesized Route can shadow an expected Ingress change.
Operator upgrade cascades. Because OpenShift is operator-driven, a cluster upgrade rolls ~30 cluster operators plus the OS. A single mis-reconciling cluster operator can stall the whole upgrade; diagnosing requires reading oc get clusteroperators and the failing operator’s status — a different troubleshooting model from a kubeadm cluster.
SCC mis-grants widen the blast radius. Granting privileged or anyuid SCCs broadly to make a stubborn image work undoes the platform’s hardening. SCCs are powerful and easy to over-grant; the discipline is least-privilege custom SCCs, not blanket permissive ones.
Resource weight. OpenShift’s full operator set, monitoring stack, registry, and console make it substantially heavier than a minimal Kubernetes cluster — control-plane nodes need more CPU/RAM than a kubeadm cluster of equivalent workload size. Under-provisioning the control plane is a common early mistake.
RHCOS immutability surprises. OpenShift nodes run Red Hat CoreOS, an immutable OS configured only through MachineConfig. Operators used to SSHing in and editing /etc find changes reverted on reboot — node configuration must go through MachineConfig.
Alternatives and When to Choose Them
Vanilla Kubernetes (kubeadm, Managed Kubernetes Services). Choose plain Kubernetes when you want the lightest, least-opinionated platform and your team is comfortable assembling the ingress controller, registry, build pipeline, and operator catalog themselves. OpenShift’s value is precisely the pre-assembly; if you don’t want the assembly, you don’t want the weight or the licensing.
Managed Kubernetes Services (EKS, GKE, AKS). Hyperscaler-managed Kubernetes is lighter and cloud-integrated but ships no PaaS layer — no S2I, no integrated registry-with-ImageStreams, no OperatorHub-by-default. Notably, Red Hat OpenShift is also available as a managed service on every major cloud (ROSA on AWS, ARO on Azure, OpenShift Dedicated on GCP), so “OpenShift vs managed Kubernetes” is not strictly either/or.
Lightweight Kubernetes Distributions (k3s, k0s). The opposite end of the spectrum — minimal, edge-focused, feature-stripped. Choose these when the goal is the smallest possible Kubernetes; OpenShift is the largest, most opinionated one.
OKD vs OpenShift Container Platform. Choose OKD for the OpenShift architecture and developer experience without licensing cost, accepting community-only support. Choose OCP when enterprise support, certified errata, and a contractual relationship matter — which, for the regulated enterprises that are OpenShift’s core market, they almost always do.
Production Notes
OpenShift’s enterprise traction is grounded in a specific value proposition: it bundles opinionated, secure-by-default decisions so that hundreds of teams across a large organization do not each re-derive how to do ingress, image builds, RBAC, and operator installation. The cost — heavier footprint, Red Hat licensing, less freedom to deviate from the platform’s opinions — is one that regulated industries (finance, government, healthcare) accept readily because the support relationship and the security defaults are exactly what their compliance posture needs.
The operator-driven cluster is OpenShift 4’s most-copied idea. Running the platform itself as a set of reconciled operators turned cluster upgrades from a feared manual procedure into a declarative version bump — and the broader industry has moved the same direction (Cluster API, the managed services’ internal automation). OpenShift productized the “the cluster manages itself” model years before it was common.
The non-root-by-default posture, enforced via SCCs, is OpenShift’s most underrated contribution to the ecosystem’s security hygiene. By making “your container must not need root” a hard requirement that surfaces immediately on first deploy, OpenShift pushed a generation of container images toward rootless operation — the same goal upstream Pod Security Standards later pursued cluster-wide. The friction of “OpenShift won’t run my root image” is, viewed correctly, the platform doing its job.
See Also
- CRI-O — the minimal Kubernetes-only container runtime that is OpenShift’s default
- Pod Security Standards — the upstream successor to OpenShift’s SCC mechanism
- Pod Security Admission — the upstream admission controller; runs in parallel with SCCs in OCP 4.11+, with a controller syncing PSA labels to SCC permissions
- SecurityContext — what SCCs constrain a Pod from requesting
- Operator Lifecycle Manager — the Red Hat project OpenShift ships as OperatorHub’s backbone
- Operator Pattern — the model OpenShift applies to the cluster itself, not just workloads
- Ingress, Gateway API — the upstream L7 objects alongside OpenShift’s native Routes
- Namespace — what an OpenShift Project wraps
- Managed Kubernetes Services — including ROSA/ARO, the managed-OpenShift offerings
- Lightweight Kubernetes Distributions — the opposite, minimalist end of the distribution spectrum
- Self-Managed Kubernetes — OpenShift is an opinionated take on running your own cluster
- Kubernetes MOC — §17, the parent map