6.3. 管理节点

OpenShift Container Platform 使用 KubeletConfig 自定义资源(CR)来管理节点的配置。通过创建 KubeletConfig 对象的实例,会创建一个受管机器配置来覆盖节点上的设置。

注意

不支持为更改配置而登录远程机器。

6.3.1. 修改节点

要对集群或机器池进行配置更改,您必须创建自定义资源定义(CRD)或 kubeletConfig 对象。OpenShift Container Platform 使用 Machine Config Controller 来监控是否通过 CRD 进行了更改,以将更改应用到集群。

注意

因为 kubeletConfig 对象中的字段直接从上游 Kubernetes 传递给 kubelet,所以对这些字段的验证直接由 kubelet 本身处理。有关这些字段的有效值,请参阅相关的 Kubernetes 文档。kubeletConfig 对象中的无效值可能会导致集群节点不可用。

流程

  1. 为您要配置的节点类型,获取与静态 CRD (Machine Config Pool) 关联的标签。执行以下步骤之一:

    1. 检查所需机器配置池的当前标签。

      例如:

      $  oc get machineconfigpool  --show-labels

      输出示例

      NAME      CONFIG                                             UPDATED   UPDATING   DEGRADED   LABELS
      master    rendered-master-e05b81f5ca4db1d249a1bf32f9ec24fd   True      False      False      operator.machineconfiguration.openshift.io/required-for-upgrade=
      worker    rendered-worker-f50e78e1bc06d8e82327763145bfcf62   True      False      False

    2. 为所需的机器配置池添加自定义标签。

      例如:

      $ oc label machineconfigpool worker custom-kubelet=enabled
  2. 为您的配置更改创建一个 kubeletconfig 自定义资源(CR)。

    例如:

    custom-config CR 配置示例

    apiVersion: machineconfiguration.openshift.io/v1
    kind: KubeletConfig
    metadata:
      name: custom-config 1
    spec:
      machineConfigPoolSelector:
        matchLabels:
          custom-kubelet: enabled 2
      kubeletConfig: 3
        podsPerCore: 10
        maxPods: 250
        systemReserved:
          cpu: 2000m
          memory: 1Gi
    #...

    1
    为 CR 分配一个名称。
    2
    指定要应用配置更改的标签,这是您添加到机器配置池中的标签。
    3
    指定要更改的新值。
  3. 创建 CR 对象。

    $ oc create -f <file-name>

    例如:

    $ oc create -f master-kube-config.yaml

大多数 Kubelet 配置选项 可由用户设置。不允许覆盖下列选项:

  • CgroupDriver
  • ClusterDNS
  • ClusterDomain
  • StaticPodPath
注意

如果单个节点包含超过 50 个镜像,pod 调度可能会在节点间进行平衡。这是因为节点上的镜像列表默认简写为 50。您可以通过编辑 KubeletConfig 对象来禁用镜像限制,并将 nodeStatusMaxImages 的值设置为 -1

6.3.2. 将 control plane 节点配置为可以调度

您可以将 control plane 节点配置为可以调度,这意味着允许在 master 节点上放置新的 pod。默认情况下,control plane 节点不可调度。

您可以将 master 设置为可调度,但必须保留 worker 节点。

注意

您可以在裸机集群中部署没有 worker 节点的 OpenShift Container Platform。在这种情况下,control plane 节点会被标记为可以调度。

您可以通过配置 mastersSchedulable 字段来允许或禁止调度 control plane 节点。

重要

当您将 control plane 节点从默认的不可调度配置为可以调度时,需要额外的订阅。这是因为 control plane 节点随后变为 worker 节点。

流程

  1. 编辑 schedulers.config.openshift.io 资源。

    $ oc edit schedulers.config.openshift.io cluster
  2. 配置 mastersSchedulable 字段。

    apiVersion: config.openshift.io/v1
    kind: Scheduler
    metadata:
      creationTimestamp: "2019-09-10T03:04:05Z"
      generation: 1
      name: cluster
      resourceVersion: "433"
      selfLink: /apis/config.openshift.io/v1/schedulers/cluster
      uid: a636d30a-d377-11e9-88d4-0a60097bee62
    spec:
      mastersSchedulable: false 1
    status: {}
    #...
    1
    设置为 true 以允许调度 control plane 节点,或设置为 false 以禁止调度 control plane 节点。
  3. 保存文件以使改变生效。

6.3.3. 设置 SELinux 布尔值

