Cloud Native 34 min read

Step‑by‑Step Offline Installation of an OpenShift Container Platform Cluster

This guide walks through the complete offline installation of OpenShift Container Platform, covering preparation of offline resources, server planning, firewall and DNS configuration, load‑balancer setup with Envoy, creation of ignition files, bootstrap, master and worker node provisioning, CSR approval, operator validation, and final cluster verification.

Programmer DD
Programmer DD
Programmer DD
Step‑by‑Step Offline Installation of an OpenShift Container Platform Cluster

1. Installation Process

During OCP installation a bootstrap host is required to start a temporary control plane, generate ignition files and deploy the cluster. The bootstrap host creates master nodes, builds the Etcd cluster, launches a temporary Kubernetes control plane and then hands over control to the production control plane.

Bootstrap host starts and provides resources for Master nodes.

Master nodes retrieve resources from bootstrap and become operational.

Master nodes build the Etcd cluster.

Bootstrap host launches a temporary Kubernetes control plane.

Temporary control plane transfers control to the production control plane.

Bootstrap host injects OCP components and shuts down.

2. Preparing Server Resources

Plan the following servers:

Three control‑plane nodes running Etcd, control‑plane components and Infras.

Two compute nodes for workloads.

One bootstrap host for installation tasks (removed after cluster deployment).

One base node to host offline resources, DNS and load balancer.

One image node for a private Quay registry.

3. Firewall Configuration

Open the required ports between all nodes and configure two layer‑4 load balancers for the API (port 6443) and Ingress (ports 80/443).

TCP 2379‑2380 – Etcd service.

TCP 6443 – Kubernetes API.

4. DNS Configuration

According to the official documentation, a UPI‑based OCP cluster requires DNS records that use <cluster_name>.<base_domain>. The CoreDNS service with the etcd plugin is recommended to serve wildcard and SRV records.

# yum install -y etcd
systemctl enable etcd --now
# wget https://github.com/coredns/coredns/releases/download/v1.6.9/coredns_1.6.9_linux_amd64.tgz
 tar zxvf coredns_1.6.9_linux_amd64.tgz
 mv coredns /usr/local/bin
cat > /etc/systemd/system/coredns.service <<EOF
[Unit]
Description=CoreDNS DNS server
After=network.target
[Service]
PermissionsStartOnly=true
LimitNOFILE=1048576
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
NoNewPrivileges=true
User=coredns
WorkingDirectory=~
ExecStart=/usr/local/bin/coredns -conf=/etc/coredns/Corefile
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
# useradd coredns -s /sbin/nologin
cat > /etc/coredns/Corefile <<EOF
.:53 {
  template IN A apps.openshift4.example.com {
    match .*apps\.openshift4\.example\.com
    answer "{{ .Name }} 60 IN A 192.168.57.60"
    fallthrough
  }
  etcd {
    path /skydns
    endpoint http://localhost:2379
    fallthrough
  }
  prometheus
  cache 160
  loadbalance
  forward . 192.168.57.1
  log
}
EOF
# systemctl enable coredns --now

5. Load Balancer Configuration

Envoy is used as the load balancer. Create the following configuration files.

# /etc/envoy/envoy.yaml
node:
  id: node0
  cluster: cluster0
dynamic_resources:
  lds_config:
    path: /etc/envoy/lds.yaml
  cds_config:
    path: /etc/envoy/cds.yaml
admin:
  access_log_path: "/dev/stdout"
  address:
    socket_address:
      address: "0.0.0.0"
      port_value: 15001
# /etc/envoy/lds.yaml
version_info: "0"
resources:
- "@type": type.googleapis.com/envoy.config.listener.v3.Listener
  name: listener_openshift-api-server
  address:
    socket_address:
      address: 0.0.0.0
      port_value: 6443
  filter_chains:
  - filters:
    - name: envoy.tcp_proxy
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
        stat_prefix: openshift-api-server
        cluster: openshift-api-server
        access_log:
          name: envoy.access_loggers.file
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
            path: /dev/stdout
# /etc/envoy/cds.yaml
version_info: "0"
resources:
- "@type": type.googleapis.com/envoy.config.cluster.v3.Cluster
  name: openshift-api-server
  connect_timeout: 1s
  type: strict_dns
  dns_lookup_family: V4_ONLY
  lb_policy: ROUND_ROBIN
  load_assignment:
    cluster_name: openshift-api-server
    endpoints:
    - lb_endpoints:
      - endpoint:
          address:
            socket_address:
              address: 192.168.57.61
              port_value: 6443
      - endpoint:
          address:
            socket_address:
              address: 192.168.57.62
              port_value: 6443
      - endpoint:
          address:
            socket_address:
              address: 192.168.57.63
              port_value: 6443
      - endpoint:
          address:
            socket_address:
              address: 192.168.57.64
              port_value: 6443

