$ oc get infrastructure cluster -o jsonpath='{.spec.platformSpec.vsphere.machineNetworks}{"\n"}'
You can expand an existing OKD cluster on VMware vSphere by adding bare-metal compute machines or virtual machines (VMs) without vSphere integration.
This workflow applies to compute machines added after cluster installation, regardless of the original installation method. The existing cluster retains its vSphere platform configuration and control plane.
Provision physical or virtual compute machines manually and install Fedora CoreOS (FCOS) with your OKD cluster’s worker configuration. These nodes join the cluster without vSphere integration.
The target cluster is the existing OKD cluster on vSphere that the new compute machines join. Run the OpenShift CLI (oc) commands in this workflow against the target cluster.
For a virtual machine (VM), use a virtualization environment other than vSphere, such as OKD Virtualization. That environment supplies the processor, memory, virtual disks, and network interfaces. Create the VM in that environment, and then install FCOS inside the VM by using the ISO procedure. The VM needs network access to the target cluster and its worker Ignition configuration.
For VMs hosted on vSphere, use the procedures for adding vSphere compute machines.
The ISO procedure uses coreos-installer install with --platform=metal for both physical machines and VMs. The metal value selects the Ignition platform for the new worker; the target cluster retains its vSphere platform configuration.
You must provision and replace the added machines manually. The Machine API, compute machine sets, and cluster autoscaler do not provision or replace these machines. The Machine Config Operator (MCO) manages node configuration and operating system updates through machine config pools (MCPs).
If the added workers require configuration changes that differ from the existing workers, use a custom MCP to target those changes. The custom pool must inherit the worker configuration.
The requirement to disable the native vSphere Container Storage Interface (CSI) driver applies to workload storage in the target cluster. Storage for a VM’s virtual disks is configured in its virtualization environment.
Before you add bare-metal compute machines or virtual machines (VMs) without vSphere integration to your OKD cluster, prepare the machines, network, and storage.
You have an existing OKD cluster installed on vSphere.
The new physical machines or VMs meet the minimum resource requirements for compute machines, including processor capacity, memory, disk capacity, and disk performance.
You have console access to each machine and a persistent disk on which to install Fedora CoreOS (FCOS).
For VMs, you have created the VMs and configured their virtual disks and network interfaces. You can attach an ISO image and control the boot order.
You have configured persistent IP addresses and hostnames for the new machines by using Dynamic Host Configuration Protocol (DHCP) or static configuration. You have also configured forward and reverse DNS resolution.
The new machines and existing cluster nodes can communicate in both directions by using their node IP addresses. For VMs, these are the guest IP addresses. The new machines can also access the API, Machine Config Server, and required image registries.
For clusters that use virtual IP addresses (VIPs), the VIPs remain reachable if served from an added node. The network must deliver incoming traffic for a VIP to that node, including when the node is on another subnet.
You have migrated all workloads that depend on vSphere volumes to an alternative storage solution. This includes any platform workloads that use those volumes.
After migrating the workloads, you have disabled the native vSphere Container Storage Interface (CSI) driver by setting spec.managementState to Removed in the csi.vsphere.vmware.com ClusterCSIDriver object.
|
Disabling the native vSphere CSI driver affects every node in the target cluster, including the existing vSphere nodes. These nodes lose the ability to provision or attach vSphere volumes. The CSI Operator removes all vSphere storage classes, including Removing the driver does not delete existing persistent volumes (PVs) or persistent volume claims (PVCs), but new pods cannot use them after you remove the driver. Migrate workloads that depend on these volumes to an alternative storage solution before you disable the driver. |
If new compute machines use an additional subnet, add it to the machine networks in your OKD cluster’s infrastructure configuration before the machines join.
Apply this procedure to both bare-metal machines and virtual machines (VMs) without vSphere integration. If their subnet is already listed, continue to the ISO installation procedure.
Adding the subnet to the cluster configuration does not configure external routing or establish virtual IP address (VIP) reachability. Configure that connectivity before adding the machines.
You have installed the OpenShift CLI (oc).
You are logged in to the target cluster as a user with the cluster-admin role.
You know the subnets in Classless Inter-Domain Routing (CIDR) notation that your network administrator assigned to the existing machines and the new machines.
Display the configured machine networks by running the following command:
$ oc get infrastructure cluster -o jsonpath='{.spec.platformSpec.vsphere.machineNetworks}{"\n"}'
Edit the Infrastructure object named cluster by running the following command:
$ oc edit infrastructure cluster
In spec.platformSpec.vsphere.machineNetworks, retain the existing entries and append the new subnet. If machineNetworks is absent, add the list with the existing and new machine subnets.
The following excerpt shows the location of the list:
spec:
platformSpec:
type: VSphere
vsphere:
machineNetworks:
- <existing_machine_network_cidr>
- <new_machine_network_cidr>
where:
<existing_machine_network_cidr>Specifies an existing machine subnet. Retain all existing entries.
<new_machine_network_cidr>Specifies the subnet for the new machines, for example, 192.0.2.0/24. Add each new subnet only once.
Save your changes and exit the editor.
Verify that the list contains the existing networks and each new subnet by running the following command:
$ oc get infrastructure cluster -o jsonpath='{.spec.platformSpec.vsphere.machineNetworks}{"\n"}'
Install Fedora CoreOS (FCOS) on physical machines or virtual machines (VMs) by using an ISO image and the worker Ignition configuration from your OKD cluster on vSphere. The machines join as workers without vSphere integration.
You have prepared the machines, network, and storage for adding compute machines without vSphere integration.
You have added any new machine subnets to the target cluster’s infrastructure configuration.
You have a Hypertext Transfer Protocol (HTTP) server that the new machines can access to download the Ignition configuration.
You have installed the OpenShift CLI (oc) and jq on your workstation.
You are logged in to the target cluster as a user with the cluster-admin role.
From your workstation, obtain the ISO download URL from the target cluster by running the following command:
$ oc -n openshift-machine-config-operator get configmap/coreos-bootimages -o jsonpath='{.data.stream}' | jq -r '.architectures["<architecture>"].artifacts.metal.formats.iso.disk.location'
Replace <architecture> with the processor architecture of the new machines, for example, x86_64. The architecture must be supported by the target cluster.
Download the ISO image from the returned URL.
Extract the worker Ignition configuration from the target cluster by running the following command:
$ oc extract -n openshift-machine-api secret/worker-user-data-managed --keys=userData --to=- > worker.ign
Upload the worker.ign file to your HTTP server. Record its URL.
Boot the new machine from the ISO image:
For a physical machine, use local installation media or remote ISO redirection.
For a VM, attach the ISO image to the VM’s virtual optical drive and configure the VM to boot from it.
From the live installation console, configure networking if Dynamic Host Configuration Protocol (DHCP) does not provide the required settings. You can use nmcli or nmtui to configure a static address or other network settings.
From the live installation console, verify that the machine can retrieve its Ignition configuration by running the following command:
$ curl --fail http://<http_server>/worker.ign
Replace <http_server> with the address of your HTTP server. Include the path to worker.ign if you placed it in a subdirectory. The command must return the Ignition configuration.
Identify the destination disk by running the following command:
$ lsblk
Install FCOS on that disk by running the following command:
If you configured networking in the live environment, add --copy-network to the command to copy the connection profiles in /etc/NetworkManager/system-connections to the installed system. This option does not copy the system hostname. Use the documented hostname configuration for your network.
$ sudo coreos-installer install <installation_disk> \
--ignition-url=http://<http_server>/worker.ign \
--insecure-ignition \
--platform=metal
where:
<installation_disk>Specifies the disk on which to install FCOS, for example, /dev/sda on a physical machine or /dev/vda on a VM. Installation overwrites the contents of this disk.
<http_server>Specifies the HTTP server and any directory path used in the Ignition URL.
After installation completes, remove or detach the ISO media, or change the boot order so that the machine boots from the installed disk. Reboot the machine by running the following command:
$ sudo reboot
Monitor the console as the machine boots from disk. It attempts to join the target cluster and generates certificate signing requests (CSRs).
From your workstation, verify that the new machine has generated CSRs in the target cluster by running the following command:
$ oc get csr
Continue by reviewing and approving the CSRs for the machines that you added.
To allow newly added machines to join your OKD cluster, confirm that the cluster approves pending certificate signing requests (CSRs), or approve them yourself. Approve client requests first, then server requests.
You added machines to your cluster.
Confirm that the cluster recognizes the machines:
$ oc get nodes
NAME STATUS ROLES AGE VERSION
master-0 Ready master 63m v1.36.3
master-1 Ready master 63m v1.36.3
master-2 Ready master 64m v1.36.3
The output lists all of the machines that you created.
|
The preceding output might not include the compute nodes until some CSRs are approved. |
Review the pending CSRs and ensure that you see the client requests with the Pending or Approved status for each machine that you added to the cluster:
$ oc get csr
NAME AGE REQUESTOR CONDITION
csr-8b2br 15m system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Pending
csr-8vnps 15m system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Pending
...
In this example, two machines are joining the cluster. You might see more approved CSRs in the list.
If the CSRs were not approved, after all of the pending CSRs for the machines you added are in Pending status, approve the CSRs for your cluster machines:
|
You must approve your CSRs within an hour of adding the machines to the cluster. If you do not approve them within an hour, the certificates rotate, and more than two certificates are present for each node. You must approve all of these certificates. After you approve the client CSR, the kubelet creates a secondary CSR for the serving certificate, which requires manual approval. The |
|
For clusters running on platforms that are not machine API enabled, such as bare metal and other user-provisioned infrastructure, you must implement a method of automatically approving the kubelet serving certificate requests (CSRs). If you do not approve a request, the |
To approve them individually, run the following command for each valid CSR:
$ oc adm certificate approve <csr_name>
where:
<csr_name>Specifies the name of a CSR from the list of current CSRs.
To approve all pending CSRs, run the following command:
$ oc get csr -o go-template='{{range .items}}{{if not .status}}{{.metadata.name}}{{"\n"}}{{end}}{{end}}' | xargs --no-run-if-empty oc adm certificate approve
|
Some Operators might not become available until some CSRs are approved. Each node submits two CSRs, so you might need to run the command to approve CSRs multiple times. |
After you approve your client requests, review the server requests for each machine that you added to the cluster:
$ oc get csr
NAME AGE REQUESTOR CONDITION
csr-bfd72 5m26s system:node:ip-10-0-50-126.us-east-2.compute.internal Pending
csr-c57lv 5m26s system:node:ip-10-0-95-157.us-east-2.compute.internal Pending
...
If the remaining CSRs are not approved, and are in the Pending status, approve the CSRs for your cluster machines:
To approve them individually, run the following command for each valid CSR:
$ oc adm certificate approve <csr_name>
where:
<csr_name>Specifies the name of a CSR from the list of current CSRs.
To approve all pending CSRs, run the following command:
$ oc get csr -o go-template='{{range .items}}{{if not .status}}{{.metadata.name}}{{"\n"}}{{end}}{{end}}' | xargs oc adm certificate approve
After you approve all client and server CSRs, the machines have the Ready status. Verify this by running the following command:
$ oc get nodes
NAME STATUS ROLES AGE VERSION
master-0 Ready master 73m v1.36.3
master-1 Ready master 73m v1.36.3
master-2 Ready master 74m v1.36.3
worker-0 Ready worker 11m v1.36.3
worker-1 Ready worker 11m v1.36.3
|
You might need to wait a few minutes after approval of the server CSRs for the machines to reach the |
To schedule workloads on bare-metal compute nodes or virtual machines (VMs) without vSphere integration, remove the node.cloudprovider.kubernetes.io/uninitialized taint after the nodes join your OKD cluster.
The vSphere Cloud Controller Manager (CCM) attempts to initialize each node by searching vCenter for a matching virtual machine. For nodes without vSphere integration, the CCM cannot find a match and cannot remove the taint automatically. A node can have the Ready status and still have this taint, which prevents workload scheduling.
|
The CCM logs error messages similar to |
The compute nodes have joined the target cluster and their certificate signing requests (CSRs) have been approved.
You have installed the OpenShift CLI (oc).
You are logged in to the target cluster as a user with the cluster-admin role.
Remove the node.cloudprovider.kubernetes.io/uninitialized taint from each compute node that you added without vSphere integration by running the following command:
$ oc adm taint nodes <node_name> node.cloudprovider.kubernetes.io/uninitialized:NoSchedule-
Replace <node_name> with the name of the compute node as shown in the output of oc get nodes.
Verify that the compute node has the Ready status and does not show SchedulingDisabled by running the following command:
$ oc get node <node_name>
Replace <node_name> with the name of the compute node as shown in the output of oc get nodes.
Verify that node.cloudprovider.kubernetes.io/uninitialized does not appear in the node’s taints by running the following command:
$ oc get node <node_name> -o jsonpath='{.spec.taints}{"\n"}'
Verify that the machine config pool (MCP) containing the added node has Updated=True, Updating=False, and Degraded=False by running the following command:
$ oc get machineconfigpools
Obtain the value of the added node’s kubernetes.io/hostname label for a test pod by running the following command:
$ oc get node <node_name> -o jsonpath='{.metadata.labels.kubernetes\.io/hostname}{"\n"}'
Create a file named compute-node-test.yaml with the following content. Use an existing test project whose node selector permits scheduling on the added node.
apiVersion: v1
kind: Pod
metadata:
name: compute-node-test
namespace: <test_namespace>
spec:
nodeSelector:
kubernetes.io/hostname: <node_hostname>
restartPolicy: Never
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: test
image: <test_image>
command: ["/bin/sh", "-c", "sleep 3600"]
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
where:
<test_namespace>Specifies the existing test project.
<node_hostname>Specifies the hostname label value returned by the preceding command.
<test_image>Specifies a container image that supports the node’s architecture, runs as a non-root user, and contains /bin/sh and sleep. For example, use registry.access.redhat.com/ubi9/ubi-minimal:latest or a mirrored copy accessible to the cluster.
Create the test pod by running the following command:
$ oc apply -f compute-node-test.yaml
Verify that the test pod has STATUS set to Running, READY set to 1/1, and NODE set to the added node by running the following command:
$ oc get pod compute-node-test -n <test_namespace> -o wide
This command also displays the pod if it has not been assigned to a node. If the pod remains pending or fails to become ready, examine its status and events by running the following command:
$ oc describe pod compute-node-test -n <test_namespace>
Resolve any reported scheduling or image-pull errors before continuing. This test verifies pod scheduling and startup on the node.
Delete the test pod by running the following command:
$ oc delete pod compute-node-test -n <test_namespace>
Repeat the node and workload checks for each added node.
After the cluster finishes reconciling the new nodes, verify that the cluster Operators have Available=True, Progressing=False, and Degraded=False by running the following command:
$ oc get clusteroperators