OpenShift Container Platform 允许您在 Red Hat Enterprise Linux CoreOS (RHCOS) 节点上启用和禁用 SELinux 布尔值。以下流程解释了如何使用 Machine Config Operator (MCO) 修改节点上的 SELinux 布尔值。此流程使用 container_manage_cgroup 作为示例布尔值。您可以将这个值修改为您需要的任何布尔值。

先决条件

  • 已安装 OpenShift CLI(oc)。

流程

  1. 使用 MachineConfig 对象创建新 YAML 文件,如下例所示:

    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfig
    metadata:
      labels:
        machineconfiguration.openshift.io/role: worker
      name: 99-worker-setsebool
    spec:
      config:
        ignition:
          version: 3.2.0
        systemd:
          units:
          - contents: |
              [Unit]
              Description=Set SELinux booleans
              Before=kubelet.service
    
              [Service]
              Type=oneshot
              ExecStart=/sbin/setsebool container_manage_cgroup=on
              RemainAfterExit=true
    
              [Install]
              WantedBy=multi-user.target graphical.target
            enabled: true
            name: setsebool.service
    #...
  2. 运行以下命令来创建新的 MachineConfig 对象:

    $ oc create -f 99-worker-setsebool.yaml
注意

MachineConfig 对象应用任何更改将导致所有受影响的节点在应用更改后安全重启。

6.3.4. 为节点添加内核参数

在一些特殊情况下,您可能需要为集群中的一组节点添加内核参数。进行此操作时应小心谨慎,而且您必须先清楚了解所设参数的影响。

警告

不当使用内核参数会导致系统变得无法引导。

您可以设置的内核参数示例包括:

  • nosmt:在内核中禁用对称多线程 (SMT)。多线程允许每个 CPU 有多个逻辑线程。您可以在多租户环境中考虑使用 nosmt,以减少潜在的跨线程攻击风险。禁用 SMT 在本质上相当于选择安全性而非性能。
  • systemd.unified_cgroup_hierarchy:启用 Linux 控制组版本 2 (cgroup v2)。cgroup v2 是内核控制组的下一个版本,它包括了多个改进。

    重要

    OpenShift Container Platform cgroups 版本 2 支持只是一个技术预览功能。技术预览功能不受红帽产品服务等级协议(SLA)支持,且功能可能并不完整。红帽不推荐在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。

    有关红帽技术预览功能支持范围的更多信息,请参阅技术预览功能支持范围

  • Enforcing=0:将 Security Enhanced Linux(SELinux)配置为以 permissive 模式运行。在 permissive 模式中,系统会象 enforcing 模式一样加载安全策略,包括标记对象并在日志中记录访问拒绝条目,但它并不会拒绝任何操作。虽然不建议在生产环境系统中使用 permissive 模式,但 permissive 模式会有助于调试。

    警告

    不支持在生产环境中禁用 RHCOS 上的 SELinux。在节点上禁用 SELinux 后,必须在生产集群中重新设置前重新置备它。

如需内核参数的列表和描述,请参阅 Kernel.org 内核参数

在以下流程中,您要创建一个用于标识以下内容的 MachineConfig 对象:

  • 您要添加内核参数的一组机器。本例中为具有 worker 角色的机器。
  • 附加到现有内核参数末尾的内核参数。
  • 指示机器配置列表中应用更改的位置的标签。

先决条件

  • 具有正常运行的 OpenShift Container Platform 集群的管理特权。

