OKD: Community Kubernetes Platform Complete Guide
OKD (Origin Kubernetes Distribution) is the community-supported Kubernetes platform that serves as the upstream for Red Hat OpenShift. OKD provides the same enterprise features as OpenShift - including integrated CI/CD, developer workflows, operators, and security - without licensing costs. Built on Fedora CoreOS, OKD offers a production-ready platform for organizations seeking enterprise Kubernetes capabilities with open-source flexibility.
What is OKD?
OKD is the upstream, community-driven Kubernetes distribution that provides:
Key Features
- 100% Open Source: No licensing costs, full source access
- Enterprise Features: Same capabilities as OpenShift
- Integrated Developer Tools: S2I, BuildConfigs, DeploymentConfigs
- Operator Framework: Automated application lifecycle
- Built-in CI/CD: OpenShift Pipelines (Tekton)
- Service Mesh: Integrated Istio
- Monitoring Stack: Prometheus + Grafana
- Web Console: Full-featured dashboard
- Security: SELinux, SCCs, RBAC
- Fedora CoreOS: Immutable, auto-updating OS
OKD vs OpenShift vs Kubernetes
| Feature | OKD | OpenShift | Kubernetes |
|---|---|---|---|
| Cost | Free | Commercial | Free |
| Support | Community | Red Hat | Community |
| Release Cycle | Faster | Stable/LTS | Regular |
| Base OS | Fedora CoreOS | RHEL CoreOS | Various |
| Updates | Rolling | Controlled | Manual |
| Lifecycle | Community-driven | Enterprise | Community |
| Features | Full | Full | Core only |
| Stability | Beta/Stable | Production | Production |
| Best For | Dev/Test, Cost-sensitive | Enterprise | DIY |
Architecture
┌──────────────────────────────────────────────────────────────┐│ OKD Control Plane ││ ││ ┌──────────────────────────────────────────────────────┐ ││ │ Kubernetes Core Components │ ││ │ │ ││ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ ││ │ │ API Server │ │ Scheduler │ │ Controller │ │ ││ │ │ │ │ │ │ Manager │ │ ││ │ └─────────────┘ └─────────────┘ └─────────────┘ │ ││ │ │ ││ │ ┌──────────────────────────────────────────────┐ │ ││ │ │ etcd Cluster │ │ ││ │ └──────────────────────────────────────────────┘ │ ││ └──────────────────────────────────────────────────────┘ ││ ││ ┌──────────────────────────────────────────────────────┐ ││ │ OpenShift/OKD Platform Services │ ││ │ │ ││ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ ││ │ │ OAuth │ │ Image │ │ Router │ │ ││ │ │ Server │ │ Registry │ │ (HAProxy) │ │ ││ │ └─────────────┘ └─────────────┘ └─────────────┘ │ ││ │ │ ││ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ ││ │ │ Web │ │ Monitoring │ │ Logging │ │ ││ │ │ Console │ │ (Prom/Graf) │ │ (EFK) │ │ ││ │ └─────────────┘ └─────────────┘ └─────────────┘ │ ││ │ │ ││ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ ││ │ │ Pipelines │ │ Operators │ │ Service │ │ ││ │ │ (Tekton) │ │ Framework │ │ Mesh │ │ ││ │ └─────────────┘ └─────────────┘ └─────────────┘ │ ││ └──────────────────────────────────────────────────────┘ │└──────────────────────────────────────────────────────────────┘ │ ┌────────────┴────────────┐ ▼ ▼┌───────────────────────────┐ ┌───────────────────────────┐│ Worker Nodes │ │ Infrastructure Nodes ││ (Fedora CoreOS) │ │ (Fedora CoreOS) ││ │ │ ││ • CRI-O Runtime │ │ • Image Registry ││ • kubelet │ │ • Router/Ingress ││ • Application Pods │ │ • Monitoring Stack ││ • Storage CSI │ │ • Logging Stack │└───────────────────────────┘ └───────────────────────────┘Installation
Prerequisites
Minimum Requirements:
- 3 control plane nodes: 4 vCPU, 16 GB RAM, 120 GB disk
- 2+ worker nodes: 2 vCPU, 8 GB RAM, 120 GB disk
- 1 bootstrap node (temporary): 4 vCPU, 16 GB RAM, 120 GB disk
- DNS configured (wildcard *.apps record)
- Load balancer for API (6443) and apps (80/443)
- DHCP with MAC reservations or static IPs
Recommended Production:
- 3 control plane: 8 vCPU, 32 GB RAM, 250 GB SSD
- 5+ workers: 16 vCPU, 64 GB RAM, 500 GB SSD
- 3 infrastructure nodes: 8 vCPU, 16 GB RAM, 250 GB SSD
- 10 Gbps network
- Separate storage for persistent volumes
DNS Configuration
# Required DNS records for cluster "okd" in domain "example.com"
# API and API-INT (both point to load balancer)api.okd.example.com. A 192.168.1.100api-int.okd.example.com. A 192.168.1.100
# Wildcard for applications (points to load balancer)*.apps.okd.example.com. A 192.168.1.101
# etcd nodes (control planes)etcd-0.okd.example.com. A 192.168.1.11etcd-1.okd.example.com. A 192.168.1.12etcd-2.okd.example.com. A 192.168.1.13
# SRV records for etcd_etcd-server-ssl._tcp.okd.example.com. 86400 IN SRV 0 10 2380 etcd-0.okd.example.com._etcd-server-ssl._tcp.okd.example.com. 86400 IN SRV 0 10 2380 etcd-1.okd.example.com._etcd-server-ssl._tcp.okd.example.com. 86400 IN SRV 0 10 2380 etcd-2.okd.example.com.
# Control plane nodesmaster-0.okd.example.com. A 192.168.1.11master-1.okd.example.com. A 192.168.1.12master-2.okd.example.com. A 192.168.1.13
# Worker nodesworker-0.okd.example.com. A 192.168.1.21worker-1.okd.example.com. A 192.168.1.22
# Bootstrap (temporary)bootstrap.okd.example.com. A 192.168.1.10
# Verify DNSdig +short api.okd.example.comdig +short *.apps.okd.example.comdig +short _etcd-server-ssl._tcp.okd.example.com SRVLoad Balancer Configuration
# HAProxy configuration for OKDglobal log /dev/log local0 chroot /var/lib/haproxy stats timeout 30s user haproxy group haproxy daemon maxconn 4096
defaults log global mode tcp option tcplog option dontlognull timeout connect 5000 timeout client 50000 timeout server 50000
# API Server (6443)frontend api_frontend bind *:6443 mode tcp default_backend api_backend
backend api_backend mode tcp balance roundrobin server bootstrap 192.168.1.10:6443 check server master-0 192.168.1.11:6443 check server master-1 192.168.1.12:6443 check server master-2 192.168.1.13:6443 check
# Machine Config Server (22623)frontend machine_config_frontend bind *:22623 mode tcp default_backend machine_config_backend
backend machine_config_backend mode tcp balance roundrobin server bootstrap 192.168.1.10:22623 check server master-0 192.168.1.11:22623 check server master-1 192.168.1.12:22623 check server master-2 192.168.1.13:22623 check
# HTTP Ingress (80)frontend http_frontend bind *:80 mode tcp default_backend http_backend
backend http_backend mode tcp balance roundrobin server worker-0 192.168.1.21:80 check server worker-1 192.168.1.22:80 check
# HTTPS Ingress (443)frontend https_frontend bind *:443 mode tcp default_backend https_backend
backend https_backend mode tcp balance roundrobin server worker-0 192.168.1.21:443 check server worker-1 192.168.1.22:443 checkInstallation Process
# Download OKD installer and CLIVERSION=4.15.0-0.okd-2024-02-23-163410wget https://github.com/okd-project/okd/releases/download/${VERSION}/openshift-install-linux-${VERSION}.tar.gzwget https://github.com/okd-project/okd/releases/download/${VERSION}/openshift-client-linux-${VERSION}.tar.gz
# Extracttar xvf openshift-install-linux-${VERSION}.tar.gztar xvf openshift-client-linux-${VERSION}.tar.gzsudo mv openshift-install oc kubectl /usr/local/bin/
# Create install directorymkdir ~/okd-installcd ~/okd-install
# Generate SSH key for core user accessssh-keygen -t ed25519 -N '' -f ~/.ssh/okd-key
# Get pull secret from https://console.redhat.com/openshift/downloads# For OKD, create minimal pull secret:cat > pull-secret.json << 'EOF'{"auths":{"fake":{"auth":"aGVsbG86d29ybGQ="}}}EOF
# Create install-config.yamlcat > install-config.yaml << 'EOF'apiVersion: v1baseDomain: example.commetadata: name: okd
compute:- name: worker replicas: 2 platform: {}
controlPlane: name: master replicas: 3 platform: {}
networking: networkType: OVNKubernetes clusterNetwork: - cidr: 10.128.0.0/14 hostPrefix: 23 serviceNetwork: - 172.30.0.0/16 machineNetwork: - cidr: 192.168.1.0/24
platform: none: {}
pullSecret: '{"auths":{"fake":{"auth":"aGVsbG86d29ybGQ="}}}'
sshKey: | ssh-ed25519 AAAAC3...your-key-here...
fips: false
# Optional: Custom certificates# additionalTrustBundle: |# -----BEGIN CERTIFICATE-----# ...# -----END CERTIFICATE-----EOF
# Backup config (installer consumes it)cp install-config.yaml install-config.yaml.backup
# Generate ignition configsopenshift-install create ignition-configs --dir ~/okd-install
# Files generated:# - bootstrap.ign# - master.ign# - worker.ign# - metadata.json# - auth/kubeconfig# - auth/kubeadmin-password
# Host ignition files on web serversudo mkdir -p /var/www/html/okdsudo cp ~/okd-install/*.ign /var/www/html/okd/sudo chmod 644 /var/www/html/okd/*.ign
# Start web serversudo python3 -m http.server 8080 --directory /var/www/htmlBoot Nodes
# For each node, boot from Fedora CoreOS live ISO with kernel parameters:
# Bootstrap node:coreos.inst.install_dev=sda \coreos.inst.image_url=https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/latest/x86_64/fedora-coreos-metal.x86_64.raw.xz \coreos.inst.ignition_url=http://192.168.1.1:8080/okd/bootstrap.ign \ip=192.168.1.10::192.168.1.1:255.255.255.0:bootstrap.okd.example.com:ens192:none \nameserver=192.168.1.1
# Control plane nodes (repeat for master-0, master-1, master-2):coreos.inst.install_dev=sda \coreos.inst.image_url=https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/latest/x86_64/fedora-coreos-metal.x86_64.raw.xz \coreos.inst.ignition_url=http://192.168.1.1:8080/okd/master.ign \ip=192.168.1.11::192.168.1.1:255.255.255.0:master-0.okd.example.com:ens192:none \nameserver=192.168.1.1
# Worker nodes:coreos.inst.install_dev=sda \coreos.inst.image_url=https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/latest/x86_64/fedora-coreos-metal.x86_64.raw.xz \coreos.inst.ignition_url=http://192.168.1.1:8080/okd/worker.ign \ip=192.168.1.21::192.168.1.1:255.255.255.0:worker-0.okd.example.com:ens192:none \nameserver=192.168.1.1
# Alternative: Use PXE boot# See: https://docs.okd.io/latest/installing/installing_bare_metal/installing-bare-metal.htmlMonitor Installation
# Wait for bootstrap to complete (30-45 minutes)openshift-install wait-for bootstrap-complete \ --dir ~/okd-install \ --log-level=info
# Output: "INFO It is now safe to remove the bootstrap resources"
# Remove bootstrap from load balancer# Shutdown bootstrap node
# Set kubeconfigexport KUBECONFIG=~/okd-install/auth/kubeconfig
# Approve worker CSRswatch -n5 oc get csroc get csr -o name | xargs oc adm certificate approve
# Wait for installation complete (10-15 minutes)openshift-install wait-for install-complete \ --dir ~/okd-install \ --log-level=info
# Output shows console URL and kubeadmin credentialsFirst Login
# Login via CLIoc login -u kubeadmin -p <password-from-install>
# Get console URLoc whoami --show-console
# Access web console# https://console-openshift-console.apps.okd.example.com# Username: kubeadmin# Password: <from ~/okd-install/auth/kubeadmin-password>Post-Installation Configuration
Configure OAuth (Identity Provider)
# HTPasswd providerapiVersion: v1kind: Secretmetadata: name: htpass-secret namespace: openshift-configtype: Opaquedata: htpasswd: <base64-encoded-htpasswd-file>---apiVersion: config.openshift.io/v1kind: OAuthmetadata: name: clusterspec: identityProviders: - name: my_htpasswd_provider mappingMethod: claim type: HTPasswd htpasswd: fileData: name: htpass-secret# Create htpasswd filehtpasswd -c -B -b users.htpasswd admin admin123htpasswd -b users.htpasswd developer dev123
# Create secretoc create secret generic htpass-secret \ --from-file=htpasswd=users.htpasswd \ -n openshift-config
# Apply OAuth configoc apply -f oauth.yaml
# Grant cluster-admin to useroc adm policy add-cluster-role-to-user cluster-admin admin
# Remove kubeadminoc delete secrets kubeadmin -n kube-systemConfigure Image Registry
# For production with persistent storageoc patch configs.imageregistry.operator.openshift.io cluster \ --type merge \ --patch '{"spec":{"managementState":"Managed","storage":{"pvc":{"claim":""}}}}'
# For testing (emptyDir - not persistent)oc patch configs.imageregistry.operator.openshift.io cluster \ --type merge \ --patch '{"spec":{"managementState":"Managed","storage":{"emptyDir":{}}}}'
# Verifyoc get clusteroperator image-registrySetup Persistent Storage
# Example: NFS StorageClassapiVersion: storage.k8s.io/v1kind: StorageClassmetadata: name: nfs-storageprovisioner: nfs.csi.k8s.ioparameters: server: nfs-server.example.com share: /export/okd-storagereclaimPolicy: DeletevolumeBindingMode: ImmediateDeveloper Workflows
Source-to-Image (S2I)
# Create new app from Gitoc new-project my-appoc new-app nodejs:18~https://github.com/sclorg/nodejs-ex
# Expose routeoc expose svc/nodejs-ex
# Get routeoc get route nodejs-ex
# Trigger rebuildoc start-build nodejs-ex
# Follow build logsoc logs -f bc/nodejs-exOpenShift Pipelines (Tekton)
# Install Pipelines Operatorcat <<EOF | oc apply -f -apiVersion: operators.coreos.com/v1alpha1kind: Subscriptionmetadata: name: openshift-pipelines-operator namespace: openshift-operatorsspec: channel: latest name: openshift-pipelines-operator-rh source: community-operators sourceNamespace: openshift-marketplaceEOF
# Create pipelinecat <<EOF | oc apply -f -apiVersion: tekton.dev/v1beta1kind: Pipelinemetadata: name: build-and-deployspec: params: - name: git-url type: string - name: git-revision type: string default: main
workspaces: - name: shared-workspace
tasks: - name: fetch-repository taskRef: name: git-clone kind: ClusterTask workspaces: - name: output workspace: shared-workspace params: - name: url value: $(params.git-url) - name: revision value: $(params.git-revision)
- name: build-image taskRef: name: buildah kind: ClusterTask runAfter: - fetch-repository workspaces: - name: source workspace: shared-workspace params: - name: IMAGE value: image-registry.openshift-image-registry.svc:5000/my-app/app:latestEOFOperators
Install Operator via OperatorHub
apiVersion: operators.coreos.com/v1alpha1kind: Subscriptionmetadata: name: mongodb-enterprise namespace: openshift-operatorsspec: channel: stable name: mongodb-enterprise source: community-operators sourceNamespace: openshift-marketplace installPlanApproval: AutomaticCustom Operator
# Install Operator SDKexport ARCH=$(case $(arch) in x86_64) echo -n amd64 ;; aarch64) echo -n arm64 ;; *) echo -n $(arch) ;; esac)export OS=$(uname | awk '{print tolower($0)}')export OPERATOR_SDK_DL_URL=https://github.com/operator-framework/operator-sdk/releases/download/v1.33.0curl -LO ${OPERATOR_SDK_DL_URL}/operator-sdk_${OS}_${ARCH}chmod +x operator-sdk_${OS}_${ARCH}sudo mv operator-sdk_${OS}_${ARCH} /usr/local/bin/operator-sdk
# Create new operatormkdir my-operator && cd my-operatoroperator-sdk init --domain=example.com --repo=github.com/example/my-operatoroperator-sdk create api --group=app --version=v1 --kind=MyApp --resource --controllerMonitoring and Observability
Access Prometheus
# Port-forward to Prometheusoc port-forward -n openshift-monitoring \ svc/prometheus-k8s 9090:9090
# Access at http://localhost:9090Custom Metrics
apiVersion: monitoring.coreos.com/v1kind: ServiceMonitormetadata: name: myapp-metrics namespace: my-appspec: selector: matchLabels: app: myapp endpoints: - port: metrics interval: 30sUpgrades
Check Available Upgrades
# Check current versionoc get clusterversion
# View available upgradesoc adm upgrade
# Upgrade to specific versionoc adm upgrade --to=4.15.0-0.okd-2024-03-10-010116
# Monitor upgradewatch oc get clusterversionoc get clusteroperatorsBest Practices
Production Deployment
- Infrastructure Nodes: Dedicated nodes for router, registry, monitoring
- Storage: Persistent storage for registry and monitoring
- Monitoring: Configure alerting and log aggregation
- Backup: Regular etcd backups
- Updates: Test upgrades in non-production first
Security
- Remove kubeadmin: After creating admin users
- Network Policies: Restrict pod-to-pod communication
- SCCs: Use restrictive SCCs by default
- Secrets: External secrets management (Vault)
- RBAC: Least privilege access
Performance
- Worker Sizing: Right-size based on workload
- Storage: Fast storage for etcd
- Network: 10 Gbps recommended
- Monitoring: Resource limits on monitoring stack
Troubleshooting
# Check cluster operatorsoc get co
# Check node statusoc get nodesoc describe node <node-name>
# Check pod logsoc logs -n <namespace> <pod-name>
# Debug nodeoc debug node/<node-name>
# Collect must-gatheroc adm must-gather
# Check eventsoc get events --sort-by='.lastTimestamp'Conclusion
OKD provides enterprise Kubernetes capabilities without licensing costs, making it ideal for development, testing, and cost-sensitive production deployments. While lacking Red Hat’s commercial support, OKD’s active community and rapid innovation make it a compelling choice for teams seeking OpenShift features with open-source flexibility.
Master OKD and Kubernetes with our training programs. Contact us for customized cloud-native training.