Qué vas a conseguir
Un clúster OpenShift en el que cada equipo tiene su proyecto, entra con su cuenta corporativa y despliega sin pedirte permiso para cada cosa; una aplicación interna publicada con una Route; un procedimiento de actualización que no te pilla por sorpresa, y los dos tickets que más llegan resueltos en minutos.
Antes de empezar
- Un clúster OpenShift Container Platform 4.x ya instalado (en vSphere, Nutanix, bare metal o en la nube) y acceso de
cluster-admin. - El cliente
ocde la misma versión menor que el clúster (se descarga desde la propia consola: icono de ayuda › Herramientas de línea de comandos). - Saber qué es un Pod, un Deployment y un Service: la guía de Kubernetes lo cuenta. Aquí se habla de lo que OpenShift pone encima.
1. Lo que OpenShift añade a Kubernetes
| Kubernetes | OpenShift |
|---|---|
| Namespace | Project: un namespace con plantilla, cuotas y permisos por defecto al crearlo |
| Ingress (si instalas un controlador) | Route servida por el router HAProxy integrado, con TLS en el borde, re-encrypt o passthrough |
| Pod Security Admission | Además, Security Context Constraints (SCC): por defecto los pods corren con un UID aleatorio y sin privilegios (restricted-v2) |
| Dashboard opcional | Consola web completa: cargas de trabajo, logs, métricas, alertas y actualizaciones |
| Helm o manifiestos | Operators desde el catálogo (OperatorHub) gestionados por OLM, y el propio clúster se gestiona con Operators |
| Registro externo | Registro integrado (image-registry.openshift-image-registry.svc:5000) y builds con BuildConfig / Source-to-Image |
Lo que más cambia en el día a día es la SCC: una imagen que en un Kubernetes cualquiera arranca como root, aquí no lo hace. Es intencionado y es la causa del primer ticket de la sección 6.
2. Entrar con oc y crear el proyecto
En la consola, menú de usuario › Copy login command da el token de la sesión. Con él:
oc login --token=sha256~XXXXXXXX --server=https://api.ocp01.contoso.example.com:6443
Después, oc new-project finanzas-informes --display-name="Finanzas · Informes" crea el proyecto y lo deja como activo, y oc whoami --show-console devuelve la URL de la consola.
- Todo lo que se crea a partir de aquí va al proyecto activo;
oc projectdice cuál es yoc get projectslista los tuyos.
3. Desplegar una aplicación interna
La forma rápida es oc new-app, que crea el Deployment y el Service a partir de una imagen:
oc new-app --name=informes registry.contoso.example.com/finanzas/informes:1.4.2--> Creating resources ... deployment.apps "informes" created service "informes" created--> Successoc create route edge informes --service=informes --hostname=informes.apps.ocp01.contoso.example.comroute.route.openshift.io/informes createdoc get pods,routeNAME READY STATUS RESTARTS AGEpod/informes-6d9c7b9f5c-2kqzl 1/1 Running 0 48sNAME HOST/PORT SERVICES PORT TERMINATIONroute.route.openshift.io/informes informes.apps.ocp01.contoso.example.com informes 8080-tcp edge- Para producción, guarda los manifiestos (Deployment, Service, Route) en Git y aplícalos con
oc apply -fo con OpenShift GitOps (Argo CD).new-appsirve para empezar; lo que no está en Git no se puede reconstruir. - edge termina TLS en el router con el certificado comodín de
*.apps; re-encrypt vuelve a cifrar hasta el pod; passthrough deja el TLS al pod. - Añade readiness y liveness probes: sin ellas el router manda tráfico a pods que aún no responden.
4. Acceso de un equipo: proveedor de identidad y RoleBindings
Tras la instalación solo existe kubeadmin. Lo primero es conectar el proveedor de identidad. Con Entra ID se usa OpenID Connect: registra una aplicación en Entra ID con la URL de retorno https://oauth-openshift.apps.ocp01.contoso.example.com/oauth2callback/entra-id, guarda su secreto en openshift-config y añádela al recurso OAuth:
- Con LDAP / Active Directory el proveedor es de tipo LDAP y los grupos se traen con
oc adm groups syncy un fichero de configuración, programado como CronJob. - Los permisos se dan a grupos, nunca a personas:
oc adm policy add-role-to-group edit grp-ocp-finanzas -n finanzas-informes
- Roles predefinidos:
view(solo lectura),edit(desplegar),admin(además gestionar permisos del proyecto).cluster-adminsolo para el equipo de plataforma, y mejor con un grupo dedicado. - Cuando el proveedor funciona y hay al menos un
cluster-adminde grupo, eliminakubeadmin:oc delete secrets kubeadmin -n kube-system.
Antes de borrar kubeadmin, entra con una cuenta del grupo de administradores en otra ventana. Si el proveedor falla después, el acceso de emergencia es el kubeconfig de la instalación: guárdalo en la caja fuerte de credenciales.
5. Actualizar el clúster por canales
OpenShift se actualiza entero (sistema operativo de los nodos incluido) desde el Cluster Version Operator. El canal decide qué versiones se ofrecen: stable-4.x para producción, fast-4.x cuando quieres la versión antes, eus-4.x en las versiones pares para saltar de EUS a EUS.
oc get clusterversionNAME VERSION AVAILABLE PROGRESSING SINCE STATUSversion 4.20.14 True False 23d Cluster version is 4.20.14oc adm upgradeCluster version is 4.20.14Channel: stable-4.20Recommended updates: VERSION IMAGE 4.20.18 quay.io/openshift-release-dev/ocp-release@sha256:...oc adm upgrade --to=4.20.18Requested update to 4.20.18oc get clusteroperators | grep -v "True False False"NAME VERSION AVAILABLE PROGRESSING DEGRADEDmachine-config 4.20.14 True True False- Antes: todos los
clusteroperatorsen Available y sin Degraded, losMachineConfigPoolactualizados (oc get mcp) y las notas de la versión leídas, sobre todo las APIs retiradas (el clúster pide un admin-ack cuando hay alguna). - Los nodos se reinician de uno en uno. Los PodDisruptionBudget mal puestos (mínimo disponible igual al número de réplicas) bloquean el drenado: es la causa más habitual de una actualización parada.
- Para controlar el ritmo en los workers, pausa su pool (
oc patch mcp worker --type merge -p '{"spec":{"paused":true}}') y reanúdalo en la ventana.
6. El ticket: "el pod no arranca: permission denied"
Una imagen de nginx publicada en Docker Hub entra en CrashLoopBackOff:
oc logs deploy/portalnginx: [emerg] mkdir() "/var/cache/nginx/client_temp" failed (13: Permission denied)oc get pod portal-7f8d6c5b4-xk2vp -o jsonpath='{.metadata.annotations.openshift\.io/scc}{"\n"}'restricted-v2oc get pod portal-7f8d6c5b4-xk2vp -o jsonpath='{.spec.containers[0].securityContext.runAsUser}{"\n"}'1000680000El pod corre con un UID del rango del proyecto, no como root, y la imagen espera escribir en carpetas de root. Por orden de preferencia:
- Usar una imagen preparada para UID arbitrario (las UBI de Red Hat o las variantes unprivileged), o ajustar el Dockerfile para que las carpetas de escritura pertenezcan al grupo 0 con permisos de grupo.
- Montar un
emptyDiren las rutas donde escribe. - Solo si no hay otra salida, una cuenta de servicio propia con la SCC
nonroot-v2oanyuid(oc adm policy add-scc-to-user anyuid -z sa-portal), documentada como excepción. Nunca a la cuentadefaultni conprivileged.
La variante: "la Route devuelve 503 Application is not available". El router no encuentra un pod sano detrás del Service. Revisa en este orden: oc get endpoints portal (si está vacío, el selector del Service no coincide con las etiquetas de los pods, o los pods no están Ready); oc describe route portal (¿apunta al Service y al puerto correctos?), y el targetPort del Service frente al puerto en el que escucha realmente el contenedor.
7. Lo que revisas cada mes
- Actualizaciones pendientes del canal y el fin de soporte de la versión menor en uso.
- Alertas activas en Observar › Alertas, certificados próximos a caducar y uso de disco de etcd.
- Excepciones de SCC concedidas: quién, para qué y si siguen haciendo falta.
- Proyectos sin propietario o sin cuota, y RoleBindings a usuarios individuales que deberían ser de grupo.
Siguientes pasos
- La guía de Kubernetes para lo que comparte con OpenShift: Deployments, probes, recursos y almacenamiento.
- Terraform para crear la infraestructura del clúster y los registros DNS de
apiy*.apps. - La guía de Entra ID: SSO/SAML para el registro de aplicaciones y los grupos en el token.
- Azure Monitor y Log Analytics o Grafana si quieres llevar las métricas y logs fuera del clúster.
¿Falta algo o en tu entorno es distinto? Escríbeme y lo corrijo.
What you'll get
An OpenShift cluster in which each team has its own project, signs in with its corporate account and deploys without asking you for every change; an internal application published with a Route; an upgrade procedure that doesn't take you by surprise, and the two most common tickets solved in minutes.
Before you start
- An OpenShift Container Platform 4.x cluster already installed (on vSphere, Nutanix, bare metal or in the cloud) and
cluster-adminaccess. - The
occlient at the same minor version as the cluster (downloadable from the console itself: help icon › Command line tools). - Knowing what a Pod, a Deployment and a Service are: the Kubernetes guide covers that. This one is about what OpenShift puts on top.
1. What OpenShift adds to Kubernetes
| Kubernetes | OpenShift |
|---|---|
| Namespace | Project: a namespace with a template, quotas and default permissions on creation |
| Ingress (if you install a controller) | Route served by the built-in HAProxy router, with edge, re-encrypt or passthrough TLS |
| Pod Security Admission | Plus Security Context Constraints (SCCs): by default pods run with a random UID and no privileges (restricted-v2) |
| Optional dashboard | Full web console: workloads, logs, metrics, alerts and upgrades |
| Helm or manifests | Operators from the catalogue (OperatorHub) managed by OLM, and the cluster itself is run by Operators |
| External registry | Integrated registry (image-registry.openshift-image-registry.svc:5000) and builds with BuildConfig / Source-to-Image |
What changes most day to day is the SCC: an image that starts as root on any other Kubernetes does not start that way here. That is deliberate, and it is the cause of the first ticket in section 6.
2. Sign in with oc and create the project
In the console, user menu › Copy login command gives the session token. With it:
oc login --token=sha256~XXXXXXXX --server=https://api.ocp01.contoso.example.com:6443
Then oc new-project finance-reports --display-name="Finance · Reports" creates the project and makes it active, and oc whoami --show-console returns the console URL.
- Everything created from here goes into the active project;
oc projecttells you which one andoc get projectslists yours.
3. Deploy an internal application
The quick way is oc new-app, which creates the Deployment and the Service from an image:
oc new-app --name=reports registry.contoso.example.com/finance/reports:1.4.2--> Creating resources ... deployment.apps "reports" created service "reports" created--> Successoc create route edge reports --service=reports --hostname=reports.apps.ocp01.contoso.example.comroute.route.openshift.io/reports createdoc get pods,routeNAME READY STATUS RESTARTS AGEpod/reports-6d9c7b9f5c-2kqzl 1/1 Running 0 48sNAME HOST/PORT SERVICES PORT TERMINATIONroute.route.openshift.io/reports reports.apps.ocp01.contoso.example.com reports 8080-tcp edge- For production, keep the manifests (Deployment, Service, Route) in Git and apply them with
oc apply -for with OpenShift GitOps (Argo CD).new-appis for getting started; what isn't in Git can't be rebuilt. - edge terminates TLS at the router with the
*.appswildcard certificate; re-encrypt encrypts again to the pod; passthrough leaves TLS to the pod. - Add readiness and liveness probes: without them the router sends traffic to pods that aren't answering yet.
4. Team access: identity provider and RoleBindings
After installation only kubeadmin exists. The first thing is to connect the identity provider. With Entra ID it is OpenID Connect: register an application in Entra ID with the redirect URL https://oauth-openshift.apps.ocp01.contoso.example.com/oauth2callback/entra-id, store its secret in openshift-config and add it to the OAuth resource:
- With LDAP / Active Directory the provider is of type LDAP and groups are brought in with
oc adm groups syncand a configuration file, scheduled as a CronJob. - Permissions go to groups, never to people:
oc adm policy add-role-to-group edit grp-ocp-finance -n finance-reports
- Built-in roles:
view(read only),edit(deploy),admin(also manage the project's permissions).cluster-adminonly for the platform team, and preferably through a dedicated group. - Once the provider works and there is at least one group-based
cluster-admin, removekubeadmin:oc delete secrets kubeadmin -n kube-system.
Before deleting kubeadmin, sign in with an account from the administrators group in another window. If the provider fails later, the emergency access is the installation kubeconfig: keep it in the credentials vault.
5. Upgrade the cluster through channels
OpenShift is upgraded as a whole (including the nodes' operating system) by the Cluster Version Operator. The channel decides which versions are offered: stable-4.x for production, fast-4.x when you want the release earlier, eus-4.x on even versions to jump from EUS to EUS.
oc get clusterversionNAME VERSION AVAILABLE PROGRESSING SINCE STATUSversion 4.20.14 True False 23d Cluster version is 4.20.14oc adm upgradeCluster version is 4.20.14Channel: stable-4.20Recommended updates: VERSION IMAGE 4.20.18 quay.io/openshift-release-dev/ocp-release@sha256:...oc adm upgrade --to=4.20.18Requested update to 4.20.18oc get clusteroperators | grep -v "True False False"NAME VERSION AVAILABLE PROGRESSING DEGRADEDmachine-config 4.20.14 True True False- Beforehand: every
clusteroperatorAvailable and not Degraded, theMachineConfigPoolsup to date (oc get mcp) and the release notes read, especially removed APIs (the cluster asks for an admin-ack when there are any). - Nodes reboot one at a time. Badly set PodDisruptionBudgets (minimum available equal to the number of replicas) block the drain: the most common cause of a stalled upgrade.
- To control the pace on the workers, pause their pool (
oc patch mcp worker --type merge -p '{"spec":{"paused":true}}') and resume it in the window.
6. The ticket: "the pod won't start: permission denied"
An nginx image published on Docker Hub goes into CrashLoopBackOff:
oc logs deploy/portalnginx: [emerg] mkdir() "/var/cache/nginx/client_temp" failed (13: Permission denied)oc get pod portal-7f8d6c5b4-xk2vp -o jsonpath='{.metadata.annotations.openshift\.io/scc}{"\n"}'restricted-v2oc get pod portal-7f8d6c5b4-xk2vp -o jsonpath='{.spec.containers[0].securityContext.runAsUser}{"\n"}'1000680000The pod runs with a UID from the project's range, not as root, and the image expects to write to root-owned folders. In order of preference:
- Use an image built for an arbitrary UID (Red Hat UBI images or the unprivileged variants), or adjust the Dockerfile so the writable folders belong to group 0 with group permissions.
- Mount an
emptyDiron the paths it writes to. - Only if there is no other way, a dedicated service account with the
nonroot-v2oranyuidSCC (oc adm policy add-scc-to-user anyuid -z sa-portal), documented as an exception. Never on thedefaultaccount and neverprivileged.
The variant: "the Route returns 503 Application is not available". The router can't find a healthy pod behind the Service. Check in this order: oc get endpoints portal (if empty, the Service selector doesn't match the pods' labels, or the pods aren't Ready); oc describe route portal (does it point to the right Service and port?), and the Service targetPort against the port the container actually listens on.
7. What you review each month
- Pending updates in the channel and the end of support of the minor version in use.
- Active alerts in Observe › Alerting, certificates about to expire and etcd disk usage.
- SCC exceptions granted: who, what for, and whether they are still needed.
- Projects with no owner or no quota, and RoleBindings to individual users that should be group-based.
Next steps
- The Kubernetes guide for what it shares with OpenShift: Deployments, probes, resources and storage.
- Terraform to build the cluster's infrastructure and the DNS records for
apiand*.apps. - The Entra ID: SSO/SAML guide for app registrations and groups in the token.
- Azure Monitor and Log Analytics or Grafana if you want to take metrics and logs out of the cluster.
Is something missing, or different in your environment? Get in touch and I'll fix it.
Tech Career Lab · newsletter
¿Te ha servido? Cada dos semanas envío una idea práctica para perfiles IT: LinkedIn, proyectos, networking y procesos de selección.Found this useful? Every two weeks I send one practical idea for IT professionals: LinkedIn, projects, networking and hiring processes.
Apúntate y llévate las 33 ideasSign up and get the 33 ideas →