流程

  1. 列出 OpenShift Container Platform 集群的现有 MachineConfig 对象,以确定如何标记您的机器配置:

    $ oc get MachineConfig

    输出示例

    NAME                                               GENERATEDBYCONTROLLER                      IGNITIONVERSION   AGE
    00-master                                          52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    00-worker                                          52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    01-master-container-runtime                        52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    01-master-kubelet                                  52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    01-worker-container-runtime                        52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    01-worker-kubelet                                  52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    99-master-generated-registries                     52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    99-master-ssh                                                                                 3.2.0             40m
    99-worker-generated-registries                     52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    99-worker-ssh                                                                                 3.2.0             40m
    rendered-master-23e785de7587df95a4b517e0647e5ab7   52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    rendered-worker-5d596d9293ca3ea80c896a1191735bb1   52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m

  2. 创建一个用于标识内核参数的 MachineConfig 对象文件(例如 05-worker-kernelarg-selinuxpermissive.yaml

    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfig
    metadata:
      labels:
        machineconfiguration.openshift.io/role: worker1
      name: 05-worker-kernelarg-selinuxpermissive2
    spec:
      kernelArguments:
        - enforcing=03
    1
    仅将新内核参数应用到 worker 节点。
    2
    用于标识它插入到机器配置中的什么位置(05)以及发挥什么作用(添加一个内核参数来配置 SELinux permissive 模式)。
    3
    将确切的内核参数标识为 enforcing=0
  3. 创建新机器配置:

    $ oc create -f 05-worker-kernelarg-selinuxpermissive.yaml
  4. 检查机器配置以查看是否添加了新配置:

    $ oc get MachineConfig

    输出示例

    NAME                                               GENERATEDBYCONTROLLER                      IGNITIONVERSION   AGE
    00-master                                          52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    00-worker                                          52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    01-master-container-runtime                        52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    01-master-kubelet                                  52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    01-worker-container-runtime                        52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    01-worker-kubelet                                  52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    05-worker-kernelarg-selinuxpermissive                                                         3.2.0             105s
    99-master-generated-registries                     52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    99-master-ssh                                                                                 3.2.0             40m
    99-worker-generated-registries                     52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    99-worker-ssh                                                                                 3.2.0             40m
    rendered-master-23e785de7587df95a4b517e0647e5ab7   52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m
    rendered-worker-5d596d9293ca3ea80c896a1191735bb1   52dd3ba6a9a527fc3ab42afac8d12b693534c8c9   3.2.0             33m

  5. 检查节点:

    $ oc get nodes

    输出示例

    NAME                           STATUS                     ROLES    AGE   VERSION
    ip-10-0-136-161.ec2.internal   Ready                      worker   28m   v1.25.0
    ip-10-0-136-243.ec2.internal   Ready                      master   34m   v1.25.0
    ip-10-0-141-105.ec2.internal   Ready,SchedulingDisabled   worker   28m   v1.25.0
    ip-10-0-142-249.ec2.internal   Ready                      master   34m   v1.25.0
    ip-10-0-153-11.ec2.internal    Ready                      worker   28m   v1.25.0
    ip-10-0-153-150.ec2.internal   Ready                      master   34m   v1.25.0

    您可以发现,在应用更改时每个 worker 节点上的调度都会被禁用。

  6. 前往其中一个 worker 节点并列出内核命令行参数(主机上的 /proc/cmdline 中),以检查内核参数确实已发挥作用:

    $ oc debug node/ip-10-0-141-105.ec2.internal

    输出示例

    Starting pod/ip-10-0-141-105ec2internal-debug ...
    To use host binaries, run `chroot /host`
    
    sh-4.2# cat /host/proc/cmdline
    BOOT_IMAGE=/ostree/rhcos-... console=tty0 console=ttyS0,115200n8
    rootflags=defaults,prjquota rw root=UUID=fd0... ostree=/ostree/boot.0/rhcos/16...
    coreos.oem.id=qemu coreos.oem.id=ec2 ignition.platform.id=ec2 enforcing=0
    
    sh-4.2# exit

    您应看到 enforcing=0 参数已添加至其他内核参数。

6.3.5. 在节点上启用交换内存使用

重要

在节点上启用交换内存只是一个技术预览功能。技术预览功能不受红帽产品服务等级协议(SLA)支持,且功能可能并不完整。红帽不推荐在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。

有关红帽技术预览功能支持范围的更多信息,请参阅技术预览功能支持范围

您可以根据节点为 OpenShift Container Platform 工作负载启用交换内存使用。

警告

启用交换内存可能会对工作负载性能和资源不足处理造成负面影响。不要在 control plane 节点上启用交换内存。

要启用交换内存,请创建一个 kubeletconfig 自定义资源(CR)来设置 swapbehavior 参数。您可以设置有限或无限的交换内存:

  • 有限:使用 LimitedSwap 值来限制可以使用的交换内存工作负载量。任何不是由 OpenShift Container Platform 管理的节点上的工作负载都可以使用交换内存。LimitedSwap 行为取决于节点是否使用 Linux 控制组 版本 1(cgroups v1)版本 2(cgroup v2) 运行:

    • cgroup v1:OpenShift Container Platform 工作负载可以使用内存和交换的任意组合(如果设置)到 pod 的内存限值。
    • cgroup v2:OpenShift Container Platform 工作负载无法使用交换内存。
  • 无限:使用 UnlimitedSwap 值来允许工作负载在请求时尽可能多地使用 swap 内存,最多使用系统限制。

由于 kubelet 在没有此配置的情况下不会启动交换内存,因此您必须在 OpenShift Container Platform 中启用交换内存前在节点上启用交换内存。如果节点上没有交换内存,则在 OpenShift Container Platform 中启用交换内存不会起作用。

先决条件

  • 您有一个正在运行的 OpenShift Container Platform 集群,它使用版本 4.10 或更高版本。
  • 以具有管理特权的用户身份登录集群。
  • 您已在集群中启用了 TechPreviewNoUpgrade 功能集(请参阅 Nodes → Working with cluster → Enabling features using feature gates)。

    注意

    启用 TechPreviewNoUpgrade 功能集将无法撤消,并防止次版本更新。不建议在生产环境集群中使用这些功能集。

  • 如果节点上启用了 cgroup v2,则必须通过设置 swapaccount=1 内核参数来启用节点上的交换核算。

流程

  1. 对要允许交换内存的机器配置池应用自定义标签。

    $ oc label machineconfigpool worker kubelet-swap=enabled
  2. 创建自定义资源(CR)来启用和配置 swap 设置。

    apiVersion: machineconfiguration.openshift.io/v1
    kind: KubeletConfig
    metadata:
      name: swap-config
    spec:
      machineConfigPoolSelector:
        matchLabels:
          kubelet-swap: enabled
      kubeletConfig:
        failSwapOn: false 1
        memorySwap:
          swapBehavior: LimitedSwap 2
    #...
    1
    设置为 false,以在关联的节点上启用交换内存使用。设置为 true 可禁用交换内存使用。
    2
    指定交换内存行为。如果未指定,则默认值为 LimitedSwap
  3. 在机器上启用交换内存。

6.3.6. 将 control plane 节点从一个 RHOSP 主机迁移到另一个 RHOSP 主机

您可以运行将 control plane 节点从一个 Red Hat OpenStack Platform(RHOSP)节点移至另一个脚本。

先决条件

  • 环境变量 OS_CLOUD 是对在 clouds.yaml 文件中具有管理凭证的 clouds 条目的引用。
  • 环境变量 KUBECONFIG 是指包含管理 OpenShift Container Platform 凭证的配置。

流程

  • 在命令行中运行以下命令:
#!/usr/bin/env bash

set -Eeuo pipefail

if [ $# -lt 1 ]; then
	echo "Usage: '$0 node_name'"
	exit 64
fi

# Check for admin OpenStack credentials
openstack server list --all-projects >/dev/null || { >&2 echo "The script needs OpenStack admin credentials. Exiting"; exit 77; }

# Check for admin OpenShift credentials
oc adm top node >/dev/null || { >&2 echo "The script needs OpenShift admin credentials. Exiting"; exit 77; }

set -x

declare -r node_name="$1"
declare server_id
server_id="$(openstack server list --all-projects -f value -c ID -c Name | grep "$node_name" | cut -d' ' -f1)"
readonly server_id

# Drain the node
oc adm cordon "$node_name"
oc adm drain "$node_name" --delete-emptydir-data --ignore-daemonsets --force

# Power off the server
oc debug "node/${node_name}" -- chroot /host shutdown -h 1

# Verify the server is shut off
until openstack server show "$server_id" -f value -c status | grep -q 'SHUTOFF'; do sleep 5; done

# Migrate the node
openstack server migrate --wait "$server_id"

# Resize the VM
openstack server resize confirm "$server_id"

# Wait for the resize confirm to finish
until openstack server show "$server_id" -f value -c status | grep -q 'SHUTOFF'; do sleep 5; done

# Restart the VM
openstack server start "$server_id"

# Wait for the node to show up as Ready:
until oc get node "$node_name" | grep -q "^${node_name}[[:space:]]\+Ready"; do sleep 5; done

# Uncordon the node
oc adm uncordon "$node_name"

# Wait for cluster operators to stabilize
until oc get co -o go-template='statuses: {{ range .items }}{{ range .status.conditions }}{{ if eq .type "Degraded" }}{{ if ne .status "False" }}DEGRADED{{ end }}{{ else if eq .type "Progressing"}}{{ if ne .status "False" }}PROGRESSING{{ end }}{{ else if eq .type "Available"}}{{ if ne .status "True" }}NOTAVAILABLE{{ end }}{{ end }}{{ end }}{{ end }}' | grep -qv '\(DEGRADED\|PROGRESSING\|NOTAVAILABLE\)'; do sleep 5; done

如果脚本完成,control plane 机器将迁移到一个新的 RHOSP 节点。