OpenShift
Deploy and manage applications on Red Hat OpenShift Container Platform.
When to Use This Skill
Use this skill when:
- Deploying applications to OpenShift clusters
- Using OpenShift-specific features (Routes, BuildConfigs)
- Managing projects and RBAC in OpenShift
- Implementing S2I (Source-to-Image) builds
- Working with OpenShift Operators
Prerequisites
- OpenShift cluster access
- oc CLI installed
- Basic Kubernetes knowledge
CLI Basics
Authentication
bash# Login to cluster oc login https://api.cluster.example.com:6443 -u admin -p password # Login with token oc login --token=sha256~xxxx --server=https://api.cluster.example.com:6443 # Check current context oc whoami oc whoami --show-server oc whoami --show-context # Logout oc logout
Project Management
bash# Create project (namespace) oc new-project myapp --display-name="My App" --description="My Application" # Switch project oc project myapp # List projects oc projects # Delete project oc delete project myapp
Deploying Applications
From Image
bash# Deploy from container image oc new-app --image=nginx:latest --name=webserver # Deploy from Docker Hub oc new-app docker.io/library/nginx:latest # Deploy with environment variables oc new-app myimage:latest \ -e DATABASE_URL=postgres://localhost/db \ -e APP_ENV=production
From Source (S2I)
bash# Deploy from Git repository oc new-app https://github.com/org/myapp.git # Specify builder image oc new-app nodejs:18~https://github.com/org/nodejs-app.git # With context directory oc new-app https://github.com/org/monorepo.git \ --context-dir=backend \ --name=backend-api
From Template
bash# List available templates oc get templates -n openshift # Deploy from template oc new-app postgresql-persistent \ -p POSTGRESQL_USER=user \ -p POSTGRESQL_PASSWORD=secret \ -p POSTGRESQL_DATABASE=mydb
Routes
Creating Routes
yamlapiVersion: route.openshift.io/v1 kind: Route metadata: name: myapp spec: host: myapp.apps.cluster.example.com to: kind: Service name: myapp weight: 100 port: targetPort: 8080 tls: termination: edge insecureEdgeTerminationPolicy: Redirect
bash# Create route via CLI oc expose svc/myapp # Create with custom hostname oc create route edge myapp \ --service=myapp \ --hostname=myapp.apps.cluster.example.com # Create passthrough route (TLS termination at pod) oc create route passthrough myapp-secure --service=myapp
A/B Testing
yamlapiVersion: route.openshift.io/v1 kind: Route metadata: name: myapp spec: to: kind: Service name: myapp-v1 weight: 90 alternateBackends: - kind: Service name: myapp-v2 weight: 10
Build Configurations
BuildConfig
yamlapiVersion: build.openshift.io/v1 kind: BuildConfig metadata: name: myapp spec: source: type: Git git: uri: https://github.com/org/myapp.git ref: main strategy: type: Docker dockerStrategy: dockerfilePath: Dockerfile output: to: kind: ImageStreamTag name: myapp:latest triggers: - type: ConfigChange - type: GitHub github: secret: webhook-secret
S2I Build
yamlapiVersion: build.openshift.io/v1 kind: BuildConfig metadata: name: myapp spec: source: type: Git git: uri: https://github.com/org/myapp.git strategy: type: Source sourceStrategy: from: kind: ImageStreamTag namespace: openshift name: nodejs:18-ubi8 env: - name: NPM_RUN value: start output: to: kind: ImageStreamTag name: myapp:latest
Build Commands
bash# Start build oc start-build myapp # Start build from local source oc start-build myapp --from-dir=. # Follow build logs oc start-build myapp --follow # View build logs oc logs -f bc/myapp # Cancel build oc cancel-build myapp-1
Image Streams
yamlapiVersion: image.openshift.io/v1 kind: ImageStream metadata: name: myapp spec: lookupPolicy: local: true tags: - name: latest from: kind: DockerImage name: registry.example.com/myapp:latest importPolicy: scheduled: true
bash# Create image stream oc create imagestream myapp # Import image oc import-image myapp:latest \ --from=docker.io/library/nginx:latest \ --confirm # Tag image oc tag myapp:latest myapp:production
Deployment Configs
yamlapiVersion: apps.openshift.io/v1 kind: DeploymentConfig metadata: name: myapp spec: replicas: 3 selector: app: myapp template: metadata: labels: app: myapp spec: containers: - name: myapp image: myapp:latest ports: - containerPort: 8080 resources: requests: memory: "128Mi" cpu: "100m" limits: memory: "256Mi" cpu: "500m" triggers: - type: ConfigChange - type: ImageChange imageChangeParams: automatic: true containerNames: - myapp from: kind: ImageStreamTag name: myapp:latest strategy: type: Rolling rollingParams: maxSurge: 25% maxUnavailable: 25%
ConfigMaps and Secrets
bash# Create ConfigMap oc create configmap myapp-config \ --from-literal=APP_ENV=production \ --from-file=config.yaml # Create Secret oc create secret generic myapp-secrets \ --from-literal=password=secret123 # Mount as volume oc set volume dc/myapp \ --add --name=config \ --type=configmap \ --configmap-name=myapp-config \ --mount-path=/etc/config # Set as environment oc set env dc/myapp --from=secret/myapp-secrets
Security Context Constraints
bash# List SCCs oc get scc # View SCC details oc describe scc restricted # Grant SCC to service account oc adm policy add-scc-to-user anyuid -z myapp-sa -n myproject # Create service account oc create serviceaccount myapp-sa
Custom SCC
yamlapiVersion: security.openshift.io/v1 kind: SecurityContextConstraints metadata: name: myapp-scc allowPrivilegedContainer: false runAsUser: type: MustRunAsNonRoot seLinuxContext: type: MustRunAs fsGroup: type: RunAsAny volumes: - configMap - secret - persistentVolumeClaim users: - system:serviceaccount:myproject:myapp-sa
Operators
bash# List available operators oc get packagemanifests -n openshift-marketplace # Subscribe to operator cat <<EOF | oc apply -f - apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: prometheus namespace: openshift-operators spec: channel: stable name: prometheus source: community-operators sourceNamespace: openshift-marketplace EOF # View installed operators oc get csv -n openshift-operators
Monitoring
bash# View pod logs oc logs -f pod/myapp-1-xyz # View events oc get events --sort-by='.lastTimestamp' # Resource usage oc adm top pods oc adm top nodes # Debug pod oc debug pod/myapp-1-xyz
Common Issues
Issue: Build Fails
Problem: S2I build cannot find dependencies Solution: Check builder image, verify source repository access
Issue: Pod Security Violation
Problem: Pod fails to start due to SCC Solution: Use appropriate SCC or modify container security context
Issue: Route Not Working
Problem: Cannot access application via route Solution: Verify service selector, check router pods, validate DNS
Issue: Image Pull Error
Problem: Cannot pull image from registry Solution: Create image pull secret, link to service account
bashoc create secret docker-registry regcred \ --docker-server=registry.example.com \ --docker-username=user \ --docker-password=pass oc secrets link default regcred --for=pull
Best Practices
- Use Projects for isolation (not just namespaces)
- Leverage ImageStreams for image management
- Use BuildConfigs for CI/CD integration
- Implement proper SCCs (avoid privileged)
- Use Routes instead of Ingress
- Leverage OpenShift templates for repeatability
- Monitor with built-in Prometheus
- Use Operators for complex applications
Related Skills
- kubernetes-ops - K8s fundamentals
- helm-charts - Helm deployments
- container-registries - Image management