Start Envoy in a container:

# podman run -d --restart=always --name envoy --net host -v /etc/envoy:/etc/envoy envoyproxy/envoy

6. Installation Preparation

Generate SSH Key and Add to ssh‑agent

# ssh-keygen -t rsa -b 4096 -N '' -f ~/.ssh/new_rsa
# eval "$(ssh-agent -s)"
# ssh-add ~/.ssh/new_rsa

Create Installation Directory

# mkdir /ocpinstall

Create install-config.yaml

apiVersion: v1
baseDomain: example.com
compute:
- hyperthreading: Enabled
  name: worker
  replicas: 0
controlPlane:
  hyperthreading: Enabled
  name: master
  replicas: 3
metadata:
  name: openshift4
networking:
  clusterNetwork:
  - cidr: 10.128.0.0/14
    hostPrefix: 23
  networkType: OpenShiftSDN
  serviceNetwork:
  - 172.30.0.0/16
platform:
  none: {}
fips: false
pullSecret: '{"auths": ...}'
sshKey: 'ssh-rsa ...'
additionalTrustBundle: |
  -----BEGIN CERTIFICATE-----
  ...
  -----END CERTIFICATE-----
imageContentSources:
- mirrors:
  - registry.openshift4.example.com/ocp4/openshift4
  source: quay.io/openshift-release-dev/ocp-release
- mirrors:
  - registry.openshift4.example.com/ocp4/openshift4
  source: quay.io/openshift-release-dev/ocp-v4.0-art-dev

Create Ignition Files

# cp install-config.yaml.20200604 install-config.yaml
# openshift-install create ignition-configs --dir=/ocpinstall

The command generates bootstrap.ign, master.ign, worker.ign and authentication files.

7. Install the Cluster

Bootstrap Node

Create a VM, mount the RHCOS ISO and set the following kernel parameters in the installer:

ip=192.168.57.61::192.168.57.1:255.255.255.0:bootstrap.openshift4.example.com:ens192:none nameserver=192.168.57.60 coreos.inst.install_dev=sda coreos.inst.image_url=http://192.168.57.60:8080/install/rhcos-4.4.3-x86_64-metal.x86_64.raw.gz coreos.inst.ignition_url=http://192.168.57.60:8080/ignition/bootstrap.ign

Master Nodes

Repeat the VM creation for each master, adjusting the IP and hostname:

ip=192.168.57.62::192.168.57.1:255.255.255.0:master1.openshift4.example.com:ens192:none nameserver=192.168.57.60 coreos.inst.install_dev=sda coreos.inst.image_url=http://192.168.57.60:8080/install/rhcos-4.4.3-x86_64-metal.x86_64.raw.gz coreos.inst.ignition_url=http://192.168.57.60:8080/ignition/master.ign

Worker Nodes

Similarly create worker VMs:

ip=192.168.57.65::192.168.57.1:255.255.255.0:worker1.openshift4.example.com:ens192:none nameserver=192.168.57.60 coreos.inst.install_dev=sda coreos.inst.image_url=http://192.168.57.60:8080/install/rhcos-4.4.3-x86_64-metal.x86_64.raw.gz coreos.inst.ignition_url=http://192.168.57.60:8080/ignition/worker.ign

Monitor Bootstrap Completion

# openshift-install --dir=/ocpinstall wait-for bootstrap-complete --log-level=debug

After the bootstrap phase finishes, remove the bootstrap host from the Envoy cds.yaml endpoints and reload Envoy.

Approve Certificate Signing Requests

# oc get csr -o json | jq -r '.items[] | select(.status == {}) | .metadata.name' | xargs oc adm certificate approve

Verify Operators

# oc get clusteroperators

All operators should show AVAILABLE=True. If any are not ready, investigate their logs.

Complete Installation

# openshift-install --dir=/ocpinstall wait-for install-complete --log-level=debug

When the installer reports that the Web Console is reachable, retrieve the admin password from /ocpinstall/auth/kubeadmin-password and log in.

8. References

OpenShift 4.2 vSphere Install with Static IPs

OpenShift Container Platform 4.3 Deployment Record

Chapter 1. Installing on Bare Metal

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

ClusterOpenShiftoffline installation
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.