Chapter 4. Postinstallation cluster tasks
After installing OpenShift Container Platform, you can further expand and customize your cluster to your requirements.
4.1. Available cluster customizations Copy linkLink copied to clipboard!
You complete most of the cluster configuration and customization after you deploy your OpenShift Container Platform cluster. A number of configuration resources are available.
If you install your cluster on IBM Z®, not all features and functions are available.
You modify the configuration resources to configure the major features of the cluster, such as the image registry, networking configuration, image build behavior, and the identity provider.
For current documentation of the settings that you control by using these resources, use the oc explain
command, for example oc explain builds --api-version=config.openshift.io/v1
4.1.1. Cluster configuration resources Copy linkLink copied to clipboard!
All cluster configuration resources are globally scoped (not namespaced) and named cluster
.
Resource name | Description |
---|---|
| Provides API server configuration such as certificates and certificate authorities. |
| Controls the identity provider and authentication configuration for the cluster. |
| Controls default and enforced configuration for all builds on the cluster. |
| Configures the behavior of the web console interface, including the logout behavior. |
| Enables FeatureGates so that you can use Tech Preview features. |
| Configures how specific image registries should be treated (allowed, disallowed, insecure, CA details). |
| Configuration details related to routing such as the default domain for routes. |
| Configures identity providers and other behavior related to internal OAuth server flows. |
| Configures how projects are created including the project template. |
| Defines proxies to be used by components needing external network access. Note: not all components currently consume this value. |
| Configures scheduler behavior such as profiles and default node selectors. |
4.1.2. Operator configuration resources Copy linkLink copied to clipboard!
These configuration resources are cluster-scoped instances, named cluster
, which control the behavior of a specific component as owned by a particular Operator.
Resource name | Description |
---|---|
| Controls console appearance such as branding customizations |
| Configures OpenShift image registry settings such as public routing, log levels, proxy settings, resource constraints, replica counts, and storage type. |
| Configures the Samples Operator to control which example image streams and templates are installed on the cluster. |
4.1.3. Additional configuration resources Copy linkLink copied to clipboard!
These configuration resources represent a single instance of a particular component. In some cases, you can request multiple instances by creating multiple instances of the resource. In other cases, the Operator can use only a specific resource instance name in a specific namespace. Reference the component-specific documentation for details on how and when you can create additional resource instances.
Resource name | Instance name | Namespace | Description |
---|---|---|---|
|
|
| Controls the Alertmanager deployment parameters. |
|
|
| Configures Ingress Operator behavior such as domain, number of replicas, certificates, and controller placement. |
4.1.4. Informational Resources Copy linkLink copied to clipboard!
You use these resources to retrieve information about the cluster. Some configurations might require you to edit these resources directly.
Resource name | Instance name | Description |
---|---|---|
|
|
In OpenShift Container Platform 4.17, you must not customize the |
|
| You cannot modify the DNS settings for your cluster. You can check the DNS Operator status. |
|
| Configuration details allowing the cluster to interact with its cloud provider. |
|
| You cannot modify your cluster networking after installation. To customize your network, follow the process to customize networking during installation. |
4.2. Adding worker nodes Copy linkLink copied to clipboard!
After you deploy your OpenShift Container Platform cluster, you can add worker nodes to scale cluster resources. There are different ways you can add worker nodes depending on the installation method and the environment of your cluster.
4.2.1. Adding worker nodes to an on-premise cluster Copy linkLink copied to clipboard!
For on-premise clusters, you can add worker nodes by using the OpenShift Container Platform CLI (oc
) to generate an ISO image, which can then be used to boot one or more nodes in your target cluster. This process can be used regardless of how you installed your cluster.
You can add one or more nodes at a time while customizing each node with more complex configurations, such as static network configuration, or you can specify only the MAC address of each node. Any configurations that are not specified during ISO generation are retrieved from the target cluster and applied to the new nodes.
Preflight validation checks are also performed when booting the ISO image to inform you of failure-causing issues before you attempt to boot each node.
4.2.2. Adding worker nodes to installer-provisioned infrastructure clusters Copy linkLink copied to clipboard!
For installer-provisioned infrastructure clusters, you can manually or automatically scale the MachineSet
object to match the number of available bare-metal hosts.
To add a bare-metal host, you must configure all network prerequisites, configure an associated baremetalhost
object, then provision the worker node to the cluster. You can add a bare-metal host manually or by using the web console.
4.2.3. Adding worker nodes to user-provisioned infrastructure clusters Copy linkLink copied to clipboard!
For user-provisioned infrastructure clusters, you can add worker nodes by using a RHEL or RHCOS ISO image and connecting it to your cluster using cluster Ignition config files. For RHEL worker nodes, the following example uses Ansible playbooks to add worker nodes to the cluster. For RHCOS worker nodes, the following example uses an ISO image and network booting to add worker nodes to the cluster.
4.2.4. Adding worker nodes to clusters managed by the Assisted Installer Copy linkLink copied to clipboard!
For clusters managed by the Assisted Installer, you can add worker nodes by using the Red Hat OpenShift Cluster Manager console, the Assisted Installer REST API or you can manually add worker nodes using an ISO image and cluster Ignition config files.
4.2.5. Adding worker nodes to clusters managed by the multicluster engine for Kubernetes Copy linkLink copied to clipboard!
For clusters managed by the multicluster engine for Kubernetes, you can add worker nodes by using the dedicated multicluster engine console.
4.3. Adjust worker nodes Copy linkLink copied to clipboard!
If you incorrectly sized the worker nodes during deployment, adjust them by creating one or more new compute machine sets, scale them up, then scale the original compute machine set down before removing them.
4.3.1. Understanding the difference between compute machine sets and the machine config pool Copy linkLink copied to clipboard!
MachineSet
objects describe OpenShift Container Platform nodes with respect to the cloud or machine provider.
The MachineConfigPool
object allows MachineConfigController
components to define and provide the status of machines in the context of upgrades.
The MachineConfigPool
object allows users to configure how upgrades are rolled out to the OpenShift Container Platform nodes in the machine config pool.
The NodeSelector
object can be replaced with a reference to the MachineSet
object.
4.3.2. Scaling a compute machine set manually Copy linkLink copied to clipboard!
To add or remove an instance of a machine in a compute machine set, you can manually scale the compute machine set.
This guidance is relevant to fully automated, installer-provisioned infrastructure installations. Customized, user-provisioned infrastructure installations do not have compute machine sets.
Prerequisites
-
Install an OpenShift Container Platform cluster and the
oc
command line. -
Log in to
oc
as a user withcluster-admin
permission.
Procedure
View the compute machine sets that are in the cluster by running the following command:
oc get machinesets.machine.openshift.io -n openshift-machine-api
$ oc get machinesets.machine.openshift.io -n openshift-machine-api
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The compute machine sets are listed in the form of
<clusterid>-worker-<aws-region-az>
.View the compute machines that are in the cluster by running the following command:
oc get machines.machine.openshift.io -n openshift-machine-api
$ oc get machines.machine.openshift.io -n openshift-machine-api
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Set the annotation on the compute machine that you want to delete by running the following command:
oc annotate machines.machine.openshift.io/<machine_name> -n openshift-machine-api machine.openshift.io/delete-machine="true"
$ oc annotate machines.machine.openshift.io/<machine_name> -n openshift-machine-api machine.openshift.io/delete-machine="true"
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Scale the compute machine set by running one of the following commands:
oc scale --replicas=2 machinesets.machine.openshift.io <machineset> -n openshift-machine-api
$ oc scale --replicas=2 machinesets.machine.openshift.io <machineset> -n openshift-machine-api
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Or:
oc edit machinesets.machine.openshift.io <machineset> -n openshift-machine-api
$ oc edit machinesets.machine.openshift.io <machineset> -n openshift-machine-api
Copy to Clipboard Copied! Toggle word wrap Toggle overflow TipYou can alternatively apply the following YAML to scale the compute machine set:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow You can scale the compute machine set up or down. It takes several minutes for the new machines to be available.
ImportantBy default, the machine controller tries to drain the node that is backed by the machine until it succeeds. In some situations, such as with a misconfigured pod disruption budget, the drain operation might not be able to succeed. If the drain operation fails, the machine controller cannot proceed removing the machine.
You can skip draining the node by annotating
machine.openshift.io/exclude-node-draining
in a specific machine.
Verification
Verify the deletion of the intended machine by running the following command:
oc get machines.machine.openshift.io
$ oc get machines.machine.openshift.io
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
4.3.3. The compute machine set deletion policy Copy linkLink copied to clipboard!
Random
, Newest
, and Oldest
are the three supported deletion options. The default is Random
, meaning that random machines are chosen and deleted when scaling compute machine sets down. The deletion policy can be set according to the use case by modifying the particular compute machine set:
spec: deletePolicy: <delete_policy> replicas: <desired_replica_count>
spec:
deletePolicy: <delete_policy>
replicas: <desired_replica_count>
Specific machines can also be prioritized for deletion by adding the annotation machine.openshift.io/delete-machine=true
to the machine of interest, regardless of the deletion policy.
By default, the OpenShift Container Platform router pods are deployed on workers. Because the router is required to access some cluster resources, including the web console, do not scale the worker compute machine set to 0
unless you first relocate the router pods.
Custom compute machine sets can be used for use cases requiring that services run on specific nodes and that those services are ignored by the controller when the worker compute machine sets are scaling down. This prevents service disruption.
4.3.4. Creating default cluster-wide node selectors Copy linkLink copied to clipboard!
You can use default cluster-wide node selectors on pods together with labels on nodes to constrain all pods created in a cluster to specific nodes.
With cluster-wide node selectors, when you create a pod in that cluster, OpenShift Container Platform adds the default node selectors to the pod and schedules the pod on nodes with matching labels.
You configure cluster-wide node selectors by editing the Scheduler Operator custom resource (CR). You add labels to a node, a compute machine set, or a machine config. Adding the label to the compute machine set ensures that if the node or machine goes down, new nodes have the label. Labels added to a node or machine config do not persist if the node or machine goes down.
You can add additional key/value pairs to a pod. But you cannot add a different value for a default key.
Procedure
To add a default cluster-wide node selector:
Edit the Scheduler Operator CR to add the default cluster-wide node selectors:
oc edit scheduler cluster
$ oc edit scheduler cluster
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example Scheduler Operator CR with a node selector
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- Add a node selector with the appropriate
<key>:<value>
pairs.
After making this change, wait for the pods in the
openshift-kube-apiserver
project to redeploy. This can take several minutes. The default cluster-wide node selector does not take effect until the pods redeploy.Add labels to a node by using a compute machine set or editing the node directly:
Use a compute machine set to add labels to nodes managed by the compute machine set when a node is created:
Run the following command to add labels to a
MachineSet
object:oc patch MachineSet <name> --type='json' -p='[{"op":"add","path":"/spec/template/spec/metadata/labels", "value":{"<key>"="<value>","<key>"="<value>"}}]' -n openshift-machine-api
$ oc patch MachineSet <name> --type='json' -p='[{"op":"add","path":"/spec/template/spec/metadata/labels", "value":{"<key>"="<value>","<key>"="<value>"}}]' -n openshift-machine-api
1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- Add a
<key>/<value>
pair for each label.
For example:
oc patch MachineSet ci-ln-l8nry52-f76d1-hl7m7-worker-c --type='json' -p='[{"op":"add","path":"/spec/template/spec/metadata/labels", "value":{"type":"user-node","region":"east"}}]' -n openshift-machine-api
$ oc patch MachineSet ci-ln-l8nry52-f76d1-hl7m7-worker-c --type='json' -p='[{"op":"add","path":"/spec/template/spec/metadata/labels", "value":{"type":"user-node","region":"east"}}]' -n openshift-machine-api
Copy to Clipboard Copied! Toggle word wrap Toggle overflow TipYou can alternatively apply the following YAML to add labels to a compute machine set:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that the labels are added to the
MachineSet
object by using theoc edit
command:For example:
oc edit MachineSet abc612-msrtw-worker-us-east-1c -n openshift-machine-api
$ oc edit MachineSet abc612-msrtw-worker-us-east-1c -n openshift-machine-api
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example
MachineSet
objectCopy to Clipboard Copied! Toggle word wrap Toggle overflow Redeploy the nodes associated with that compute machine set by scaling down to
0
and scaling up the nodes:For example:
oc scale --replicas=0 MachineSet ci-ln-l8nry52-f76d1-hl7m7-worker-c -n openshift-machine-api
$ oc scale --replicas=0 MachineSet ci-ln-l8nry52-f76d1-hl7m7-worker-c -n openshift-machine-api
Copy to Clipboard Copied! Toggle word wrap Toggle overflow oc scale --replicas=1 MachineSet ci-ln-l8nry52-f76d1-hl7m7-worker-c -n openshift-machine-api
$ oc scale --replicas=1 MachineSet ci-ln-l8nry52-f76d1-hl7m7-worker-c -n openshift-machine-api
Copy to Clipboard Copied! Toggle word wrap Toggle overflow When the nodes are ready and available, verify that the label is added to the nodes by using the
oc get
command:oc get nodes -l <key>=<value>
$ oc get nodes -l <key>=<value>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow For example:
oc get nodes -l type=user-node
$ oc get nodes -l type=user-node
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
NAME STATUS ROLES AGE VERSION ci-ln-l8nry52-f76d1-hl7m7-worker-c-vmqzp Ready worker 61s v1.30.3
NAME STATUS ROLES AGE VERSION ci-ln-l8nry52-f76d1-hl7m7-worker-c-vmqzp Ready worker 61s v1.30.3
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Add labels directly to a node:
Edit the
Node
object for the node:oc label nodes <name> <key>=<value>
$ oc label nodes <name> <key>=<value>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow For example, to label a node:
oc label nodes ci-ln-l8nry52-f76d1-hl7m7-worker-b-tgq49 type=user-node region=east
$ oc label nodes ci-ln-l8nry52-f76d1-hl7m7-worker-b-tgq49 type=user-node region=east
Copy to Clipboard Copied! Toggle word wrap Toggle overflow TipYou can alternatively apply the following YAML to add labels to a node:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that the labels are added to the node using the
oc get
command:oc get nodes -l <key>=<value>,<key>=<value>
$ oc get nodes -l <key>=<value>,<key>=<value>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow For example:
oc get nodes -l type=user-node,region=east
$ oc get nodes -l type=user-node,region=east
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
NAME STATUS ROLES AGE VERSION ci-ln-l8nry52-f76d1-hl7m7-worker-b-tgq49 Ready worker 17m v1.30.3
NAME STATUS ROLES AGE VERSION ci-ln-l8nry52-f76d1-hl7m7-worker-b-tgq49 Ready worker 17m v1.30.3
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
4.4. Improving cluster stability in high latency environments using worker latency profiles Copy linkLink copied to clipboard!
If the cluster administrator has performed latency tests for platform verification, they can discover the need to adjust the operation of the cluster to ensure stability in cases of high latency. The cluster administrator needs to change only one parameter, recorded in a file, which controls four parameters affecting how supervisory processes read status and interpret the health of the cluster. Changing only the one parameter provides cluster tuning in an easy, supportable manner.
The Kubelet
process provides the starting point for monitoring cluster health. The Kubelet
sets status values for all nodes in the OpenShift Container Platform cluster. The Kubernetes Controller Manager (kube controller
) reads the status values every 10 seconds, by default. If the kube controller
cannot read a node status value, it loses contact with that node after a configured period. The default behavior is:
-
The node controller on the control plane updates the node health to
Unhealthy
and marks the nodeReady
condition`Unknown`. - In response, the scheduler stops scheduling pods to that node.
-
The Node Lifecycle Controller adds a
node.kubernetes.io/unreachable
taint with aNoExecute
effect to the node and schedules any pods on the node for eviction after five minutes, by default.
This behavior can cause problems if your network is prone to latency issues, especially if you have nodes at the network edge. In some cases, the Kubernetes Controller Manager might not receive an update from a healthy node due to network latency. The Kubelet
evicts pods from the node even though the node is healthy.
To avoid this problem, you can use worker latency profiles to adjust the frequency that the Kubelet
and the Kubernetes Controller Manager wait for status updates before taking action. These adjustments help to ensure that your cluster runs properly if network latency between the control plane and the worker nodes is not optimal.
These worker latency profiles contain three sets of parameters that are predefined with carefully tuned values to control the reaction of the cluster to increased latency. There is no need to experimentally find the best values manually.
You can configure worker latency profiles when installing a cluster or at any time you notice increased latency in your cluster network.
4.4.1. Understanding worker latency profiles Copy linkLink copied to clipboard!
Worker latency profiles are four different categories of carefully-tuned parameters. The four parameters which implement these values are node-status-update-frequency
, node-monitor-grace-period
, default-not-ready-toleration-seconds
and default-unreachable-toleration-seconds
. These parameters can use values which allow you to control the reaction of the cluster to latency issues without needing to determine the best values by using manual methods.
Setting these parameters manually is not supported. Incorrect parameter settings adversely affect cluster stability.
All worker latency profiles configure the following parameters:
- node-status-update-frequency
- Specifies how often the kubelet posts node status to the API server.
- node-monitor-grace-period
-
Specifies the amount of time in seconds that the Kubernetes Controller Manager waits for an update from a kubelet before marking the node unhealthy and adding the
node.kubernetes.io/not-ready
ornode.kubernetes.io/unreachable
taint to the node. - default-not-ready-toleration-seconds
- Specifies the amount of time in seconds after marking a node unhealthy that the Kube API Server Operator waits before evicting pods from that node.
- default-unreachable-toleration-seconds
- Specifies the amount of time in seconds after marking a node unreachable that the Kube API Server Operator waits before evicting pods from that node.
The following Operators monitor the changes to the worker latency profiles and respond accordingly:
-
The Machine Config Operator (MCO) updates the
node-status-update-frequency
parameter on the worker nodes. -
The Kubernetes Controller Manager updates the
node-monitor-grace-period
parameter on the control plane nodes. -
The Kubernetes API Server Operator updates the
default-not-ready-toleration-seconds
anddefault-unreachable-toleration-seconds
parameters on the control plane nodes.
Although the default configuration works in most cases, OpenShift Container Platform offers two other worker latency profiles for situations where the network is experiencing higher latency than usual. The three worker latency profiles are described in the following sections:
- Default worker latency profile
With the
Default
profile, eachKubelet
updates its status every 10 seconds (node-status-update-frequency
). TheKube Controller Manager
checks the statuses ofKubelet
every 5 seconds.The Kubernetes Controller Manager waits 40 seconds (
node-monitor-grace-period
) for a status update fromKubelet
before considering theKubelet
unhealthy. If no status is made available to the Kubernetes Controller Manager, it then marks the node with thenode.kubernetes.io/not-ready
ornode.kubernetes.io/unreachable
taint and evicts the pods on that node.If a pod is on a node that has the
NoExecute
taint, the pod runs according totolerationSeconds
. If the node has no taint, it will be evicted in 300 seconds (default-not-ready-toleration-seconds
anddefault-unreachable-toleration-seconds
settings of theKube API Server
).Expand Profile Component Parameter Value Default
kubelet
node-status-update-frequency
10s
Kubelet Controller Manager
node-monitor-grace-period
40s
Kubernetes API Server Operator
default-not-ready-toleration-seconds
300s
Kubernetes API Server Operator
default-unreachable-toleration-seconds
300s
- Medium worker latency profile
Use the
MediumUpdateAverageReaction
profile if the network latency is slightly higher than usual.The
MediumUpdateAverageReaction
profile reduces the frequency of kubelet updates to 20 seconds and changes the period that the Kubernetes Controller Manager waits for those updates to 2 minutes. The pod eviction period for a pod on that node is reduced to 60 seconds. If the pod has thetolerationSeconds
parameter, the eviction waits for the period specified by that parameter.The Kubernetes Controller Manager waits for 2 minutes to consider a node unhealthy. In another minute, the eviction process starts.
Expand Profile Component Parameter Value MediumUpdateAverageReaction
kubelet
node-status-update-frequency
20s
Kubelet Controller Manager
node-monitor-grace-period
2m
Kubernetes API Server Operator
default-not-ready-toleration-seconds
60s
Kubernetes API Server Operator
default-unreachable-toleration-seconds
60s
- Low worker latency profile
Use the
LowUpdateSlowReaction
profile if the network latency is extremely high.The
LowUpdateSlowReaction
profile reduces the frequency of kubelet updates to 1 minute and changes the period that the Kubernetes Controller Manager waits for those updates to 5 minutes. The pod eviction period for a pod on that node is reduced to 60 seconds. If the pod has thetolerationSeconds
parameter, the eviction waits for the period specified by that parameter.The Kubernetes Controller Manager waits for 5 minutes to consider a node unhealthy. In another minute, the eviction process starts.
Expand Profile Component Parameter Value LowUpdateSlowReaction
kubelet
node-status-update-frequency
1m
Kubelet Controller Manager
node-monitor-grace-period
5m
Kubernetes API Server Operator
default-not-ready-toleration-seconds
60s
Kubernetes API Server Operator
default-unreachable-toleration-seconds
60s
The latency profiles do not support custom machine config pools, only the default worker machine config pools.
4.4.2. Using and changing worker latency profiles Copy linkLink copied to clipboard!
To change a worker latency profile to deal with network latency, edit the node.config
object to add the name of the profile. You can change the profile at any time as latency increases or decreases.
You must move one worker latency profile at a time. For example, you cannot move directly from the Default
profile to the LowUpdateSlowReaction
worker latency profile. You must move from the Default
worker latency profile to the MediumUpdateAverageReaction
profile first, then to LowUpdateSlowReaction
. Similarly, when returning to the Default
profile, you must move from the low profile to the medium profile first, then to Default
.
You can also configure worker latency profiles upon installing an OpenShift Container Platform cluster.
Procedure
To move from the default worker latency profile:
Move to the medium worker latency profile:
Edit the
node.config
object:oc edit nodes.config/cluster
$ oc edit nodes.config/cluster
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Add
spec.workerLatencyProfile: MediumUpdateAverageReaction
:Example
node.config
objectCopy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- Specifies the medium worker latency policy.
Scheduling on each worker node is disabled as the change is being applied.
Optional: Move to the low worker latency profile:
Edit the
node.config
object:oc edit nodes.config/cluster
$ oc edit nodes.config/cluster
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Change the
spec.workerLatencyProfile
value toLowUpdateSlowReaction
:Example
node.config
objectCopy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- Specifies use of the low worker latency policy.
Scheduling on each worker node is disabled as the change is being applied.
Verification
When all nodes return to the
Ready
condition, you can use the following command to look in the Kubernetes Controller Manager to ensure it was applied:oc get KubeControllerManager -o yaml | grep -i workerlatency -A 5 -B 5
$ oc get KubeControllerManager -o yaml | grep -i workerlatency -A 5 -B 5
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- Specifies that the profile is applied and active.
To change the medium profile to default or change the default to medium, edit the node.config
object and set the spec.workerLatencyProfile
parameter to the appropriate value.
4.5. Managing control plane machines Copy linkLink copied to clipboard!
Control plane machine sets provide management capabilities for control plane machines that are similar to what compute machine sets provide for compute machines. The availability and initial status of control plane machine sets on your cluster depend on your cloud provider and the version of OpenShift Container Platform that you installed. For more information, see Getting started with control plane machine sets.
4.6. Creating infrastructure machine sets for production environments Copy linkLink copied to clipboard!
You can create a compute machine set to create machines that host only infrastructure components, such as the default router, the integrated container image registry, and components for cluster metrics and monitoring. These infrastructure machines are not counted toward the total number of subscriptions that are required to run the environment.
In a production deployment, it is recommended that you deploy at least three compute machine sets to hold infrastructure components. Both OpenShift Logging and Red Hat OpenShift Service Mesh deploy Elasticsearch, which requires three instances to be installed on different nodes. Each of these nodes can be deployed to different availability zones for high availability. A configuration like this requires three different compute machine sets, one for each availability zone. In global Azure regions that do not have multiple availability zones, you can use availability sets to ensure high availability.
For information on infrastructure nodes and which components can run on infrastructure nodes, see Creating infrastructure machine sets.
To create an infrastructure node, you can use a machine set, assign a label to the nodes, or use a machine config pool.
For sample machine sets that you can use with these procedures, see Creating machine sets for different clouds.
Applying a specific node selector to all infrastructure components causes OpenShift Container Platform to schedule those workloads on nodes with that label.
4.6.1. Creating a compute machine set Copy linkLink copied to clipboard!
In addition to the compute machine sets created by the installation program, you can create your own to dynamically manage the machine compute resources for specific workloads of your choice.
Prerequisites
- Deploy an OpenShift Container Platform cluster.
-
Install the OpenShift CLI (
oc
). -
Log in to
oc
as a user withcluster-admin
permission.
Procedure
Create a new YAML file that contains the compute machine set custom resource (CR) sample and is named
<file_name>.yaml
.Ensure that you set the
<clusterID>
and<role>
parameter values.Optional: If you are not sure which value to set for a specific field, you can check an existing compute machine set from your cluster.
To list the compute machine sets in your cluster, run the following command:
oc get machinesets -n openshift-machine-api
$ oc get machinesets -n openshift-machine-api
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
Copy to Clipboard Copied! Toggle word wrap Toggle overflow To view values of a specific compute machine set custom resource (CR), run the following command:
oc get machineset <machineset_name> \ -n openshift-machine-api -o yaml
$ oc get machineset <machineset_name> \ -n openshift-machine-api -o yaml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- The cluster infrastructure ID.
- 2
- A default node label.Note
For clusters that have user-provisioned infrastructure, a compute machine set can only create
worker
andinfra
type machines. - 3
- The values in the
<providerSpec>
section of the compute machine set CR are platform-specific. For more information about<providerSpec>
parameters in the CR, see the sample compute machine set CR configuration for your provider.
Create a
MachineSet
CR by running the following command:oc create -f <file_name>.yaml
$ oc create -f <file_name>.yaml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
View the list of compute machine sets by running the following command:
oc get machineset -n openshift-machine-api
$ oc get machineset -n openshift-machine-api
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
Copy to Clipboard Copied! Toggle word wrap Toggle overflow When the new compute machine set is available, the
DESIRED
andCURRENT
values match. If the compute machine set is not available, wait a few minutes and run the command again.
4.6.2. Creating an infrastructure node Copy linkLink copied to clipboard!
See Creating infrastructure machine sets for installer-provisioned infrastructure environments or for any cluster where the control plane nodes are managed by the machine API.
Requirements of the cluster dictate that infrastructure (infra) nodes, be provisioned. The installation program provisions only control plane and worker nodes. Worker nodes can be designated as infrastructure nodes through labeling. You can then use taints and tolerations to move appropriate workloads to the infrastructure nodes. For more information, see "Moving resources to infrastructure machine sets".
You can optionally create a default cluster-wide node selector. The default node selector is applied to pods created in all namespaces and creates an intersection with any existing node selectors on a pod, which additionally constrains the pod’s selector.
If the default node selector key conflicts with the key of a pod’s label, then the default node selector is not applied.
However, do not set a default node selector that might cause a pod to become unschedulable. For example, setting the default node selector to a specific node role, such as node-role.kubernetes.io/infra=""
, when a pod’s label is set to a different node role, such as node-role.kubernetes.io/master=""
, can cause the pod to become unschedulable. For this reason, use caution when setting the default node selector to specific node roles.
You can alternatively use a project node selector to avoid cluster-wide node selector key conflicts.
Procedure
Add a label to the worker nodes that you want to act as infrastructure nodes:
oc label node <node-name> node-role.kubernetes.io/infra=""
$ oc label node <node-name> node-role.kubernetes.io/infra=""
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Check to see if applicable nodes now have the
infra
role:oc get nodes
$ oc get nodes
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Optional: Create a default cluster-wide node selector:
Edit the
Scheduler
object:oc edit scheduler cluster
$ oc edit scheduler cluster
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Add the
defaultNodeSelector
field with the appropriate node selector:Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- This example node selector deploys pods on infrastructure nodes by default.
- Save the file to apply the changes.
You can now move infrastructure resources to the new infrastructure nodes. Also, remove any workloads that you do not want, or that do not belong, on the new infrastructure node. See the list of workloads supported for use on infrastructure nodes in "OpenShift Container Platform infrastructure components".
4.6.3. Creating a machine config pool for infrastructure machines Copy linkLink copied to clipboard!
If you need infrastructure machines to have dedicated configurations, you must create an infra pool.
Creating a custom machine configuration pool overrides default worker pool configurations if they refer to the same file or unit.
Procedure
Add a label to the node you want to assign as the infra node with a specific label:
oc label node <node_name> <label>
$ oc label node <node_name> <label>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow oc label node ci-ln-n8mqwr2-f76d1-xscn2-worker-c-6fmtx node-role.kubernetes.io/infra=
$ oc label node ci-ln-n8mqwr2-f76d1-xscn2-worker-c-6fmtx node-role.kubernetes.io/infra=
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Create a machine config pool that contains both the worker role and your custom role as machine config selector:
cat infra.mcp.yaml
$ cat infra.mcp.yaml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
Copy to Clipboard Copied! Toggle word wrap Toggle overflow NoteCustom machine config pools inherit machine configs from the worker pool. Custom pools use any machine config targeted for the worker pool, but add the ability to also deploy changes that are targeted at only the custom pool. Because a custom pool inherits resources from the worker pool, any change to the worker pool also affects the custom pool.
After you have the YAML file, you can create the machine config pool:
oc create -f infra.mcp.yaml
$ oc create -f infra.mcp.yaml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Check the machine configs to ensure that the infrastructure configuration rendered successfully:
oc get machineconfig
$ oc get machineconfig
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
Copy to Clipboard Copied! Toggle word wrap Toggle overflow You should see a new machine config, with the
rendered-infra-*
prefix.Optional: To deploy changes to a custom pool, create a machine config that uses the custom pool name as the label, such as
infra
. Note that this is not required and only shown for instructional purposes. In this manner, you can apply any custom configurations specific to only your infra nodes.NoteAfter you create the new machine config pool, the MCO generates a new rendered config for that pool, and associated nodes of that pool reboot to apply the new configuration.
Create a machine config:
cat infra.mc.yaml
$ cat infra.mc.yaml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- Add the label you added to the node as a
nodeSelector
.
Apply the machine config to the infra-labeled nodes:
oc create -f infra.mc.yaml
$ oc create -f infra.mc.yaml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Confirm that your new machine config pool is available:
oc get mcp
$ oc get mcp
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
NAME CONFIG UPDATED UPDATING DEGRADED MACHINECOUNT READYMACHINECOUNT UPDATEDMACHINECOUNT DEGRADEDMACHINECOUNT AGE infra rendered-infra-60e35c2e99f42d976e084fa94da4d0fc True False False 1 1 1 0 4m20s master rendered-master-9360fdb895d4c131c7c4bebbae099c90 True False False 3 3 3 0 91m worker rendered-worker-60e35c2e99f42d976e084fa94da4d0fc True False False 2 2 2 0 91m
NAME CONFIG UPDATED UPDATING DEGRADED MACHINECOUNT READYMACHINECOUNT UPDATEDMACHINECOUNT DEGRADEDMACHINECOUNT AGE infra rendered-infra-60e35c2e99f42d976e084fa94da4d0fc True False False 1 1 1 0 4m20s master rendered-master-9360fdb895d4c131c7c4bebbae099c90 True False False 3 3 3 0 91m worker rendered-worker-60e35c2e99f42d976e084fa94da4d0fc True False False 2 2 2 0 91m
Copy to Clipboard Copied! Toggle word wrap Toggle overflow In this example, a worker node was changed to an infra node.
4.7. Assigning machine set resources to infrastructure nodes Copy linkLink copied to clipboard!
After creating an infrastructure machine set, the worker
and infra
roles are applied to new infra nodes. Nodes with the infra
role are not counted toward the total number of subscriptions that are required to run the environment, even when the worker
role is also applied.
However, when an infra node is assigned the worker role, there is a chance that user workloads can get assigned inadvertently to the infra node. To avoid this, you can apply a taint to the infra node and tolerations for the pods that you want to control.
4.7.1. Binding infrastructure node workloads using taints and tolerations Copy linkLink copied to clipboard!
If you have an infrastructure node that has the infra
and worker
roles assigned, you must configure the node so that user workloads are not assigned to it.
It is recommended that you preserve the dual infra,worker
label that is created for infrastructure nodes and use taints and tolerations to manage nodes that user workloads are scheduled on. If you remove the worker
label from the node, you must create a custom pool to manage it. A node with a label other than master
or worker
is not recognized by the MCO without a custom pool. Maintaining the worker
label allows the node to be managed by the default worker machine config pool, if no custom pools that select the custom label exists. The infra
label communicates to the cluster that it does not count toward the total number of subscriptions.
Prerequisites
-
Configure additional
MachineSet
objects in your OpenShift Container Platform cluster.
Procedure
Add a taint to the infrastructure node to prevent scheduling user workloads on it:
Determine if the node has the taint:
oc describe nodes <node_name>
$ oc describe nodes <node_name>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Sample output
Copy to Clipboard Copied! Toggle word wrap Toggle overflow This example shows that the node has a taint. You can proceed with adding a toleration to your pod in the next step.
If you have not configured a taint to prevent scheduling user workloads on it:
oc adm taint nodes <node_name> <key>=<value>:<effect>
$ oc adm taint nodes <node_name> <key>=<value>:<effect>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow For example:
oc adm taint nodes node1 node-role.kubernetes.io/infra=reserved:NoSchedule
$ oc adm taint nodes node1 node-role.kubernetes.io/infra=reserved:NoSchedule
Copy to Clipboard Copied! Toggle word wrap Toggle overflow TipYou can alternatively edit the pod specification to add the taint:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow These examples place a taint on
node1
that has thenode-role.kubernetes.io/infra
key and theNoSchedule
taint effect. Nodes with theNoSchedule
effect schedule only pods that tolerate the taint, but allow existing pods to remain scheduled on the node.If you added a
NoSchedule
taint to the infrastructure node, any pods that are controlled by a daemon set on that node are marked asmisscheduled
. You must either delete the pods or add a toleration to the pods as shown in the Red Hat Knowledgebase solution add toleration onmisscheduled
DNS pods. Note that you cannot add a toleration to a daemon set object that is managed by an operator.NoteIf a descheduler is used, pods violating node taints could be evicted from the cluster.
Add tolerations to the pods that you want to schedule on the infrastructure node, such as the router, registry, and monitoring workloads. Referencing the previous examples, add the following tolerations to the
Pod
object specification:Copy to Clipboard Copied! Toggle word wrap Toggle overflow This toleration matches the taint created by the
oc adm taint
command. A pod with this toleration can be scheduled onto the infrastructure node.NoteMoving pods for an Operator installed via OLM to an infrastructure node is not always possible. The capability to move Operator pods depends on the configuration of each Operator.
- Schedule the pod to the infrastructure node by using a scheduler. See the documentation for "Controlling pod placement using the scheduler" for details.
- Remove any workloads that you do not want, or that do not belong, on the new infrastructure node. See the list of workloads supported for use on infrastructure nodes in "OpenShift Container Platform infrastructure components".
4.8. Moving resources to infrastructure machine sets Copy linkLink copied to clipboard!
Some of the infrastructure resources are deployed in your cluster by default. You can move them to the infrastructure machine sets that you created.
4.8.1. Moving the router Copy linkLink copied to clipboard!
You can deploy the router pod to a different compute machine set. By default, the pod is deployed to a worker node.
Prerequisites
- Configure additional compute machine sets in your OpenShift Container Platform cluster.
Procedure
View the
IngressController
custom resource for the router Operator:oc get ingresscontroller default -n openshift-ingress-operator -o yaml
$ oc get ingresscontroller default -n openshift-ingress-operator -o yaml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The command output resembles the following text:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Edit the
ingresscontroller
resource and change thenodeSelector
to use theinfra
label:oc edit ingresscontroller default -n openshift-ingress-operator
$ oc edit ingresscontroller default -n openshift-ingress-operator
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- Add a
nodeSelector
parameter with the appropriate value to the component you want to move. You can use anodeSelector
parameter in the format shown or use<key>: <value>
pairs, based on the value specified for the node. If you added a taint to the infrastructure node, also add a matching toleration.
Confirm that the router pod is running on the
infra
node.View the list of router pods and note the node name of the running pod:
oc get pod -n openshift-ingress -o wide
$ oc get pod -n openshift-ingress -o wide
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES router-default-86798b4b5d-bdlvd 1/1 Running 0 28s 10.130.2.4 ip-10-0-217-226.ec2.internal <none> <none> router-default-955d875f4-255g8 0/1 Terminating 0 19h 10.129.2.4 ip-10-0-148-172.ec2.internal <none> <none>
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES router-default-86798b4b5d-bdlvd 1/1 Running 0 28s 10.130.2.4 ip-10-0-217-226.ec2.internal <none> <none> router-default-955d875f4-255g8 0/1 Terminating 0 19h 10.129.2.4 ip-10-0-148-172.ec2.internal <none> <none>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow In this example, the running pod is on the
ip-10-0-217-226.ec2.internal
node.View the node status of the running pod:
oc get node <node_name>
$ oc get node <node_name>
1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- Specify the
<node_name>
that you obtained from the pod list.
Example output
NAME STATUS ROLES AGE VERSION ip-10-0-217-226.ec2.internal Ready infra,worker 17h v1.30.3
NAME STATUS ROLES AGE VERSION ip-10-0-217-226.ec2.internal Ready infra,worker 17h v1.30.3
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Because the role list includes
infra
, the pod is running on the correct node.
4.8.2. Moving the default registry Copy linkLink copied to clipboard!
You configure the registry Operator to deploy its pods to different nodes.
Prerequisites
- Configure additional compute machine sets in your OpenShift Container Platform cluster.
Procedure
View the
config/instance
object:oc get configs.imageregistry.operator.openshift.io/cluster -o yaml
$ oc get configs.imageregistry.operator.openshift.io/cluster -o yaml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Edit the
config/instance
object:oc edit configs.imageregistry.operator.openshift.io/cluster
$ oc edit configs.imageregistry.operator.openshift.io/cluster
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- Add a
nodeSelector
parameter with the appropriate value to the component you want to move. You can use anodeSelector
parameter in the format shown or use<key>: <value>
pairs, based on the value specified for the node. If you added a taint to the infrasructure node, also add a matching toleration.
Verify the registry pod has been moved to the infrastructure node.
Run the following command to identify the node where the registry pod is located:
oc get pods -o wide -n openshift-image-registry
$ oc get pods -o wide -n openshift-image-registry
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Confirm the node has the label you specified:
oc describe node <node_name>
$ oc describe node <node_name>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Review the command output and confirm that
node-role.kubernetes.io/infra
is in theLABELS
list.
4.8.3. Moving the monitoring solution Copy linkLink copied to clipboard!
The monitoring stack includes multiple components, including Prometheus, Thanos Querier, and Alertmanager. The Cluster Monitoring Operator manages this stack. To redeploy the monitoring stack to infrastructure nodes, you can create and apply a custom config map.
Prerequisites
-
You have access to the cluster as a user with the
cluster-admin
cluster role. -
You have created the
cluster-monitoring-config
ConfigMap
object. -
You have installed the OpenShift CLI (
oc
).
Procedure
Edit the
cluster-monitoring-config
config map and change thenodeSelector
to use theinfra
label:oc edit configmap cluster-monitoring-config -n openshift-monitoring
$ oc edit configmap cluster-monitoring-config -n openshift-monitoring
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- Add a
nodeSelector
parameter with the appropriate value to the component you want to move. You can use anodeSelector
parameter in the format shown or use<key>: <value>
pairs, based on the value specified for the node. If you added a taint to the infrastructure node, also add a matching toleration.
Watch the monitoring pods move to the new machines:
watch 'oc get pod -n openshift-monitoring -o wide'
$ watch 'oc get pod -n openshift-monitoring -o wide'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If a component has not moved to the
infra
node, delete the pod with this component:oc delete pod -n openshift-monitoring <pod>
$ oc delete pod -n openshift-monitoring <pod>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The component from the deleted pod is re-created on the
infra
node.
4.9. Applying autoscaling to your cluster Copy linkLink copied to clipboard!
Applying autoscaling to an OpenShift Container Platform cluster involves deploying a cluster autoscaler and then deploying machine autoscalers for each machine type in your cluster.
For more information, see Applying autoscaling to an OpenShift Container Platform cluster.
4.10. Configuring Linux cgroup Copy linkLink copied to clipboard!
As of OpenShift Container Platform 4.14, OpenShift Container Platform uses Linux control group version 2 (cgroup v2) in your cluster. If you are using cgroup v1 on OpenShift Container Platform 4.13 or earlier, migrating to OpenShift Container Platform 4.14 or later will not automatically update your cgroup configuration to version 2. A fresh installation of OpenShift Container Platform 4.14 or later will use cgroup v2 by default. However, you can enable Linux control group version 1 (cgroup v1) upon installation.
cgroup v2 is the current version of the Linux cgroup API. cgroup v2 offers several improvements over cgroup v1, including a unified hierarchy, safer sub-tree delegation, new features such as Pressure Stall Information, and enhanced resource management and isolation. However, cgroup v2 has different CPU, memory, and I/O management characteristics than cgroup v1. Therefore, some workloads might experience slight differences in memory or CPU usage on clusters that run cgroup v2.
You can change between cgroup v1 and cgroup v2, as needed. Enabling cgroup v1 in OpenShift Container Platform disables all cgroup v2 controllers and hierarchies in your cluster.
cgroup v1 is a deprecated feature. Deprecated functionality is still included in OpenShift Container Platform and continues to be supported; however, it will be removed in a future release of this product and is not recommended for new deployments.
For the most recent list of major functionality that has been deprecated or removed within OpenShift Container Platform, refer to the Deprecated and removed features section of the OpenShift Container Platform release notes.
Prerequisites
- You have a running OpenShift Container Platform cluster that uses version 4.12 or later.
- You are logged in to the cluster as a user with administrative privileges.
Procedure
Configure the wanted cgroup version on your nodes:
Edit the
node.config
object:oc edit nodes.config/cluster
$ oc edit nodes.config/cluster
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Add
spec.cgroupMode: "v1"
:Example
node.config
objectCopy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- Enables cgroup v1.
Verification
Check the machine configs to see that the new machine configs were added:
oc get mc
$ oc get mc
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- New machine configs are created, as expected.
Check that the new
kernelArguments
were added to the new machine configs:oc describe mc <name>
$ oc describe mc <name>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example output for cgroup v1
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Check the nodes to see that scheduling on the nodes is disabled. This indicates that the change is being applied:
oc get nodes
$ oc get nodes
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
Copy to Clipboard Copied! Toggle word wrap Toggle overflow After a node returns to the
Ready
state, start a debug session for that node:oc debug node/<node_name>
$ oc debug node/<node_name>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Set
/host
as the root directory within the debug shell:chroot /host
sh-4.4# chroot /host
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Check that the
sys/fs/cgroup/cgroup2fs
file is present on your nodes. This file is created by cgroup v1:stat -c %T -f /sys/fs/cgroup
$ stat -c %T -f /sys/fs/cgroup
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
cgroup2fs
cgroup2fs
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
4.11. Enabling Technology Preview features using FeatureGates Copy linkLink copied to clipboard!
You can turn on a subset of the current Technology Preview features on for all nodes in the cluster by editing the FeatureGate
custom resource (CR).
4.11.1. Understanding feature gates Copy linkLink copied to clipboard!
You can use the FeatureGate
custom resource (CR) to enable specific feature sets in your cluster. A feature set is a collection of OpenShift Container Platform features that are not enabled by default.
You can activate the following feature set by using the FeatureGate
CR:
TechPreviewNoUpgrade
. This feature set is a subset of the current Technology Preview features. This feature set allows you to enable these Technology Preview features on test clusters, where you can fully test them, while leaving the features disabled on production clusters.WarningEnabling the
TechPreviewNoUpgrade
feature set on your cluster cannot be undone and prevents minor version updates. You should not enable this feature set on production clusters.The following Technology Preview features are enabled by this feature set:
-
External cloud providers. Enables support for external cloud providers for clusters on vSphere, AWS, Azure, and GCP. Support for OpenStack is GA. This is an internal feature that most users do not need to interact with. (
ExternalCloudProvider
) -
Swap memory on nodes. Enables swap memory use for OpenShift Container Platform workloads on a per-node basis. (
NodeSwap
) -
OpenStack Machine API Provider. This gate has no effect and is planned to be removed from this feature set in a future release. (
MachineAPIProviderOpenStack
) -
Insights Operator. Enables the
InsightsDataGather
CRD, which allows users to configure some Insights data gathering options. The feature set also enables theDataGather
CRD, which allows users to run Insights data gathering on-demand. (InsightsConfigAPI
) -
Dynamic Resource Allocation API. Enables a new API for requesting and sharing resources between pods and containers. This is an internal feature that most users do not need to interact with. (
DynamicResourceAllocation
) -
Pod security admission enforcement. Enables the restricted enforcement mode for pod security admission. Instead of only logging a warning, pods are rejected if they violate pod security standards. (
OpenShiftPodSecurityAdmission
) -
StatefulSet pod availability upgrading limits. Enables users to define the maximum number of statefulset pods unavailable during updates which reduces application downtime. (
MaxUnavailableStatefulSet
) -
gcpLabelsTags
-
vSphereStaticIPs
-
routeExternalCertificate
-
automatedEtcdBackup
-
gcpClusterHostedDNS
-
vSphereControlPlaneMachineset
-
dnsNameResolver
-
machineConfigNodes
-
metricsServer
-
installAlternateInfrastructureAWS
-
mixedCPUsAllocation
-
managedBootImages
-
onClusterBuild
-
signatureStores
-
SigstoreImageVerification
-
DisableKubeletCloudCredentialProviders
-
BareMetalLoadBalancer
-
ClusterAPIInstallAWS
-
ClusterAPIInstallAzure
-
ClusterAPIInstallNutanix
-
ClusterAPIInstallOpenStack
-
ClusterAPIInstallVSphere
-
HardwareSpeed
-
KMSv1
-
NetworkDiagnosticsConfig
-
VSphereDriverConfiguration
-
ExternalOIDC
-
ChunkSizeMiB
-
ClusterAPIInstallGCP
-
ClusterAPIInstallPowerVS
-
EtcdBackendQuota
-
InsightsConfig
-
InsightsOnDemandDataGather
-
MetricsCollectionProfiles
-
NewOLM
-
NodeDisruptionPolicy
-
PinnedImages
-
PlatformOperators
-
ServiceAccountTokenNodeBinding
-
TranslateStreamCloseWebsocketRequests
-
UpgradeStatus
-
VSphereMultiVCenters
-
VolumeGroupSnapshot
-
AdditionalRoutingCapabilities
-
BootcNodeManagement
-
ClusterMonitoringConfig
-
DNSNameResolver
-
ManagedBootImagesAWS
-
NetworkSegmentation
-
OVNObservability
-
PersistentIPsForVirtualization
-
ProcMountType
-
RouteAdvertisements
-
UserNamespacesSupport
-
AWSEFSDriverVolumeMetrics
-
AlibabaPlatform
-
AzureWorkloadIdentity
-
BuildCSIVolumes
-
CloudDualStackNodeIPs
-
ExternalCloudProviderAzure
-
ExternalCloudProviderExternal
-
ExternalCloudProviderGCP
-
IngressControllerLBSubnetsAWS
-
MultiArchInstallAWS
-
MultiArchInstallGCP
-
NetworkLiveMigration
-
PrivateHostedZoneAWS
-
SetEIPForNLBIngressController
-
ValidatingAdmissionPolicy
-
External cloud providers. Enables support for external cloud providers for clusters on vSphere, AWS, Azure, and GCP. Support for OpenStack is GA. This is an internal feature that most users do not need to interact with. (
4.11.2. Enabling feature sets using the web console Copy linkLink copied to clipboard!
You can use the OpenShift Container Platform web console to enable feature sets for all of the nodes in a cluster by editing the FeatureGate
custom resource (CR).
Procedure
To enable feature sets:
-
In the OpenShift Container Platform web console, switch to the Administration
Custom Resource Definitions page. - On the Custom Resource Definitions page, click FeatureGate.
- On the Custom Resource Definition Details page, click the Instances tab.
- Click the cluster feature gate, then click the YAML tab.
Edit the cluster instance to add specific feature sets:
WarningEnabling the
TechPreviewNoUpgrade
feature set on your cluster cannot be undone and prevents minor version updates. You should not enable this feature set on production clusters.Sample Feature Gate custom resource
Copy to Clipboard Copied! Toggle word wrap Toggle overflow After you save the changes, new machine configs are created, the machine config pools are updated, and scheduling on each node is disabled while the change is being applied.
Verification
You can verify that the feature gates are enabled by looking at the kubelet.conf
file on a node after the nodes return to the ready state.
-
From the Administrator perspective in the web console, navigate to Compute
Nodes. - Select a node.
- In the Node details page, click Terminal.
In the terminal window, change your root directory to
/host
:chroot /host
sh-4.2# chroot /host
Copy to Clipboard Copied! Toggle word wrap Toggle overflow View the
kubelet.conf
file:cat /etc/kubernetes/kubelet.conf
sh-4.2# cat /etc/kubernetes/kubelet.conf
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Sample output
... ...
# ... featureGates: InsightsOperatorPullingSCA: true, LegacyNodeRoleBehavior: false # ...
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The features that are listed as
true
are enabled on your cluster.NoteThe features listed vary depending upon the OpenShift Container Platform version.
4.11.3. Enabling feature sets using the CLI Copy linkLink copied to clipboard!
You can use the OpenShift CLI (oc
) to enable feature sets for all of the nodes in a cluster by editing the FeatureGate
custom resource (CR).
Prerequisites
-
You have installed the OpenShift CLI (
oc
).
Procedure
To enable feature sets:
Edit the
FeatureGate
CR namedcluster
:oc edit featuregate cluster
$ oc edit featuregate cluster
Copy to Clipboard Copied! Toggle word wrap Toggle overflow WarningEnabling the
TechPreviewNoUpgrade
feature set on your cluster cannot be undone and prevents minor version updates. You should not enable this feature set on production clusters.Sample FeatureGate custom resource
Copy to Clipboard Copied! Toggle word wrap Toggle overflow After you save the changes, new machine configs are created, the machine config pools are updated, and scheduling on each node is disabled while the change is being applied.
Verification
You can verify that the feature gates are enabled by looking at the kubelet.conf
file on a node after the nodes return to the ready state.
-
From the Administrator perspective in the web console, navigate to Compute
Nodes. - Select a node.
- In the Node details page, click Terminal.
In the terminal window, change your root directory to
/host
:chroot /host
sh-4.2# chroot /host
Copy to Clipboard Copied! Toggle word wrap Toggle overflow View the
kubelet.conf
file:cat /etc/kubernetes/kubelet.conf
sh-4.2# cat /etc/kubernetes/kubelet.conf
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Sample output
... ...
# ... featureGates: InsightsOperatorPullingSCA: true, LegacyNodeRoleBehavior: false # ...
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The features that are listed as
true
are enabled on your cluster.NoteThe features listed vary depending upon the OpenShift Container Platform version.
4.12. etcd tasks Copy linkLink copied to clipboard!
Back up etcd, enable or disable etcd encryption, or defragment etcd data.
If you deployed a bare-metal cluster, you can scale the cluster up to 5 nodes as part of your post-installation tasks. For more information, see Node scaling for etcd.
4.12.1. About etcd encryption Copy linkLink copied to clipboard!
By default, etcd data is not encrypted in OpenShift Container Platform. You can enable etcd encryption for your cluster to provide an additional layer of data security. For example, it can help protect the loss of sensitive data if an etcd backup is exposed to the incorrect parties.
When you enable etcd encryption, the following OpenShift API server and Kubernetes API server resources are encrypted:
- Secrets
- Config maps
- Routes
- OAuth access tokens
- OAuth authorize tokens
When you enable etcd encryption, encryption keys are created. You must have these keys to restore from an etcd backup.
Etcd encryption only encrypts values, not keys. Resource types, namespaces, and object names are unencrypted.
If etcd encryption is enabled during a backup, the static_kuberesources_<datetimestamp>.tar.gz
file contains the encryption keys for the etcd snapshot. For security reasons, store this file separately from the etcd snapshot. However, this file is required to restore a previous state of etcd from the respective etcd snapshot.
4.12.2. Supported encryption types Copy linkLink copied to clipboard!
The following encryption types are supported for encrypting etcd data in OpenShift Container Platform:
- AES-CBC
- Uses AES-CBC with PKCS#7 padding and a 32 byte key to perform the encryption. The encryption keys are rotated weekly.
- AES-GCM
- Uses AES-GCM with a random nonce and a 32 byte key to perform the encryption. The encryption keys are rotated weekly.
4.12.3. Enabling etcd encryption Copy linkLink copied to clipboard!
You can enable etcd encryption to encrypt sensitive resources in your cluster.
Do not back up etcd resources until the initial encryption process is completed. If the encryption process is not completed, the backup might be only partially encrypted.
After you enable etcd encryption, several changes can occur:
- The etcd encryption might affect the memory consumption of a few resources.
- You might notice a transient affect on backup performance because the leader must serve the backup.
- A disk I/O can affect the node that receives the backup state.
You can encrypt the etcd database in either AES-GCM or AES-CBC encryption.
To migrate your etcd database from one encryption type to the other, you can modify the API server’s spec.encryption.type
field. Migration of the etcd data to the new encryption type occurs automatically.
Prerequisites
-
Access to the cluster as a user with the
cluster-admin
role.
Procedure
Modify the
APIServer
object:oc edit apiserver
$ oc edit apiserver
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Set the
spec.encryption.type
field toaesgcm
oraescbc
:spec: encryption: type: aesgcm
spec: encryption: type: aesgcm
1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- Set to
aesgcm
for AES-GCM encryption oraescbc
for AES-CBC encryption.
Save the file to apply the changes.
The encryption process starts. It can take 20 minutes or longer for this process to complete, depending on the size of the etcd database.
Verify that etcd encryption was successful.
Review the
Encrypted
status condition for the OpenShift API server to verify that its resources were successfully encrypted:oc get openshiftapiserver -o=jsonpath='{range .items[0].status.conditions[?(@.type=="Encrypted")]}{.reason}{"\n"}{.message}{"\n"}'
$ oc get openshiftapiserver -o=jsonpath='{range .items[0].status.conditions[?(@.type=="Encrypted")]}{.reason}{"\n"}{.message}{"\n"}'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The output shows
EncryptionCompleted
upon successful encryption:EncryptionCompleted All resources encrypted: routes.route.openshift.io
EncryptionCompleted All resources encrypted: routes.route.openshift.io
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If the output shows
EncryptionInProgress
, encryption is still in progress. Wait a few minutes and try again.Review the
Encrypted
status condition for the Kubernetes API server to verify that its resources were successfully encrypted:oc get kubeapiserver -o=jsonpath='{range .items[0].status.conditions[?(@.type=="Encrypted")]}{.reason}{"\n"}{.message}{"\n"}'
$ oc get kubeapiserver -o=jsonpath='{range .items[0].status.conditions[?(@.type=="Encrypted")]}{.reason}{"\n"}{.message}{"\n"}'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The output shows
EncryptionCompleted
upon successful encryption:EncryptionCompleted All resources encrypted: secrets, configmaps
EncryptionCompleted All resources encrypted: secrets, configmaps
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If the output shows
EncryptionInProgress
, encryption is still in progress. Wait a few minutes and try again.Review the
Encrypted
status condition for the OpenShift OAuth API server to verify that its resources were successfully encrypted:oc get authentication.operator.openshift.io -o=jsonpath='{range .items[0].status.conditions[?(@.type=="Encrypted")]}{.reason}{"\n"}{.message}{"\n"}'
$ oc get authentication.operator.openshift.io -o=jsonpath='{range .items[0].status.conditions[?(@.type=="Encrypted")]}{.reason}{"\n"}{.message}{"\n"}'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The output shows
EncryptionCompleted
upon successful encryption:EncryptionCompleted All resources encrypted: oauthaccesstokens.oauth.openshift.io, oauthauthorizetokens.oauth.openshift.io
EncryptionCompleted All resources encrypted: oauthaccesstokens.oauth.openshift.io, oauthauthorizetokens.oauth.openshift.io
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If the output shows
EncryptionInProgress
, encryption is still in progress. Wait a few minutes and try again.
4.12.4. Disabling etcd encryption Copy linkLink copied to clipboard!
You can disable encryption of etcd data in your cluster.
Prerequisites
-
Access to the cluster as a user with the
cluster-admin
role.
Procedure
Modify the
APIServer
object:oc edit apiserver
$ oc edit apiserver
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Set the
encryption
field type toidentity
:spec: encryption: type: identity
spec: encryption: type: identity
1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- The
identity
type is the default value and means that no encryption is performed.
Save the file to apply the changes.
The decryption process starts. It can take 20 minutes or longer for this process to complete, depending on the size of your cluster.
Verify that etcd decryption was successful.
Review the
Encrypted
status condition for the OpenShift API server to verify that its resources were successfully decrypted:oc get openshiftapiserver -o=jsonpath='{range .items[0].status.conditions[?(@.type=="Encrypted")]}{.reason}{"\n"}{.message}{"\n"}'
$ oc get openshiftapiserver -o=jsonpath='{range .items[0].status.conditions[?(@.type=="Encrypted")]}{.reason}{"\n"}{.message}{"\n"}'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The output shows
DecryptionCompleted
upon successful decryption:DecryptionCompleted Encryption mode set to identity and everything is decrypted
DecryptionCompleted Encryption mode set to identity and everything is decrypted
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If the output shows
DecryptionInProgress
, decryption is still in progress. Wait a few minutes and try again.Review the
Encrypted
status condition for the Kubernetes API server to verify that its resources were successfully decrypted:oc get kubeapiserver -o=jsonpath='{range .items[0].status.conditions[?(@.type=="Encrypted")]}{.reason}{"\n"}{.message}{"\n"}'
$ oc get kubeapiserver -o=jsonpath='{range .items[0].status.conditions[?(@.type=="Encrypted")]}{.reason}{"\n"}{.message}{"\n"}'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The output shows
DecryptionCompleted
upon successful decryption:DecryptionCompleted Encryption mode set to identity and everything is decrypted
DecryptionCompleted Encryption mode set to identity and everything is decrypted
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If the output shows
DecryptionInProgress
, decryption is still in progress. Wait a few minutes and try again.Review the
Encrypted
status condition for the OpenShift OAuth API server to verify that its resources were successfully decrypted:oc get authentication.operator.openshift.io -o=jsonpath='{range .items[0].status.conditions[?(@.type=="Encrypted")]}{.reason}{"\n"}{.message}{"\n"}'
$ oc get authentication.operator.openshift.io -o=jsonpath='{range .items[0].status.conditions[?(@.type=="Encrypted")]}{.reason}{"\n"}{.message}{"\n"}'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The output shows
DecryptionCompleted
upon successful decryption:DecryptionCompleted Encryption mode set to identity and everything is decrypted
DecryptionCompleted Encryption mode set to identity and everything is decrypted
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If the output shows
DecryptionInProgress
, decryption is still in progress. Wait a few minutes and try again.
4.12.5. Backing up etcd data Copy linkLink copied to clipboard!
Follow these steps to back up etcd data by creating an etcd snapshot and backing up the resources for the static pods. This backup can be saved and used at a later time if you need to restore etcd.
Only save a backup from a single control plane host. Do not take a backup from each control plane host in the cluster.
Prerequisites
-
You have access to the cluster as a user with the
cluster-admin
role. You have checked whether the cluster-wide proxy is enabled.
TipYou can check whether the proxy is enabled by reviewing the output of
oc get proxy cluster -o yaml
. The proxy is enabled if thehttpProxy
,httpsProxy
, andnoProxy
fields have values set.
Procedure
Start a debug session as root for a control plane node:
oc debug --as-root node/<node_name>
$ oc debug --as-root node/<node_name>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Change your root directory to
/host
in the debug shell:chroot /host
sh-4.4# chroot /host
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If the cluster-wide proxy is enabled, export the
NO_PROXY
,HTTP_PROXY
, andHTTPS_PROXY
environment variables by running the following commands:export HTTP_PROXY=http://<your_proxy.example.com>:8080
$ export HTTP_PROXY=http://<your_proxy.example.com>:8080
Copy to Clipboard Copied! Toggle word wrap Toggle overflow export HTTPS_PROXY=https://<your_proxy.example.com>:8080
$ export HTTPS_PROXY=https://<your_proxy.example.com>:8080
Copy to Clipboard Copied! Toggle word wrap Toggle overflow export NO_PROXY=<example.com>
$ export NO_PROXY=<example.com>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Run the
cluster-backup.sh
script in the debug shell and pass in the location to save the backup to.TipThe
cluster-backup.sh
script is maintained as a component of the etcd Cluster Operator and is a wrapper around theetcdctl snapshot save
command./usr/local/bin/cluster-backup.sh /home/core/assets/backup
sh-4.4# /usr/local/bin/cluster-backup.sh /home/core/assets/backup
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example script output
Copy to Clipboard Copied! Toggle word wrap Toggle overflow In this example, two files are created in the
/home/core/assets/backup/
directory on the control plane host:-
snapshot_<datetimestamp>.db
: This file is the etcd snapshot. Thecluster-backup.sh
script confirms its validity. static_kuberesources_<datetimestamp>.tar.gz
: This file contains the resources for the static pods. If etcd encryption is enabled, it also contains the encryption keys for the etcd snapshot.NoteIf etcd encryption is enabled, it is recommended to store this second file separately from the etcd snapshot for security reasons. However, this file is required to restore from the etcd snapshot.
Keep in mind that etcd encryption only encrypts values, not keys. This means that resource types, namespaces, and object names are unencrypted.
-
4.12.6. Defragmenting etcd data Copy linkLink copied to clipboard!
For large and dense clusters, etcd can suffer from poor performance if the keyspace grows too large and exceeds the space quota. Periodically maintain and defragment etcd to free up space in the data store. Monitor Prometheus for etcd metrics and defragment it when required; otherwise, etcd can raise a cluster-wide alarm that puts the cluster into a maintenance mode that accepts only key reads and deletes.
Monitor these key metrics:
-
etcd_server_quota_backend_bytes
, which is the current quota limit -
etcd_mvcc_db_total_size_in_use_in_bytes
, which indicates the actual database usage after a history compaction -
etcd_mvcc_db_total_size_in_bytes
, which shows the database size, including free space waiting for defragmentation
Defragment etcd data to reclaim disk space after events that cause disk fragmentation, such as etcd history compaction.
History compaction is performed automatically every five minutes and leaves gaps in the back-end database. This fragmented space is available for use by etcd, but is not available to the host file system. You must defragment etcd to make this space available to the host file system.
Defragmentation occurs automatically, but you can also trigger it manually.
Automatic defragmentation is good for most cases, because the etcd operator uses cluster information to determine the most efficient operation for the user.
4.12.6.1. Automatic defragmentation Copy linkLink copied to clipboard!
The etcd Operator automatically defragments disks. No manual intervention is needed.
Verify that the defragmentation process is successful by viewing one of these logs:
- etcd logs
- cluster-etcd-operator pod
- operator status error log
Automatic defragmentation can cause leader election failure in various OpenShift core components, such as the Kubernetes controller manager, which triggers a restart of the failing component. The restart is harmless and either triggers failover to the next running instance or the component resumes work again after the restart.
Example log output for successful defragmentation
etcd member has been defragmented: <member_name>, memberID: <member_id>
etcd member has been defragmented: <member_name>, memberID: <member_id>
Example log output for unsuccessful defragmentation
failed defrag on member: <member_name>, memberID: <member_id>: <error_message>
failed defrag on member: <member_name>, memberID: <member_id>: <error_message>
4.12.6.2. Manual defragmentation Copy linkLink copied to clipboard!
A Prometheus alert indicates when you need to use manual defragmentation. The alert is displayed in two cases:
- When etcd uses more than 50% of its available space for more than 10 minutes
- When etcd is actively using less than 50% of its total database size for more than 10 minutes
You can also determine whether defragmentation is needed by checking the etcd database size in MB that will be freed by defragmentation with the PromQL expression: (etcd_mvcc_db_total_size_in_bytes - etcd_mvcc_db_total_size_in_use_in_bytes)/1024/1024
Defragmenting etcd is a blocking action. The etcd member will not respond until defragmentation is complete. For this reason, wait at least one minute between defragmentation actions on each of the pods to allow the cluster to recover.
Follow this procedure to defragment etcd data on each etcd member.
Prerequisites
-
You have access to the cluster as a user with the
cluster-admin
role.
Procedure
Determine which etcd member is the leader, because the leader should be defragmented last.
Get the list of etcd pods:
oc -n openshift-etcd get pods -l k8s-app=etcd -o wide
$ oc -n openshift-etcd get pods -l k8s-app=etcd -o wide
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
etcd-ip-10-0-159-225.example.redhat.com 3/3 Running 0 175m 10.0.159.225 ip-10-0-159-225.example.redhat.com <none> <none> etcd-ip-10-0-191-37.example.redhat.com 3/3 Running 0 173m 10.0.191.37 ip-10-0-191-37.example.redhat.com <none> <none> etcd-ip-10-0-199-170.example.redhat.com 3/3 Running 0 176m 10.0.199.170 ip-10-0-199-170.example.redhat.com <none> <none>
etcd-ip-10-0-159-225.example.redhat.com 3/3 Running 0 175m 10.0.159.225 ip-10-0-159-225.example.redhat.com <none> <none> etcd-ip-10-0-191-37.example.redhat.com 3/3 Running 0 173m 10.0.191.37 ip-10-0-191-37.example.redhat.com <none> <none> etcd-ip-10-0-199-170.example.redhat.com 3/3 Running 0 176m 10.0.199.170 ip-10-0-199-170.example.redhat.com <none> <none>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Choose a pod and run the following command to determine which etcd member is the leader:
oc rsh -n openshift-etcd etcd-ip-10-0-159-225.example.redhat.com etcdctl endpoint status --cluster -w table
$ oc rsh -n openshift-etcd etcd-ip-10-0-159-225.example.redhat.com etcdctl endpoint status --cluster -w table
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Based on the
IS LEADER
column of this output, thehttps://10.0.199.170:2379
endpoint is the leader. Matching this endpoint with the output of the previous step, the pod name of the leader isetcd-ip-10-0-199-170.example.redhat.com
.
Defragment an etcd member.
Connect to the running etcd container, passing in the name of a pod that is not the leader:
oc rsh -n openshift-etcd etcd-ip-10-0-159-225.example.redhat.com
$ oc rsh -n openshift-etcd etcd-ip-10-0-159-225.example.redhat.com
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Unset the
ETCDCTL_ENDPOINTS
environment variable:unset ETCDCTL_ENDPOINTS
sh-4.4# unset ETCDCTL_ENDPOINTS
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Defragment the etcd member:
etcdctl --command-timeout=30s --endpoints=https://localhost:2379 defrag
sh-4.4# etcdctl --command-timeout=30s --endpoints=https://localhost:2379 defrag
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
Finished defragmenting etcd member[https://localhost:2379]
Finished defragmenting etcd member[https://localhost:2379]
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If a timeout error occurs, increase the value for
--command-timeout
until the command succeeds.Verify that the database size was reduced:
etcdctl endpoint status -w table --cluster
sh-4.4# etcdctl endpoint status -w table --cluster
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
Copy to Clipboard Copied! Toggle word wrap Toggle overflow This example shows that the database size for this etcd member is now 41 MB as opposed to the starting size of 104 MB.
Repeat these steps to connect to each of the other etcd members and defragment them. Always defragment the leader last.
Wait at least one minute between defragmentation actions to allow the etcd pod to recover. Until the etcd pod recovers, the etcd member will not respond.
If any
NOSPACE
alarms were triggered due to the space quota being exceeded, clear them.Check if there are any
NOSPACE
alarms:etcdctl alarm list
sh-4.4# etcdctl alarm list
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
memberID:12345678912345678912 alarm:NOSPACE
memberID:12345678912345678912 alarm:NOSPACE
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Clear the alarms:
etcdctl alarm disarm
sh-4.4# etcdctl alarm disarm
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
4.12.7. Restoring to a previous cluster state Copy linkLink copied to clipboard!
You can use a saved etcd
backup to restore a previous cluster state or restore a cluster that has lost the majority of control plane hosts.
If your cluster uses a control plane machine set, see "Recovering a degraded etcd Operator" in "Troubleshooting the control plane machine set" for an etcd recovery procedure.
When you restore your cluster, you must use an etcd
backup that was taken from the same z-stream release. For example, an OpenShift Container Platform 4.7.2 cluster must use an etcd
backup that was taken from 4.7.2.
Prerequisites
-
Access to the cluster as a user with the
cluster-admin
role through a certificate-basedkubeconfig
file, like the one that was used during installation. - A healthy control plane host to use as the recovery host.
- SSH access to control plane hosts.
-
A backup directory containing both the
etcd
snapshot and the resources for the static pods, which were from the same backup. The file names in the directory must be in the following formats:snapshot_<datetimestamp>.db
andstatic_kuberesources_<datetimestamp>.tar.gz
. - Nodes must be accessible or bootable.
For non-recovery control plane nodes, it is not required to establish SSH connectivity or to stop the static pods. You can delete and re-create other non-recovery, control plane machines, one by one.
Procedure
- Select a control plane host to use as the recovery host. This is the host that you will run the restore operation on.
Establish SSH connectivity to each of the control plane nodes, including the recovery host. Use a separate terminal to establish SSH connectivity for each control plane node.
The Kubernetes API server becomes inaccessible after the restore process starts, so you cannot access the control plane nodes by using the
oc debug
method. For this reason, establish SSH connectivity to each control plane host in a separate terminal.ImportantIf you do not complete this step, you will not be able to access the control plane hosts to complete the restore procedure, and you will be unable to recover your cluster from this state.
Copy the
etcd
backup directory to the recovery control plane host.This procedure assumes that you copied the
backup
directory containing theetcd
snapshot and the resources for the static pods to the/home/core/
directory of your recovery control plane host.Stop the static pods on any other control plane nodes.
NoteYou do not need to stop the static pods on the recovery host.
- Access a control plane host that is not the recovery host.
Move the existing etcd pod file out of the kubelet manifest directory by running the following command:
sudo mv -v /etc/kubernetes/manifests/etcd-pod.yaml /tmp
$ sudo mv -v /etc/kubernetes/manifests/etcd-pod.yaml /tmp
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that the
etcd
pods are stopped by running the following command:sudo crictl ps | grep etcd | egrep -v "operator|etcd-guard"
$ sudo crictl ps | grep etcd | egrep -v "operator|etcd-guard"
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If the output of this command is not empty, wait a few minutes and check again.
Move the existing
kube-apiserver
file out of the kubelet manifest directory by running the following command:sudo mv -v /etc/kubernetes/manifests/kube-apiserver-pod.yaml /tmp
$ sudo mv -v /etc/kubernetes/manifests/kube-apiserver-pod.yaml /tmp
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that the
kube-apiserver
containers are stopped by running the following command:sudo crictl ps | grep kube-apiserver | egrep -v "operator|guard"
$ sudo crictl ps | grep kube-apiserver | egrep -v "operator|guard"
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If the output of this command is not empty, wait a few minutes and check again.
Move the existing
kube-controller-manager
file out of the kubelet manifest directory by running the following command:sudo mv -v /etc/kubernetes/manifests/kube-controller-manager-pod.yaml /tmp
$ sudo mv -v /etc/kubernetes/manifests/kube-controller-manager-pod.yaml /tmp
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that the
kube-controller-manager
containers are stopped by running the following command:sudo crictl ps | grep kube-controller-manager | egrep -v "operator|guard"
$ sudo crictl ps | grep kube-controller-manager | egrep -v "operator|guard"
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If the output of this command is not empty, wait a few minutes and check again.
Move the existing
kube-scheduler
file out of the kubelet manifest directory by running the following command:sudo mv -v /etc/kubernetes/manifests/kube-scheduler-pod.yaml /tmp
$ sudo mv -v /etc/kubernetes/manifests/kube-scheduler-pod.yaml /tmp
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that the
kube-scheduler
containers are stopped by running the following command:sudo crictl ps | grep kube-scheduler | egrep -v "operator|guard"
$ sudo crictl ps | grep kube-scheduler | egrep -v "operator|guard"
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If the output of this command is not empty, wait a few minutes and check again.
Move the
etcd
data directory to a different location with the following example:sudo mv -v /var/lib/etcd/ /tmp
$ sudo mv -v /var/lib/etcd/ /tmp
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If the
/etc/kubernetes/manifests/keepalived.yaml
file exists, complete the following steps. These steps are necessary to ensure that the API IP address is listening on the recovery host.Move the
/etc/kubernetes/manifests/keepalived.yaml
file out of the kubelet manifest directory by running the following command:sudo mv -v /etc/kubernetes/manifests/keepalived.yaml /home/core/
$ sudo mv -v /etc/kubernetes/manifests/keepalived.yaml /home/core/
Copy to Clipboard Copied! Toggle word wrap Toggle overflow NoteThis file must be restored to its original location after the procedure is completed.
Verify that any containers managed by the
keepalived
daemon are stopped:sudo crictl ps --name keepalived
$ sudo crictl ps --name keepalived
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The output of this command should be empty. If it is not empty, wait a few minutes and check again.
Check if the control plane has any Virtual IPs (VIPs) assigned to it:
ip -o address | egrep '<api_vip>|<ingress_vip>'
$ ip -o address | egrep '<api_vip>|<ingress_vip>'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow For each reported VIP, run the following command to remove it:
sudo ip address del <reported_vip> dev <reported_vip_device>
$ sudo ip address del <reported_vip> dev <reported_vip_device>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
- Repeat this step on each of the other control plane hosts that is not the recovery host.
- Access the recovery control plane host.
If the
keepalived
daemon is in use, verify that the recovery control plane node owns the VIP. Otherwise, repeat step 4.xi.ip -o address | grep <api_vip>
$ ip -o address | grep <api_vip>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The address of the VIP is highlighted in the output if it exists. This command returns an empty string if the VIP is not set or configured incorrectly.
If the cluster-wide proxy is enabled, be sure that you have exported the
NO_PROXY
,HTTP_PROXY
, andHTTPS_PROXY
environment variables.TipYou can check whether the proxy is enabled by reviewing the output of
oc get proxy cluster -o yaml
. The proxy is enabled if thehttpProxy
,httpsProxy
, andnoProxy
fields have values set.Run the restore script on the recovery control plane host and pass in the path to the
etcd
backup directory:sudo -E /usr/local/bin/cluster-restore.sh /home/core/assets/backup
$ sudo -E /usr/local/bin/cluster-restore.sh /home/core/assets/backup
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example script output
Copy to Clipboard Copied! Toggle word wrap Toggle overflow The cluster-restore.sh script must show that
etcd
,kube-apiserver
,kube-controller-manager
, andkube-scheduler
pods are stopped and then started at the end of the restore process.NoteThe restore process can cause nodes to enter the
NotReady
state if the node certificates were updated after the lastetcd
backup.Check the nodes to ensure they are in the
Ready
state. To check the nodes, you can use either the bastion host or the recovery host.If you use the recovery host, run the following commands:
export KUBECONFIG=/etc/kubernetes/static-pod-resources/kube-apiserver-certs/secrets/node-kubeconfigs/localhost-recovery.kubeconfig
$ export KUBECONFIG=/etc/kubernetes/static-pod-resources/kube-apiserver-certs/secrets/node-kubeconfigs/localhost-recovery.kubeconfig
Copy to Clipboard Copied! Toggle word wrap Toggle overflow oc get nodes -w
$ oc get nodes -w
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If you use the bastion host, complete the following steps:
Run the following command:
oc get nodes -w
$ oc get nodes -w
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Sample output
Copy to Clipboard Copied! Toggle word wrap Toggle overflow It can take several minutes for all nodes to report their state.
If any nodes are in the
NotReady
state, log in to the nodes and remove all of the PEM files from the/var/lib/kubelet/pki
directory on each node. You can SSH into the nodes or use the terminal window in the web console.ssh -i <ssh-key-path> core@<master-hostname>
$ ssh -i <ssh-key-path> core@<master-hostname>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Sample
pki
directorypwd ls
sh-4.4# pwd /var/lib/kubelet/pki sh-4.4# ls kubelet-client-2022-04-28-11-24-09.pem kubelet-server-2022-04-28-11-24-15.pem kubelet-client-current.pem kubelet-server-current.pem
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Restart the kubelet service on all control plane hosts.
From the recovery host, run the following command:
sudo systemctl restart kubelet.service
$ sudo systemctl restart kubelet.service
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - Repeat this step on all other control plane hosts.
Approve the pending Certificate Signing Requests (CSRs):
NoteClusters with no worker nodes, such as single-node clusters or clusters consisting of three schedulable control plane nodes, will not have any pending CSRs to approve. You can skip all the commands listed in this step.
Get the list of current CSRs by running the following command:
oc get csr
$ oc get csr
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Review the details of a CSR to verify that it is valid by running the following command:
oc describe csr <csr_name>
$ oc describe csr <csr_name>
1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
<csr_name>
is the name of a CSR from the list of current CSRs.
Approve each valid
node-bootstrapper
CSR by running the following command:oc adm certificate approve <csr_name>
$ oc adm certificate approve <csr_name>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow For user-provisioned installations, approve each valid kubelet service CSR by running the following command:
oc adm certificate approve <csr_name>
$ oc adm certificate approve <csr_name>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Verify that the single member control plane has started successfully.
From the recovery host, verify that the
etcd
container is running by entering the following command:sudo crictl ps | grep etcd | egrep -v "operator|etcd-guard"
$ sudo crictl ps | grep etcd | egrep -v "operator|etcd-guard"
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
3ad41b7908e32 36f86e2eeaaffe662df0d21041eb22b8198e0e58abeeae8c743c3e6e977e8009 About a minute ago Running etcd 0 7c05f8af362f0
3ad41b7908e32 36f86e2eeaaffe662df0d21041eb22b8198e0e58abeeae8c743c3e6e977e8009 About a minute ago Running etcd 0 7c05f8af362f0
Copy to Clipboard Copied! Toggle word wrap Toggle overflow From the recovery host, verify that the
etcd
pod is running by entering the following command:oc -n openshift-etcd get pods -l k8s-app=etcd
$ oc -n openshift-etcd get pods -l k8s-app=etcd
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
NAME READY STATUS RESTARTS AGE etcd-ip-10-0-143-125.ec2.internal 1/1 Running 1 2m47s
NAME READY STATUS RESTARTS AGE etcd-ip-10-0-143-125.ec2.internal 1/1 Running 1 2m47s
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If the status is
Pending
, or the output lists more than one runningetcd
pod, wait a few minutes and check again.
If you are using the
OVNKubernetes
network plugin, you must restartovnkube-controlplane
pods.Delete all of the
ovnkube-controlplane
pods by running the following command:oc -n openshift-ovn-kubernetes delete pod -l app=ovnkube-control-plane
$ oc -n openshift-ovn-kubernetes delete pod -l app=ovnkube-control-plane
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that all of the
ovnkube-controlplane
pods were redeployed by running the following command:oc -n openshift-ovn-kubernetes get pod -l app=ovnkube-control-plane
$ oc -n openshift-ovn-kubernetes get pod -l app=ovnkube-control-plane
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
If you are using the OVN-Kubernetes network plugin, restart the Open Virtual Network (OVN) Kubernetes pods on all the nodes one by one. Use the following steps to restart OVN-Kubernetes pods on each node:
ImportantRestart OVN-Kubernetes pods in the following order
- The recovery control plane host
- The other control plane hosts (if available)
- The other nodes
NoteValidating and mutating admission webhooks can reject pods. If you add any additional webhooks with the
failurePolicy
set toFail
, then they can reject pods and the restoration process can fail. You can avoid this by saving and deleting webhooks while restoring the cluster state. After the cluster state is restored successfully, you can enable the webhooks again.Alternatively, you can temporarily set the
failurePolicy
toIgnore
while restoring the cluster state. After the cluster state is restored successfully, you can set thefailurePolicy
toFail
.Remove the northbound database (nbdb) and southbound database (sbdb). Access the recovery host and the remaining control plane nodes by using Secure Shell (SSH) and run the following command:
sudo rm -f /var/lib/ovn-ic/etc/*.db
$ sudo rm -f /var/lib/ovn-ic/etc/*.db
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Restart the OpenVSwitch services. Access the node by using Secure Shell (SSH) and run the following command:
sudo systemctl restart ovs-vswitchd ovsdb-server
$ sudo systemctl restart ovs-vswitchd ovsdb-server
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Delete the
ovnkube-node
pod on the node by running the following command, replacing<node>
with the name of the node that you are restarting:oc -n openshift-ovn-kubernetes delete pod -l app=ovnkube-node --field-selector=spec.nodeName==<node>
$ oc -n openshift-ovn-kubernetes delete pod -l app=ovnkube-node --field-selector=spec.nodeName==<node>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Check the status of the OVN pods by running the following command:
oc get po -n openshift-ovn-kubernetes
$ oc get po -n openshift-ovn-kubernetes
Copy to Clipboard Copied! Toggle word wrap Toggle overflow If any OVN pods are in the
Terminating
status, delete the node that is running that OVN pod by running the following command. Replace<node>
with the name of the node you are deleting:oc delete node <node>
$ oc delete node <node>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Use SSH to log in to the OVN pod node with the
Terminating
status by running the following command:ssh -i <ssh-key-path> core@<node>
$ ssh -i <ssh-key-path> core@<node>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Move all PEM files from the
/var/lib/kubelet/pki
directory by running the following command:sudo mv /var/lib/kubelet/pki/* /tmp
$ sudo mv /var/lib/kubelet/pki/* /tmp
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Restart the kubelet service by running the following command:
sudo systemctl restart kubelet.service
$ sudo systemctl restart kubelet.service
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Return to the recovery etcd machines by running the following command:
oc get csr
$ oc get csr
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Example output
NAME AGE SIGNERNAME REQUESTOR CONDITION csr-<uuid> 8m3s kubernetes.io/kubelet-serving system:node:<node_name> Pending
NAME AGE SIGNERNAME REQUESTOR CONDITION csr-<uuid> 8m3s kubernetes.io/kubelet-serving system:node:<node_name> Pending
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Approve all new CSRs by running the following command, replacing
csr-<uuid>
with the name of the CSR:oc adm certificate approve csr-<uuid>
oc adm certificate approve csr-<uuid>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Verify that the node is back by running the following command:
oc get nodes
$ oc get nodes
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Verify that the
ovnkube-node
pod is running again with:oc -n openshift-ovn-kubernetes get pod -l app=ovnkube-node --field-selector=spec.nodeName==<node>
$ oc -n openshift-ovn-kubernetes get pod -l app=ovnkube-node --field-selector=spec.nodeName==<node>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow NoteIt might take several minutes for the pods to restart.
Turn off the quorum guard by running the following command:
oc patch etcd/cluster --type=merge -p '{"spec": {"unsupportedConfigOverrides": {"useUnsupportedUnsafeNonHANonProductionUnstableEtcd": true}}}'
$ oc patch etcd/cluster --type=merge -p '{"spec": {"unsupportedConfigOverrides": {"useUnsupportedUnsafeNonHANonProductionUnstableEtcd": true}}}'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow This command ensures that you can successfully re-create secrets and roll out the static pods.
If not yet defined, in a separate terminal window within the recovery host, export the recovery
kubeconfig
file by running the following command:export KUBECONFIG=/etc/kubernetes/static-pod-resources/kube-apiserver-certs/secrets/node-kubeconfigs/localhost-recovery.kubeconfig
$ export KUBECONFIG=/etc/kubernetes/static-pod-resources/kube-apiserver-certs/secrets/node-kubeconfigs/localhost-recovery.kubeconfig
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Force
etcd
redeployment.In the same terminal window where you exported the recovery
kubeconfig
file, run the following command:oc patch etcd cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$( date --rfc-3339=ns )"'"}}' --type=merge
$ oc patch etcd cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$( date --rfc-3339=ns )"'"}}' --type=merge
1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- The
forceRedeploymentReason
value must be unique, which is why a timestamp is appended.
The
etcd
redeployment starts.When the
etcd
cluster Operator performs a redeployment, the existing nodes are started with new pods similar to the initial bootstrap scale up.Turn the quorum guard back on by running the following command:
oc patch etcd/cluster --type=merge -p '{"spec": {"unsupportedConfigOverrides": null}}'
$ oc patch etcd/cluster --type=merge -p '{"spec": {"unsupportedConfigOverrides": null}}'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow You can verify that the
unsupportedConfigOverrides
section is removed from the object by running the following command:oc get etcd/cluster -oyaml
$ oc get etcd/cluster -oyaml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Verify all nodes are updated to the latest revision.
In a terminal that has access to the cluster as a
cluster-admin
user, run the following command:oc get etcd -o=jsonpath='{range .items[0].status.conditions[?(@.type=="NodeInstallerProgressing")]}{.reason}{"\n"}{.message}{"\n"}'
$ oc get etcd -o=jsonpath='{range .items[0].status.conditions[?(@.type=="NodeInstallerProgressing")]}{.reason}{"\n"}{.message}{"\n"}'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Review the
NodeInstallerProgressing
status condition foretcd
to verify that all nodes are at the latest revision. The output showsAllNodesAtLatestRevision
upon successful update:AllNodesAtLatestRevision 3 nodes are at revision 7
AllNodesAtLatestRevision 3 nodes are at revision 7
1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- In this example, the latest revision number is
7
.
If the output includes multiple revision numbers, such as
2 nodes are at revision 6; 1 nodes are at revision 7
, this means that the update is still in progress. Wait a few minutes and try again.After
etcd
is redeployed, force new rollouts for the control plane.kube-apiserver
will reinstall itself on the other nodes because the kubelet is connected to API servers using an internal load balancer.In a terminal that has access to the cluster as a
cluster-admin
user, complete the following steps:Force a new rollout for
kube-apiserver
:oc patch kubeapiserver cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$( date --rfc-3339=ns )"'"}}' --type=merge
$ oc patch kubeapiserver cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$( date --rfc-3339=ns )"'"}}' --type=merge
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Verify all nodes are updated to the latest revision.
oc get kubeapiserver -o=jsonpath='{range .items[0].status.conditions[?(@.type=="NodeInstallerProgressing")]}{.reason}{"\n"}{.message}{"\n"}'
$ oc get kubeapiserver -o=jsonpath='{range .items[0].status.conditions[?(@.type=="NodeInstallerProgressing")]}{.reason}{"\n"}{.message}{"\n"}'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Review the
NodeInstallerProgressing
status condition to verify that all nodes are at the latest revision. The output showsAllNodesAtLatestRevision
upon successful update:AllNodesAtLatestRevision 3 nodes are at revision 7
AllNodesAtLatestRevision 3 nodes are at revision 7
1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- In this example, the latest revision number is
7
.
If the output includes multiple revision numbers, such as
2 nodes are at revision 6; 1 nodes are at revision 7
, this means that the update is still in progress. Wait a few minutes and try again.Force a new rollout for the Kubernetes controller manager by running the following command:
oc patch kubecontrollermanager cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$( date --rfc-3339=ns )"'"}}' --type=merge
$ oc patch kubecontrollermanager cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$( date --rfc-3339=ns )"'"}}' --type=merge
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Verify all nodes are updated to the latest revision by running the following command:
oc get kubecontrollermanager -o=jsonpath='{range .items[0].status.conditions[?(@.type=="NodeInstallerProgressing")]}{.reason}{"\n"}{.message}{"\n"}'
$ oc get kubecontrollermanager -o=jsonpath='{range .items[0].status.conditions[?(@.type=="NodeInstallerProgressing")]}{.reason}{"\n"}{.message}{"\n"}'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Review the
NodeInstallerProgressing
status condition to verify that all nodes are at the latest revision. The output showsAllNodesAtLatestRevision
upon successful update:AllNodesAtLatestRevision 3 nodes are at revision 7
AllNodesAtLatestRevision 3 nodes are at revision 7
1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- In this example, the latest revision number is
7
.
If the output includes multiple revision numbers, such as
2 nodes are at revision 6; 1 nodes are at revision 7
, this means that the update is still in progress. Wait a few minutes and try again.Force a new rollout for the
kube-scheduler
by running the following command:oc patch kubescheduler cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$( date --rfc-3339=ns )"'"}}' --type=merge
$ oc patch kubescheduler cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$( date --rfc-3339=ns )"'"}}' --type=merge
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Verify all nodes are updated to the latest revision by running the following command:
oc get kubescheduler -o=jsonpath='{range .items[0].status.conditions[?(@.type=="NodeInstallerProgressing")]}{.reason}{"\n"}{.message}{"\n"}'
$ oc get kubescheduler -o=jsonpath='{range .items[0].status.conditions[?(@.type=="NodeInstallerProgressing")]}{.reason}{"\n"}{.message}{"\n"}'
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Review the
NodeInstallerProgressing
status condition to verify that all nodes are at the latest revision. The output showsAllNodesAtLatestRevision
upon successful update:AllNodesAtLatestRevision 3 nodes are at revision 7
AllNodesAtLatestRevision 3 nodes are at revision 7
1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- In this example, the latest revision number is
7
.
If the output includes multiple revision numbers, such as
2 nodes are at revision 6; 1 nodes are at revision 7
, this means that the update is still in progress. Wait a few minutes and try again.
If the
keepalived
daemon is in use, restore the configuration on the control plane nodes other than the recovery host by running the following command. Otherwise, the network operator will not advance beyond the "Progressing" state.sudo cp -v /home/core/keepalived.yaml /etc/kubernetes/manifests/
$ sudo cp -v /home/core/keepalived.yaml /etc/kubernetes/manifests/
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Monitor the platform Operators by running the following command:
oc adm wait-for-stable-cluster
$ oc adm wait-for-stable-cluster
Copy to Clipboard Copied! Toggle word wrap Toggle overflow This process can take up to 15 minutes.
To ensure that all workloads return to normal operation following a recovery procedure, restart all the control plane nodes.
NoteOn completion of the previous procedural steps, you might need to wait a few minutes for all services to return to their restored state. For example, authentication by using
oc login
might not immediately work until the OAuth server pods are restarted.Consider using the
system:admin
kubeconfig
file for immediate authentication. This method basis its authentication on SSL/TLS client certificates as against OAuth tokens. You can authenticate with this file by issuing the following command:export KUBECONFIG=<installation_directory>/auth/kubeconfig
$ export KUBECONFIG=<installation_directory>/auth/kubeconfig
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Issue the following command to display your authenticated user name:
oc whoami
$ oc whoami
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - Restart all the worker nodes in a rolling fashion.
4.12.8. Issues and workarounds for restoring a persistent storage state Copy linkLink copied to clipboard!
If your OpenShift Container Platform cluster uses persistent storage of any form, a state of the cluster is typically stored outside etcd. It might be an Elasticsearch cluster running in a pod or a database running in a StatefulSet
object. When you restore from an etcd backup, the status of the workloads in OpenShift Container Platform is also restored. However, if the etcd snapshot is old, the status might be invalid or outdated.
The contents of persistent volumes (PVs) are never part of the etcd snapshot. When you restore an OpenShift Container Platform cluster from an etcd snapshot, non-critical workloads might gain access to critical data, or vice-versa.
The following are some example scenarios that produce an out-of-date status:
- MySQL database is running in a pod backed up by a PV object. Restoring OpenShift Container Platform from an etcd snapshot does not bring back the volume on the storage provider, and does not produce a running MySQL pod, despite the pod repeatedly attempting to start. You must manually restore this pod by restoring the volume on the storage provider, and then editing the PV to point to the new volume.
- Pod P1 is using volume A, which is attached to node X. If the etcd snapshot is taken while another pod uses the same volume on node Y, then when the etcd restore is performed, pod P1 might not be able to start correctly due to the volume still being attached to node Y. OpenShift Container Platform is not aware of the attachment, and does not automatically detach it. When this occurs, the volume must be manually detached from node Y so that the volume can attach on node X, and then pod P1 can start.
- Cloud provider or storage provider credentials were updated after the etcd snapshot was taken. This causes any CSI drivers or Operators that depend on the those credentials to not work. You might have to manually update the credentials required by those drivers or Operators.
A device is removed or renamed from OpenShift Container Platform nodes after the etcd snapshot is taken. The Local Storage Operator creates symlinks for each PV that it manages from
/dev/disk/by-id
or/dev
directories. This situation might cause the local PVs to refer to devices that no longer exist.To fix this problem, an administrator must:
- Manually remove the PVs with invalid devices.
- Remove symlinks from respective nodes.
-
Delete
LocalVolume
orLocalVolumeSet
objects (see StorageConfiguring persistent storage Persistent storage using local volumes Deleting the Local Storage Operator Resources).
4.13. Pod disruption budgets Copy linkLink copied to clipboard!
Understand and configure pod disruption budgets.
4.13.1. Understanding how to use pod disruption budgets to specify the number of pods that must be up Copy linkLink copied to clipboard!
A pod disruption budget allows the specification of safety constraints on pods during operations, such as draining a node for maintenance.
PodDisruptionBudget
is an API object that specifies the minimum number or percentage of replicas that must be up at a time. Setting these in projects can be helpful during node maintenance (such as scaling a cluster down or a cluster upgrade) and is only honored on voluntary evictions (not on node failures).
A PodDisruptionBudget
object’s configuration consists of the following key parts:
- A label selector, which is a label query over a set of pods.
An availability level, which specifies the minimum number of pods that must be available simultaneously, either:
-
minAvailable
is the number of pods must always be available, even during a disruption. -
maxUnavailable
is the number of pods can be unavailable during a disruption.
-
Available
refers to the number of pods that has condition Ready=True
. Ready=True
refers to the pod that is able to serve requests and should be added to the load balancing pools of all matching services.
A maxUnavailable
of 0%
or 0
or a minAvailable
of 100%
or equal to the number of replicas is permitted but can block nodes from being drained.
The default setting for maxUnavailable
is 1
for all the machine config pools in OpenShift Container Platform. It is recommended to not change this value and update one control plane node at a time. Do not change this value to 3
for the control plane pool.
You can check for pod disruption budgets across all projects with the following:
oc get poddisruptionbudget --all-namespaces
$ oc get poddisruptionbudget --all-namespaces
The following example contains some values that are specific to OpenShift Container Platform on AWS.
Example output
The PodDisruptionBudget
is considered healthy when there are at least minAvailable
pods running in the system. Every pod above that limit can be evicted.
Depending on your pod priority and preemption settings, lower-priority pods might be removed despite their pod disruption budget requirements.
4.13.2. Specifying the number of pods that must be up with pod disruption budgets Copy linkLink copied to clipboard!
You can use a PodDisruptionBudget
object to specify the minimum number or percentage of replicas that must be up at a time.
Procedure
To configure a pod disruption budget:
Create a YAML file with the an object definition similar to the following:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
PodDisruptionBudget
is part of thepolicy/v1
API group.- 2
- The minimum number of pods that must be available simultaneously. This can be either an integer or a string specifying a percentage, for example,
20%
. - 3
- A label query over a set of resources. The result of
matchLabels
andmatchExpressions
are logically conjoined. Leave this parameter blank, for exampleselector {}
, to select all pods in the project.
Or:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
PodDisruptionBudget
is part of thepolicy/v1
API group.- 2
- The maximum number of pods that can be unavailable simultaneously. This can be either an integer or a string specifying a percentage, for example,
20%
. - 3
- A label query over a set of resources. The result of
matchLabels
andmatchExpressions
are logically conjoined. Leave this parameter blank, for exampleselector {}
, to select all pods in the project.
Run the following command to add the object to project:
oc create -f </path/to/file> -n <project_name>
$ oc create -f </path/to/file> -n <project_name>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
4.13.3. Specifying the eviction policy for unhealthy pods Copy linkLink copied to clipboard!
When you use pod disruption budgets (PDBs) to specify how many pods must be available simultaneously, you can also define the criteria for how unhealthy pods are considered for eviction.
You can choose one of the following policies:
- IfHealthyBudget
- Running pods that are not yet healthy can be evicted only if the guarded application is not disrupted.
- AlwaysAllow
Running pods that are not yet healthy can be evicted regardless of whether the criteria in the pod disruption budget is met. This policy can help evict malfunctioning applications, such as ones with pods stuck in the
CrashLoopBackOff
state or failing to report theReady
status.NoteIt is recommended to set the
unhealthyPodEvictionPolicy
field toAlwaysAllow
in thePodDisruptionBudget
object to support the eviction of misbehaving applications during a node drain. The default behavior is to wait for the application pods to become healthy before the drain can proceed.
Procedure
Create a YAML file that defines a
PodDisruptionBudget
object and specify the unhealthy pod eviction policy:Example
pod-disruption-budget.yaml
fileCopy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- Choose either
IfHealthyBudget
orAlwaysAllow
as the unhealthy pod eviction policy. The default isIfHealthyBudget
when theunhealthyPodEvictionPolicy
field is empty.
Create the
PodDisruptionBudget
object by running the following command:oc create -f pod-disruption-budget.yaml
$ oc create -f pod-disruption-budget.yaml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
With a PDB that has the AlwaysAllow
unhealthy pod eviction policy set, you can now drain nodes and evict the pods for a malfunctioning application guarded by this PDB.