在具有三个 master 或 control plane 节点的大型高密度集群中,当其中一个节点停止、重启或失败时,CPU 和内存用量将会激增。故障可能是因为电源、网络或底层基础架构出现意外问题,除了在关闭集群后重启集群以节约成本的情况下。其余两个 control plane 节点必须处理负载才能高度可用,从而增加资源使用量。另外,在升级过程中还会有这个预期,因为 master 被封锁、排空并按顺序重新引导,以应用操作系统更新以及 control plane Operator 更新。为了避免级联失败,请将 control plane 节点上的总体 CPU 和内存资源使用量保留为最多 60% 的所有可用容量,以处理资源使用量激增。相应地增加 control plane 节点上的 CPU 和内存,以避免因为缺少资源而造成潜在的停机。
节点大小取决于集群中的节点和对象数量。它还取决于集群上是否正在主动创建这些对象。在创建对象时,control plane 在资源使用量方面与对象处于
运行(running)
阶段的时间相比更活跃。
如果使用安装程序置备的基础架构安装方法,则无法修改正在运行的 OpenShift Container Platform 4.7 集群中的 control plane 节点大小。反之,您必须估计节点总数并在安装过程中使用推荐的 control plane 节点大小。
建议基于在带有 OpenShiftSDN 作为网络插件的 OpenShift Container Platform 集群上捕获的数据点。
在 OpenShift Container Platform 4.7 中,与 OpenShift Container Platform 3.11 及之前的版本相比,系统现在默认保留半个 CPU 内核(500 millicore)。确定大小时应该考虑这一点。
2.4.1. 增加 Amazon Web Services(AWS)master 实例的类别大小
当您在集群中过载 AWS master 节点并且 master 节点需要更多资源时,您可以增加 master 实例的类别文件大小。
建议您在增大 AWS master 实例的类别大小前备份 etcd。
AWS 上有一个 IPI(安装程序置备的基础架构)或 UPI(用户置备的基础架构)集群。
打开 AWS 控制台,获取 master 实例。
停止一个 master 实例。
选择已停止的实例,然后点
Actions
→
Instance Settings
→
Change instance type
。
将实例更改为较大的类型,确保类型与之前选择相同,并应用更改。例如,您可以将
m5.xlarge
更改为
m5.2xlarge
或
m5.4xlarge
。
备份实例,再对下一个 master 实例重复上述步骤。
备份 etcd
对于大型高密度的集群,如果键空间增长过大并超过空间配额,etcd 的性能将会受到影响。定期维护和碎片 etcd 释放数据存储中的空间。监控 Prometheus 以了解 etcd 指标数据,并在需要时对其进行碎片处理;否则,etcd 可能会引发一个集群范围的警报,使集群进入维护模式,以只接受键读和删除。
输出会报告磁盘是否足够快来托管 etcd,它会比较从运行中捕获的 fsync 指标的 p99,以查看它是否小于 10 ms。
因为 etcd 在所有成员间复制请求,所以其性能会严重依赖于网络输入/输出(I/O)延迟。大量网络延迟会导致 etcd heartbeat 的时间比选举超时时间更长,这会导致对集群造成破坏的领导选举机制。在部署的 OpenShift Container Platform 集群上监控的一个关键指标是每个 etcd 集群成员上的 etcd 网络对延迟的 p99 百分比。使用 Prometheus 跟踪指标数据。
histogram_quantile(0.99, rate(etcd_network_peer_round_trip_time_seconds_bucket[2m])
指标报告 etcd 在成员间复制客户端请求的时间。确保它小于 50 ms。
在 etcd 历史记录压缩和其他事件后,必须定期执行手动清除碎片以便重新声明磁盘空间。
历史压缩将自动每五分钟执行一次,并在后端数据库中造成混乱。此碎片空间可供 etcd 使用,但主机文件系统不可用。您必须对碎片 etcd 进行碎片清除,才能使这个空间可供主机文件系统使用。
因为 etcd 将数据写入磁盘,所以其性能主要取决于磁盘性能。根据您的集群的具体情况,考虑每个月清理一次 etcd 碎片,或每个月清理两次。您还可以监控
etcd_db_total_size_in_bytes
指标,以确定是否需要进行碎片操作。
分离 etcd 是一个阻止性操作。在进行碎片处理完成前,etcd 成员不会响应。因此,在每个下一个 pod 要进行碎片清理前,至少等待一分钟,以便集群可以恢复正常工作。
按照以下步骤对每个 etcd 成员上的 etcd 数据进行碎片处理。
您可以使用具有
cluster-admin
角色的用户访问集群。
确定哪个 etcd 成员是领导成员,因为领导会进行最后的碎片处理。
获取 etcd pod 列表:
$ oc get pods -n openshift-etcd -o wide | grep -v quorum-guard | grep etcd
2.7. OpenShift Container Platform 基础架构组件
以下基础架构工作负载不会导致 OpenShift Container Platform worker 订阅:
在主控机上运行的 Kubernetes 和 OpenShift Container Platform control plane 服务
默认路由器
集成的容器镜像 registry
基于 HAProxy 的 Ingress Controller
集群指标集合或监控服务,包括监控用户定义的项目的组件
集群聚合日志
Red Hat Quay
Red Hat OpenShift Container Storage
Red Hat Advanced Cluster Manager
Red Hat Advanced Cluster Security for Kubernetes
Red Hat OpenShift GitOps
Red Hat OpenShift Pipelines
运行任何其他容器、Pod 或组件的所有节点都需要是您的订阅可涵盖的 worker 节点。
有关基础架构节点以及可在基础架构节点上运行,请参阅
OpenShift sizing and subscription guide for enterprise Kubernetes
文档中的 "Red Hat OpenShift control plane and infrastructure nodes"部分。
默认情况下,部署包含 Prometheus、Grafana 和 AlertManager 的 Prometheus Cluster Monitoring 堆栈来提供集群监控功能。它由 Cluster Monitoring Operator 进行管理。若要将其组件移到其他机器上,需要创建并应用自定义配置映射。
将以下
ConfigMap
定义保存为
cluster-monitoring-configmap.yaml
文件:
apiVersion: v1
kind: ConfigMap
metadata:
name: cluster-monitoring-config
namespace: openshift-monitoring
data:
config.yaml: |+
alertmanagerMain:
nodeSelector:
node-role.kubernetes.io/infra: ""
prometheusK8s:
nodeSelector:
node-role.kubernetes.io/infra: ""
prometheusOperator:
nodeSelector:
node-role.kubernetes.io/infra: ""
grafana:
nodeSelector:
node-role.kubernetes.io/infra: ""
k8sPrometheusAdapter:
nodeSelector:
node-role.kubernetes.io/infra: ""
kubeStateMetrics:
nodeSelector:
node-role.kubernetes.io/infra: ""
telemeterClient:
nodeSelector:
node-role.kubernetes.io/infra: ""
openshiftStateMetrics:
nodeSelector:
node-role.kubernetes.io/infra: ""
thanosQuerier:
nodeSelector:
node-role.kubernetes.io/infra: ""
运行此配置映射会强制将监控堆栈的组件重新部署到基础架构节点。
应用新的配置映射:
$ oc create -f cluster-monitoring-configmap.yaml
观察监控 pod 移至新机器:
$ watch 'oc get pod -n openshift-monitoring -o wide'
如果组件没有移到
infra
节点,请删除带有这个组件的 pod:
$ oc delete pod -n openshift-monitoring <pod>
已删除 pod 的组件在
infra
节点上重新创建。
您需要配置 registry Operator,以便将其 Pod 部署到其他节点。
在 OpenShift Container Platform 集群中配置额外的机器集。
查看
config/instance
对象:
$ oc get configs.imageregistry.operator.openshift.io/cluster -o yaml
您可以将路由器 pod 部署到不同的机器集中。默认情况下,pod 部署到 worker 节点。
在 OpenShift Container Platform 集群中配置额外的机器集。
查看路由器 Operator 的
IngressController
自定义资源:
$ oc get ingresscontroller default -n openshift-ingress-operator -o yaml
命令输出类似于以下文本:
apiVersion: operator.openshift.io/v1
kind: IngressController
metadata:
creationTimestamp: 2019-04-18T12:35:39Z
finalizers:
- ingresscontroller.operator.openshift.io/finalizer-ingresscontroller
generation: 1
name: default
namespace: openshift-ingress-operator
resourceVersion: "11341"
selfLink: /apis/operator.openshift.io/v1/namespaces/openshift-ingress-operator/ingresscontrollers/default
uid: 79509e05-61d6-11e9-bc55-02ce4781844a
spec: {}
status:
availableReplicas: 2
conditions:
- lastTransitionTime: 2019-04-18T12:36:15Z
status: "True"
type: Available
domain: apps.<cluster>.example.com
endpointPublishingStrategy:
type: LoadBalancerService
selector: ingresscontroller.operator.openshift.io/deployment-ingresscontroller=default
编辑
ingresscontroller
资源,并更改
nodeSelector
以使用
infra
标签:
$ oc edit ingresscontroller default -n openshift-ingress-operator
在
spec
中添加使用
infra
标签的
nodeSelector
的部分,如下所示:
spec:
nodePlacement:
nodeSelector:
matchLabels:
node-role.kubernetes.io/infra: ""
确认路由器 Pod 在
infra
节点上运行。
查看路由器 Pod 列表,并记下正在运行的 Pod 的节点名称:
$ oc get pod -n openshift-ingress -o wide
基础架构节点的资源要求取决于集群中的集群年龄、节点和对象,因为这些因素可能会导致 Prometheus 的指标或时间序列增加。以下推荐的基础架构节点大小是基于集群最大值和 control plane 密度测试的结果。
worker 节点数量
|
CPU 内核
|
内存 (GB)
|
这些大小建议基于缩放测试,该测试可在整个集群中创建大量对象。这些测试包括达到一些集群最大值。在 OpenShift Container Platform 4.7 集群中有 250 个和 500 个节点时,这些最大值为 10000 个命名空间,包含 61000 个 pod、10000 个 部署、181000 个 secret、400 个配置映射等。Prometheus 是一个高内存密集型应用程序,资源使用量取决于各种因素,包括节点、对象、Prometheus 指标提取间隔、指标或时间序列以及集群的年龄。磁盘大小还取决于保留周期。您必须考虑以上因素并相应地调整它们的大小。
建议的大小只适用于在集群安装过程中安装的 Prometheus、Router 和 Registry 基础架构组件。日志记录(Logging)是第二天操作,因此没有包含在这些建议中。
在 OpenShift Container Platform 4.7 中,与 OpenShift Container Platform 3.11 及之前的版本相比,系统现在默认保留半个 CPU 内核(500 millicore)。这会影响缩放建议。
第 3 章 IBM Z 和 LinuxONE 环境的推荐主机实践
本节为 IBM Z 和 LinuxONE 上的 OpenShift Container Platform 提供推荐的主机实践。
s390x 架构在很多方面都是唯一的。因此,此处提出的一些建议可能不适用于其他平台。
除非另有说明,否则这些实践适用于 IBM Z 和 LinuxONE 上的 z/VM 和 Red Hat Enterprise Linux (RHEL) KVM 安装。
在高度虚拟化的 IBM Z 环境中,您必须仔细规划基础架构的设置和大小。虚拟化最重要的功能之一是能够进行资源过量使用,从而将更多资源分配给虚拟机,而不是在管理程序级别实际可用。这主要依赖于具体的工作负载,并没有适用于所有环境的“黄金法则”。
根据您的设置,在设计 CPU 过量使用 时请考虑这些最佳实践:
在 LPAR 级别 (PR/SM hypervisor),避免将所有可用物理内核 (IFL) 分配给每个 LPAR。例如,当有四个物理 IFL 可用时,您不应该定义三个 LPAR,每个都带有四个逻辑 IFL。
检查并了解 LPAR 共享和权重.
过多的虚拟 CPU 会对性能造成负面影响。不要将比逻辑处理器定义为 LPAR 更多的虚拟处理器。
为峰值工作负载配置每个客户机的虚拟处理器数量,而不是配置更多.
从一个小的数量开始,并监控工作负载。如有必要,逐步增加 vCPU 数量。
并非所有工作负载都适合适用高过量使用比率。如果工作负载是 CPU 密集型的,那么您可能无法在不对性能造成影响的情况下使用高的比率。对于高 I/O 密集型工作负载,即便具有较高的过量使用比率,也能保持一致的性能。
Z/VM 通用性能问题和解决方案
Z/VM 过量使用注意事项
LPAR CPU 管理
3.2. 如何禁用透明巨页(Transparent Huge Pages)
Transparent Huge Pages (THP) 会试图自动执行创建、管理和使用巨页的大部分方面。由于 THP 自动管理巨页,因此并不始终对所有类型的工作负载进行最佳处理。THP 可能会导致性能下降,因为许多应用程序都自行处理巨页。因此,请考虑禁用 THP。以下步骤描述了如何使用 Node Tuning Operator (NTO) 配置集禁用 THP。
3.2.1. 使用 Node Tuning Operator (NTO) 配置集禁用 THP
流程
-
将以下 NTO 示例配置集复制到 YAML 文件中。例如,
thp-s390-tuned.yaml
:
apiVersion: tuned.openshift.io/v1
kind: Tuned
metadata:
name: thp-workers-profile
namespace: openshift-cluster-node-tuning-operator
spec:
profile:
- data: |
[main]
summary=Custom tuned profile for OpenShift on IBM Z to turn off THP on worker nodes
include=openshift-node
transparent_hugepages=never
name: openshift-thp-never-worker
recommend:
- match:
- label: node-role.kubernetes.io/worker
priority: 35
profile: openshift-thp-never-worker
-
创建 NTO 配置集:
$ oc create -f thp-s390-tuned.yaml
-
检查活跃配置集列表:
$ oc get tuned -n openshift-cluster-node-tuning-operator
-
删除配置集:
$ oc delete -f thp-s390-tuned.yaml
网络堆栈是 OpenShift Container Platform 等基于 Kubernetes 的产品最重要的组件之一。对于 IBM Z 设置,网络设置取决于您选择的虚拟机监控程序。取决于具体的工作负载和应用,最佳实践通常需要根据用例和流量模式进行更改。
根据您的设置,考虑以下最佳实践:
考虑有关网络设备的所有选项,以优化您的流量模式。探索 OSA-Express、RoCE Express、HiperSockets、z/VM VSwitch、Linux 网桥 (KVM) 的优势,以确定哪个选项为您的设置带来最大好处。
始终使用最新可用的 NIC 版本。例如,OSA Express 7S 10 GbE 与带有事务工作负载类型的 OSA Express 6S 10 GbE 相比有显著改进,尽管两者都是 10 GbE 适配器。
每个虚拟交换机都添加了额外的延迟层。
负载平衡器在集群外的网络通信中扮演重要角色。如果这对应用程序至关重要,请考虑使用生产环境级的硬件负载平衡器。
OpenShift Container Platform SDN 引入了影响网络性能的流程和规则。确保对 pod 关联性和放置进行考虑,以便至关重要的服务会受益于本地通信的优势。
平衡性能和功能之间的权衡.
IBM Z 上的 OpenShift Container Platform - 性能体验、小窍门和经验
IBM Z 网络中的 OpenShift Container Platform 性能
使用节点关联性规则控制节点上的 pod 放置
3.6. IBM Z 主机上的 RHEL KVM 建议
优化 KVM 虚拟服务器环境很大程度上取决于虚拟服务器的工作负载和可用资源。增强一个环境中性能的相同操作可能会对另一种环境产生负面影响。为特定设置找到最佳平衡可能是一项挑战,通常需要进行各种试验。
下面的部分论述了在 IBM Z 和 LinuxONE 环境中将 OpenShift Container Platform 与 RHEL KVM 搭配使用时的一些最佳实践。
3.6.1. 将多个队列用于您的 VirtIO 网络接口
使用多个虚拟 CPU 时,如果您为传入和传出数据包提供多个队列,则可以并行传输软件包。使用
driver
元素的
queues
属性来配置多个队列。指定一个最小为 2 的整数,该整数不超过虚拟服务器的虚拟 CPU 数量。
以下示例规格为网络接口配置两个输入和输出队列:
<interface type="direct">
<source network="net01"/>
<model type="virtio"/>
<driver ... queues="2"/>
</interface>
多个队列旨在为网络接口提供增强的性能,但也使用内存和 CPU 资源。首先为繁忙的接口定义两个队列。接下来,尝试为不太繁忙的接口定义两个队列,为繁忙的接口设置两个以上的队列。
要使虚拟块设备使用 I/O 线程,您必须为虚拟服务器和每个虚拟块设备配置一个或多个 I/O 线程,以使用其中一个 I/O 线程。
以下示例指定了
<iothreads>3</iothreads>
来配置三个 I/O 线程,带有连续十进制线程 ID 1、2 和 3。
iothread="2"
参数指定要使用 ID 为 2 的 I/O 线程的磁盘设备的驱动程序元素。
仅在需要通过 SCSI 特定的接口解决设备时配置虚拟 SCSI 设备。将磁盘空间配置为虚拟块设备,而非虚拟 SCSI 设备,无论主机上的支持是什么。
但是,您可能需要以下特定于 SCSI 的接口:
主机上 SCSI 附加磁带驱动器的 LUN。
在主机文件系统中挂载在虚拟 DVD 驱动器中的 DVD ISO 文件。
除非您需要动态内存大小,否则请不要定义内存气球设备,并确保 libvirt 不会为您创建。将
memballoon
参数作为设备元素的子项包含在您的域配置 XML 文件中。
检查活跃配置集列表:
<memballoon model="none"/>
3.6.6. 调整主机调度程序的 CPU 迁移算法
除非您非常了解相关的影响,请不要更改调度程序设置。在进行完整的测试并确定相关的影响前,不要对生产系统应用更改。
kernel.sched_migration_cost_ns
参数指定以纳秒为单位的时间间隔。任务最后一次执行后,CPU 缓存被视为具有有用内容,直到此间隔过期为止。增加这个间隔会导致任务迁移减少。默认值为 500000 ns。
如果存在可运行的进程时 CPU 空闲时间高于预期的间隔,请尝试缩短这个间隔。如果任务非常频繁地在 CPU 或节点之间进行转换,请尝试增加它。
要动态将间隔设置为 60000 ns,请输入以下命令:
# sysctl kernel.sched_migration_cost_ns=60000
要将值永久更改为 60000 ns,在
/etc/sysctl.conf
中添加以下条目:
kernel.sched_migration_cost_ns=60000
3.6.7. 禁用 cpuset cgroup 控制器
此设置仅适用于使用 cgroups 版本 1 的 KVM 主机。要在主机上启用 CPU 热插拔,请禁用 cgroup 控制器。
使用您选择的编辑器打开
/etc/libvirt/qemu.conf
。
转至
cgroup_controllers
行。
复制整行并从副本中删除前导编号符号(#)。
删除
cpuset
条目,如下所示:
cgroup_controllers = [ "cpu", "devices", "memory", "blkio", "cpuacct" ]
要使新设置生效,您必须重启 libvirtd 守护进程:
停止所有虚拟机。
运行以下命令:
# systemctl restart libvirtd
重新启动虚拟机。
此设置在主机重新引导后保留。
当虚拟 CPU 空闲时,KVM 会轮询虚拟 CPU 的唤醒条件,然后再分配主机资源。您可以指定时间间隔,在间隔期间在
/sys/module/kvm/parameters/halt_poll_ns
的 sysfs 中进行轮询。在指定时间内,轮询可减少虚拟 CPU 的唤醒延迟,但会牺牲资源使用量。根据工作负载,更长或更短的轮询时间可能很有用。时间间隔以纳秒为单位指定。默认值为 50000 ns。
要针对低 CPU 消耗进行优化,请输入一个小的值或写入 0 来禁用轮询:
# echo 0 > /sys/module/kvm/parameters/halt_poll_ns
要针对低延迟进行优化(例如,用于事务的工作负载),请输入一个大的值:
# echo 80000 > /sys/module/kvm/parameters/halt_poll_ns
本节中的指导信息仅与使用云供应商集成的安装相关。
这些指南适用于带有软件定义网络(SDN)而不是开放虚拟网络(OVN)的 OpenShift Container Platform。
应用以下最佳实践来扩展 OpenShift Container Platform 集群中的 worker 机器数量。您可以通过增加或减少 worker MachineSet 中定义的副本数量来扩展 worker 机器集。
将集群扩展到具有更多节点时:
将节点分散到所有可用区以获得更高的可用性。
同时扩展的机器数量不要超过 25 到 50 个。
考虑在每个可用区创建一个具有类似大小的替代实例类型的新机器集,以帮助缓解周期性供应商容量限制。例如,在 AWS 上,使用 m5.large 和 m5d.large。
云供应商可能会为 API 服务实施配额。因此,需要对集群逐渐进行扩展。
如果同时将机器集中的副本设置为更高数量,则控制器可能无法创建机器。部署 OpenShift Container Platform 的云平台可以处理的请求数量将会影响该进程。当尝试创建、检查和更新有状态的机器时,控制器会开始进行更多的查询。部署 OpenShift Container Platform 的云平台具有 API 请求限制,如果出现过量查询,则可能会因为云平台的限制而导致机器创建失败。
当扩展到具有大量节点时,启用机器健康检查。如果出现故障,健康检查会监控状况并自动修复不健康的机器。
当对大型且高密度的集群减少节点数时,可能需要大量时间,因为这个过程涉及排空或驱除在同时终止的节点上运行的对象。另外,如果要驱除的对象太多,对客户端的请求处理会出现瓶颈。目前将默认的客户端 QPS 和 burst 率分别设定为
5
和
10
,且无法在 OpenShift Container Platform 中进行修改。
要更改机器集,编辑
MachineSet
YAML。然后,通过删除每台机器或将机器设置为
0
个副本来删除与机器设置关联的所有机器。然后,将副本数量调回所需的数量。您对机器集所做的更改不会影响现有的机器。
如果您需要在不进行其他更改的情况下扩展机器集,则不需要删除机器。
默认情况下,OpenShift Container Platform 路由器 Pod 部署在 worker 上。由于路由器需要访问某些集群资源(包括 Web 控制台),除非先重新放置了路由器 Pod,否则请不要将 worker 机器集扩展为
0
。
安装 OpenShift Container Platform 集群和
oc
命令行。
以具有
cluster-admin
权限的用户身份登录
oc
。
编辑机器集:
$ oc edit machineset <machineset> -n openshift-machine-api
将机器缩减为
0
:
$ oc scale --replicas=0 machineset <machineset> -n openshift-machine-api
$ oc edit machineset <machineset> -n openshift-machine-api
等待机器被删除。
根据需要扩展机器设置:
$ oc scale --replicas=2 machineset <machineset> -n openshift-machine-api
$ oc edit machineset <machineset> -n openshift-machine-api
等待机器启动。新机器包含您对机器集所做的更改。
机器健康检查自动修复特定机器池中不健康的机器。
要监控机器的健康状况,创建资源来定义控制器的配置。设置要检查的条件(例如,处于
NotReady
状态达到 5 分钟或 node-problem-detector 中显示了持久性状况),以及用于要监控的机器集合的标签。
您不能对具有 master 角色的机器进行机器健康检查。
监控
MachineHealthCheck
资源的控制器会检查定义的条件。如果机器无法进行健康检查,则会自动删除机器并创建一个机器来代替它。删除机器之后,您会看到
机器被删除
事件。
为限制删除机器造成的破坏性影响,控制器一次仅清空并删除一个节点。如果目标机器池中不健康的机器池中不健康的机器数量大于
maxUnhealthy
的值,则补救会停止,需要启用手动干预。
请根据工作负载和要求仔细考虑超时。
超时时间较长可能会导致不健康的机器上的工作负载长时间停机。
超时时间太短可能会导致补救循环。例如,检查
NotReady
状态的超时时间必须足够长,以便机器能够完成启动过程。
要停止检查,请删除资源。
部署机器健康检查前需要考虑以下限制:
只有机器集拥有的机器才可以由机器健康检查修复。
目前不支持 control plane 机器,如果不健康,则不会被修复。
如果机器的节点从集群中移除,机器健康检查会认为机器不健康,并立即修复机器。
如果机器对应的节点在
nodeStartupTimeout
之后没有加入集群,则会修复机器。
如果
Machine
资源阶段为
Failed
,则会立即修复机器。
4.4. MachineHealthCheck 资源示例
所有基于云的安装类型的
MachineHealthCheck
资源,以及裸机以外的资源,类似以下 YAML 文件:
apiVersion: machine.openshift.io/v1beta1
kind: MachineHealthCheck
metadata:
name: example 1
namespace: openshift-machine-api
spec:
selector:
matchLabels:
machine.openshift.io/cluster-api-machine-role: <role> 2
machine.openshift.io/cluster-api-machine-type: <role> 3
machine.openshift.io/cluster-api-machineset: <cluster_name>-<label>-<zone> 4
unhealthyConditions:
- type: "Ready"
timeout: "300s" 5
status: "False"
- type: "Ready"
timeout: "300s" 6
status: "Unknown"
maxUnhealthy: "40%" 7
nodeStartupTimeout: "10m" 8
-
1
-
指定要部署的机器健康检查的名称。
为要检查的机器池指定一个标签。
以
<cluster_name>-<label>-<zone>
格式 指定要跟踪的机器集。例如,
prod-node-us-east-1a
。
指定节点条件的超时持续时间。如果在超时时间内满足了条件,则会修复机器。超时时间较长可能会导致不健康的机器上的工作负载长时间停机。
指定目标池中允许同时修复的机器数量。这可设为一个百分比或一个整数。如果不健康的机器数量超过
maxUnhealthy
设定的限制,则不会执行补救。
指定机器健康检查在决定机器不健康前必须等待节点加入集群的超时持续时间。
matchLabels
只是示例; 您必须根据具体需要映射您的机器组。
短路可确保仅在集群健康时机器健康检查修复机器。通过
MachineHealthCheck
资源中的
maxUnhealthy
字段配置短路。
如果用户在修复任何机器前为
maxUnhealthy
字段定义了一个值,
MachineHealthCheck
会将
maxUnhealthy
的值与它决定不健康的目标池中的机器数量进行比较。如果不健康的机器数量超过
maxUnhealthy
限制,则不会执行补救。
如果没有设置
maxUnhealthy
,则默认值为
100%
,无论集群状态如何,机器都会被修复。
适当的
maxUnhealthy
值取决于您部署的集群规模以及
MachineHealthCheck
覆盖的机器数量。例如,您可以使用
maxUnhealthy
值覆盖多个可用区间的多个机器集,以便在丢失整个区时,
maxUnhealthy
设置可以在集群中阻止进一步补救。
maxUnhealthy
字段可以设置为整数或百分比。根据
maxUnhealthy
值,有不同的补救实现。
4.4.1.1. 使用绝对值设置
maxUnhealthy
如果将
maxUnhealthy
设为
2
:
如果 2 个或更少节点不健康,则可执行补救
如果 3 个或更多节点不健康,则不会执行补救
这些值与机器健康检查要检查的机器数量无关。
4.4.1.2. 使用百分比设置
maxUnhealthy
如果
maxUnhealthy
被设置为
40%
,有 25 个机器被检查:
如果有 10 个或更少节点处于不健康状态,则可执行补救
如果 11 个或多个节点不健康,则不会执行补救
如果
maxUnhealthy
被设置为
40%
,有 6 个机器被检查:
如果 2 个或更少节点不健康,则可执行补救
如果 3 个或更多节点不健康,则不会执行补救
当被检查的
maxUnhealthy
机器的百分比不是一个整数时,允许的机器数量会被舍入到一个小的整数。
4.5. 创建 MachineHealthCheck 资源
您可以为集群中的所有
MachineSet
创建
MachineHealthCheck
资源。您不应该创建针对 control plane 机器的
MachineHealthCheck
资源。
安装
oc
命令行界面。
创建一个
healthcheck.yml
文件,其中包含您的机器健康检查的定义。
将
healthcheck.yml
文件应用到您的集群:
$ oc apply -f healthcheck.yml
第 5 章 使用 Node Tuning Operator
了解 Node Tuning Operator,以及如何使用它通过编排 tuned 守护进程以管理节点级别的性能优化。
5.1. 关于 Node Tuning Operator
Node Tuning Operator 可以帮助您通过编排 Tuned 守护进程来管理节点级别的性能优化。大多数高性能应用程序都需要一定程度的内核级性能优化。Node Tuning Operator 为用户提供了一个统一的、节点一级的 sysctl 管理接口,并可以根据具体用户的需要灵活地添加自定义性能优化设置。
Operator 将为 OpenShift Container Platform 容器化 Tuned 守护进程作为一个 Kubernetes 守护进程集进行管理。它保证了自定义性能优化设置以可被守护进程支持的格式传递到在集群中运行的所有容器化的 Tuned 守护进程中。相应的守护进程会在集群的所有节点上运行,每个节点上运行一个。
在发生触发配置集更改的事件时,或通过接收和处理终止信号安全终止容器化 Tuned 守护进程时,容器化 Tuned 守护进程所应用的节点级设置将被回滚。
在版本 4.1 及更高版本中,OpenShift Container Platform 标准安装中包含了 Node Tuning Operator。
5.2. 访问 Node Tuning Operator 示例规格
使用此流程来访问 Node Tuning Operator 的示例规格。
$ oc get Tuned/default -o yaml -n openshift-cluster-node-tuning-operator
默认 CR 旨在为 OpenShift Container Platform 平台提供标准的节点级性能优化,它只能被修改来设置 Operator Management 状态。Operator 将覆盖对默认 CR 的任何其他自定义更改。若进行自定义性能优化,请创建自己的 Tuned CR。新创建的 CR 将与默认的 CR 合并,并基于节点或 pod 标识和配置文件优先级对节点应用自定义调整。
虽然在某些情况下,对 pod 标识的支持可以作为自动交付所需调整的一个便捷方式,但我们不鼓励使用这种方法,特别是在大型集群中。默认 Tuned CR 并不带有 pod 标识匹配。如果创建了带有 pod 标识匹配的自定义配置集,则该功能将在此时启用。在以后的 Node Tuning Operator 版本中可能会弃用 pod 标识功能。
以下是在集群中设置的默认配置集。
apiVersion: tuned.openshift.io/v1
kind: Tuned
metadata:
name: default
namespace: openshift-cluster-node-tuning-operator
spec:
profile:
- name: "openshift"
data: |
[main]
summary=Optimize systems running OpenShift (parent profile)
include=${f:virt_check:virtual-guest:throughput-performance}
[selinux]
avc_cache_threshold=8192
[net]
nf_conntrack_hashsize=131072
[sysctl]
net.ipv4.ip_forward=1
kernel.pid_max=>4194304
net.netfilter.nf_conntrack_max=1048576
net.ipv4.conf.all.arp_announce=2
net.ipv4.neigh.default.gc_thresh1=8192
net.ipv4.neigh.default.gc_thresh2=32768
net.ipv4.neigh.default.gc_thresh3=65536
net.ipv6.neigh.default.gc_thresh1=8192
net.ipv6.neigh.default.gc_thresh2=32768
net.ipv6.neigh.default.gc_thresh3=65536
vm.max_map_count=262144
[sysfs]
/sys/module/nvme_core/parameters/io_timeout=4294967295
/sys/module/nvme_core/parameters/max_retries=10
- name: "openshift-control-plane"
data: |
[main]
summary=Optimize systems running OpenShift control plane
include=openshift
[sysctl]
# ktune sysctl settings, maximizing i/o throughput
# Minimal preemption granularity for CPU-bound tasks:
# (default: 1 msec# (1 + ilog(ncpus)), units: nanoseconds)
kernel.sched_min_granularity_ns=10000000
# The total time the scheduler will consider a migrated process
# "cache hot" and thus less likely to be re-migrated
# (system default is 500000, i.e. 0.5 ms)
kernel.sched_migration_cost_ns=5000000
# SCHED_OTHER wake-up granularity.
# Preemption granularity when tasks wake up. Lower the value to
# improve wake-up latency and throughput for latency critical tasks.
kernel.sched_wakeup_granularity_ns=4000000
- name: "openshift-node"
data: |
[main]
summary=Optimize systems running OpenShift nodes
include=openshift
[sysctl]
net.ipv4.tcp_fastopen=3
fs.inotify.max_user_watches=65536
fs.inotify.max_user_instances=8192
recommend:
- profile: "openshift-control-plane"
priority: 30
match:
- label: "node-role.kubernetes.io/master"
- label: "node-role.kubernetes.io/infra"
- profile: "openshift-node"
priority: 40
使用这个流程检查在每个节点上应用了哪些 Tuned 配置集。
检查每个节点上运行的 Tuned pod:
$ oc get pods -n openshift-cluster-node-tuning-operator -o wide
Operator 的自定义资源 (CR) 包含两个主要部分。第一部分是
profile:
,这是 tuned 配置集及其名称的列表。第二部分是
recommend:
,用来定义配置集选择逻辑。
多个自定义调优规格可以共存,作为 Operator 命名空间中的多个 CR。Operator 会检测到是否存在新 CR 或删除了旧 CR。所有现有的自定义性能优化设置都会合并,同时更新容器化 Tuned 守护进程的适当对象。
通过调整默认的 Tuned CR 来设置 Operator Management 状态。默认情况下,Operator 处于 Managed 状态,默认的 Tuned CR 中没有
spec.managementState
字段。Operator Management 状态的有效值如下:
Managed: Operator 会在配置资源更新时更新其操作对象
Unmanaged: Operator 将忽略配置资源的更改
Removed: Operator 将移除 Operator 置备的操作对象和资源
配置集数据
profile:
部分列出了 Tuned 配置集及其名称。
profile:
- name: tuned_profile_1
data: |
# Tuned profile specification
[main]
summary=Description of tuned_profile_1 profile
[sysctl]
net.ipv4.ip_forward=1
# ... other sysctl's or other Tuned daemon plugins supported by the containerized Tuned
# ...
- name: tuned_profile_n
data: |
# Tuned profile specification
[main]
summary=Description of tuned_profile_n profile
# tuned_profile_n profile settings
建议的配置集
profile:
选择逻辑通过 CR 的
recommend:
部分来定义。
recommend:
部分是根据选择标准推荐配置集的项目列表。
recommend:
<recommend-item-1>
# ...
<recommend-item-n>
列表中的独立项:
- machineConfigLabels: 1
<mcLabels> 2
match: 3
<match> 4
priority: <priority> 5
profile: <tuned_profile_name> 6
operand: 7
debug: <bool> 8
-
1
-
MachineConfig
标签的键/值字典。键必须是唯一的。
如果省略,则会假设配置集匹配,除非设置了优先级更高的配置集,或设置了
machineConfigLabels
。
可选列表。
配置集排序优先级。较低数字表示优先级更高(
0
是最高优先级)。
在匹配项中应用的 TuneD 配置集。例如
tuned_profile_1
。
可选操作对象配置。
为 TuneD 守护进程打开或关闭调试。
true
为打开,
false
为关闭。默认值为
false
。
<match>
是一个递归定义的可选数组,如下所示:
- label: <label_name> 1
value: <label_value> 2
type: <label_type> 3
<match> 4
-
1
-
节点或 pod 标签名称。
可选的节点或 pod 标签值。如果省略,
<label_name>
足以匹配。
可选的对象类型(
node
或
pod
)。如果省略,会使用
node
。
可选的
<match>
列表。
如果不省略
<match>
,则所有嵌套的
<match>
部分也必须评估为
true
。否则会假定
false
,并且不会应用或建议具有对应
<match>
部分的配置集。因此,嵌套(子级
<match>
部分)会以逻辑 AND 运算来运作。反之,如果匹配
<match>
列表中任何一项,整个
<match>
列表评估为
true
。因此,该列表以逻辑 OR 运算来运作。
如果定义
了 machineConfigLabels
,基于机器配置池的匹配会对给定的
recommend:
列表项打开。
<mcLabels>
指定机器配置标签。机器配置会自动创建,以在配置集
<tuned_profile_name>
中应用主机设置,如内核引导参数。这包括使用与
<mcLabels>
匹配的机器配置选择器查找所有机器配置池,并在分配了找到的机器配置池的所有节点上设置配置集
<tuned_profile_name>
。要针对同时具有 master 和 worker 角色的节点,您必须使用 master 角色。
列表项
match
和
machineConfigLabels
由逻辑 OR 操作符连接。
match
项首先以短电路方式评估。因此,如果它被评估为
true
,则不考虑
MachineConfigLabels
项。
当使用基于机器配置池的匹配时,建议将具有相同硬件配置的节点分组到同一机器配置池中。不遵循这个原则可能会导致在共享同一机器配置池的两个或者多个节点中 Tuned 操作对象导致内核参数冲突。
以下 CR 对带有标签
tuned.openshift.io/ingress-node-label
的 OpenShift Container Platform 节点应用节点一级的自定义调整。作为管理员,使用以下命令创建一个自定义 Tuned CR。
在使用 Tuned CR 的
profile:
部分中定义的自定义配置集时,以下 Tuned 插件都受到支持,但
[main]
部分除外:
audio
eeepc_she
modules
mounts
scheduler
scsi_host
selinux
sysctl
sysfs
video
其中一些插件提供了不受支持的动态性能优化功能。以下 Tuned 插件目前还不支持:
bootloader
script
systemd
如需更多信息,请参阅
Available Tuned Plug-ins
和
Getting Started with Tuned
。
Cluster Loader 是一个将大量对象部署到集群的工具程序,它可创建用户定义的集群对象。构建、配置并运行 Cluster Loader 以测量处于各种集群状态的 OpenShift Container Platform 部署的性能指标。
流程
-
要拉取容器镜像,请运行:
$ podman pull quay.io/openshift/origin-tests:4.7
先决条件
-
软件仓库会提示您进行验证。registry 凭证允许您访问没有公开的镜像。使用您在安装时产生的现有身份验证凭证。
使用内置的测试配置执行 Cluster Loader,它会部署五个模板构建并等待它们完成:
$ podman run -v ${LOCAL_KUBECONFIG}:/root/.kube/config:z -i \
quay.io/openshift/origin-tests:4.7 /bin/bash -c 'export KUBECONFIG=/root/.kube/config && \
openshift-tests run-test "[sig-scalability][Feature:Performance] Load cluster \
should populate the cluster [Slow][Serial] [Suite:openshift]"'
或者,通过设置
VIPERCONFIG
环境变量来执行带有用户定义的配置的 Cluster Loader:
$ podman run -v ${LOCAL_KUBECONFIG}:/root/.kube/config:z \
-v ${LOCAL_CONFIG_FILE_PATH}:/root/configs/:z \
-i quay.io/openshift/origin-tests:4.7 \
/bin/bash -c 'KUBECONFIG=/root/.kube/config VIPERCONFIG=/root/configs/test.yaml \
openshift-tests run-test "[sig-scalability][Feature:Performance] Load cluster \
should populate the cluster [Slow][Serial] [Suite:openshift]"'
在这个示例中,
${LOCAL_KUBECONFIG}
代表
kubeconfig
在本地文件系统中的路径。另外,还有一个名为
${LOCAL_CONFIG_FILE_PATH}
的目录,它被挂载到包含名为
test.yaml
的配置文件的容器中。另外,如果
test.yaml
引用了任何外部模板文件或 podspec 文件,则也应该被挂载到容器中。
该工具创建多个命名空间(项目),其中包含多个模板或 pod。
6.3.1. Cluster Loader 配置文件示例
Cluster Loader 的配置文件是一个基本的 YAML 文件:
provider: local 1
ClusterLoader:
cleanup: true
projects:
- num: 1
basename: clusterloader-cakephp-mysql
tuning: default
ifexists: reuse
templates:
- num: 1
file: cakephp-mysql.json
- num: 1
basename: clusterloader-dancer-mysql
tuning: default
ifexists: reuse
templates:
- num: 1
file: dancer-mysql.json
- num: 1
basename: clusterloader-django-postgresql
tuning: default
ifexists: reuse
templates:
- num: 1
file: django-postgresql.json
- num: 1
basename: clusterloader-nodejs-mongodb
tuning: default
ifexists: reuse
templates:
- num: 1
file: quickstarts/nodejs-mongodb.json
- num: 1
basename: clusterloader-rails-postgresql
tuning: default
templates:
- num: 1
file: rails-postgresql.json
tuningsets: 2
- name: default
pods:
stepping: 3
stepsize: 5
pause: 0 s
rate_limit: 4
delay: 0 ms
-
1
-
端到端测试的可选设置。设置为
local
以避免额外的日志信息。
调整集允许速率限制和分步,可以生成几批 pod,同时在两组间暂停使用。在继续执行前,Cluster Loader 会监控上一步的完成情况。
为每
N
个对象被创建后,会暂停
M
秒。
在创建不同对象期间,限制率会等待
M
毫秒。
本例假定对任何外部模板文件或 pod spec 文件的引用也会挂载到容器中。
如果您在 Microsoft Azure 上运行 Cluster Loader,则必须将
AZURE_AUTH_LOCATION
变量设置为包含
terraform.azure.auto.tfvars.json
输出结果的文件,该文件存在于安装程序目录中。
表 6.1. 顶层 Cluster Loader 字段
字段
|
描述
|
cleanup
可设置为
true
或
false
。每个配置有一个定义。如果设置为
true
,
cleanup
会删除所有由 Cluster Loader 在测试结束时创建的命名空间(项目)。
projects
包含一个或多个定义的子对象。在
projects
下,定义了要创建的每个命名空间,
projects
有几个必需的子标题。
tuningsets
每个配置都有一个定义的子对象。
tuningset
允许用户定义一个调整集,为创建项目或对象(pods、模板等)添加可配置的计时。
每个配置都有一个定义的可选子对象。在创建对象的过程中添加同步的可能性。
|
表 6.2. projects 下的字段
字段
|
描述
|
整数。定义要创建项目的数量。
basename
字符串项目基本名称的一个定义。在
Basename
后面会附加相同命名空间的计数以避免冲突。
tuning
字符串需要应用到在这个命名空间里部署的项目的 tuning 设置。
ifexists
包含
reuse
或
delete
的字符串。如果发现一个项目或者命名空间的名称与执行期间创建的项目或命名空间的名称相同时,需要进行什么操作。
configmaps
键值对列表。键是配置映射名称,值是指向创建配置映射的文件的路径。
secrets
键值对列表。key 是 secret 名称,值是一个指向用来创建 secret 的文件的路径。
要部署的 pod 的一个或者多个定义的子对象。
templates
要部署模板的一个或者多个定义的子对象。
|
表 6.3. pods 和 templates 下的字段
字段
|
描述
|
整数。要部署的 pod 或模板数量。
image
字符串到可以拉取镜像的软件仓库的 docker 镜像 URL。
basename
字符串要创建的模板(或 pod)的基本名称的一个定义。
字符串到要创建的 pod 规格或模板的本地文件的路径。
parameters
健值对。在
parameters
下,您可以指定一组值在 pod 或模板中进行覆盖。
|
表 6.4. tuningsets 下的字段
字段
|
描述
|
字符串tuning 集的名称,该名称将与在一个项目中定义 turning 时指定的名称匹配。
指定应用于 pod 的
tuningsets
的子对象。
templates
指定应用于模板的
tuningsets
的子对象。
|
表 6.5. tuningsets pods 或 tuningsets templates 下的字段
字段
|
描述
|
stepping
子对象。如果要在步骤创建模式中创建对象,需要使用的步骤配置。
rate_limit
子对象。用来限制对象创建率的频率限制 turning 集。
|
表 6.6. tuningsets pods 或 tuningsets templates, stepping 下的字段
字段
|
描述
|
stepsize
整数。在暂停对象创建前要创建的对象数量。
pause
整数。在创建了由
stepsize
定义的对象数后需要暂停的秒数。
timeout
整数。如果对象创建失败,在失败前要等待的秒数。
delay
整数。在创建请求间等待多少毫秒 (ms)
|
表 6.7. sync 下的字段
字段
|
描述
|
server
带有
enabled
和
port
字段的子对象。布尔值
enabled
定义了是否启动用于 pod 同步的 HTTP 服务器。整数值
port
定义了要监听的 HTTP 服务器端口(默认为
9090
)。
running
布尔值等待带有与
selectors
匹配的标签的 pod 进入
Running
状态。
succeeded
布尔值等待带有与
selectors
匹配的标签的 pod 进入
Completed
状态。
selectors
匹配处于
Running
或
Completed
状态 的 pod 的选择器列表。
timeout
字符串等待处于
Running
或
Completed
状态的 pod 的同步超时时间。对于不是
0
的值,其时间单位是:[ns|us|ms|s|m|h]
|
-
当在没有配置的情况下调用 Cluster Loader 会失败。(
BZ#1761925
)
如果用户模板中没有定义
IDENTIFIER
参数,则模板创建失败,错误信息为:
error: unknown parameter name "IDENTIFIER"
。如果部署模板,在模板中添加这个参数以避免出现这个错误:
"name": "IDENTIFIER",
"description": "Number to append to the name of resources",
"value": "1"
如果部署 pod,则不需要添加该参数。
CPU Manager 管理 CPU 组并限制特定 CPU 的负载。
CPU Manager 对于有以下属性的负载有用:
需要尽可能多的 CPU 时间。
对处理器缓存丢失非常敏感。
低延迟网络应用程序。
需要与其他进程协调,并从共享一个处理器缓存中受益。
流程
-
可选:标记节点:
# oc label node perf-node.example.com cpumanager=true
-
编辑启用 CPU Manager 的节点的
MachineConfigPool
。在这个示例中,所有 worker 都启用了 CPU Manager:
# oc edit machineconfigpool worker
-
为 worker 机器配置池添加标签:
metadata:
creationTimestamp: 2020-xx-xxx
generation: 3
labels:
custom-kubelet: cpumanager-enabled
-
创建
KubeletConfig
,
cpumanager-kubeletconfig.yaml
,自定义资源 (CR) 。请参阅上一步中创建的标签,以便使用新的 kubelet 配置更新正确的节点。请参见
MachineConfigPoolSelector
部分:
apiVersion: machineconfiguration.openshift.io/v1
kind: KubeletConfig
metadata:
name: cpumanager-enabled
spec:
machineConfigPoolSelector:
matchLabels:
custom-kubelet: cpumanager-enabled
kubeletConfig:
cpuManagerPolicy: static 1
cpuManagerReconcilePeriod: 5s 2
-
1
-
指定一个策略:
none
.这个策略明确启用了现有的默认 CPU 关联性方案,从而不会出现超越调度程序自动进行的关联性。
static
。此策略允许具有某些资源特征的 pod 获得提高 CPU 关联性和节点上专用的 pod。
可选。指定 CPU Manager 协调频率。默认值为
5s
。
创建动态 kubelet 配置:
# oc create -f cpumanager-kubeletconfig.yaml
这会在 kubelet 配置中添加 CPU Manager 功能,如果需要,Machine Config Operator(MCO)将重启节点。要启用 CPU Manager,则不需要重启。
检查合并的 kubelet 配置:
# oc get machineconfig 99-worker-XXXXXX-XXXXX-XXXX-XXXXX-kubelet -o json | grep ownerReference -A7
-
确定为您标记的节点调度了 pod:
# oc describe pod cpumanager
拓扑管理器(Topology Manager)从 CPU Manager、设备管理器和其他 Hint 提供者收集提示信息,以匹配相同非统一 内存访问(NUMA)节点上的所有 QoS 类的 pod 资源(如 CPU、SR-IOV VF 和其他设备资源)。
拓扑管理器使用收集来的提示信息中获得的拓扑信息,根据配置的 Topology Manager 策略以及请求的 Pod 资源,决定节点是否被节点接受或拒绝。
拓扑管理器对希望使用硬件加速器来支持对工作延迟有极高要求的操作及高吞吐并发计算的负载很有用。
要使用拓扑管理器,必须使用
static
策略的 CPU Manager。有关 CPU Manager 的详情请参考
使用 CPU Manager
。
拓扑管理器通过从 Hint 提供者(如 CPU Manager 和设备管理器)收集拓扑提示来调整所有级别服务质量(QoS)的
Pod
资源,并使用收集的提示来匹配
Pod
资源。
要将 CPU 资源与
Pod
规格中的其他请求资源匹配,必须使用
static
CPU Manager 策略启用 CPU Manager。
拓扑管理器支持四个分配策略,这些策略在
cpumanager-enabled
自定义资源(CR)中定义:
-
none
策略
-
这是默认策略,不执行任何拓扑对齐调整。
-
best-effort
策略
-
对于带有
best-effort
拓扑管理策略的 pod 中的每个容器,kubelet 会调用每个 Hint 提供者来发现其资源的可用性。使用这些信息,拓扑管理器会保存那个容器的首选 NUMA 节点关联性设置。如果关联性没有被首选设置,则拓扑管理器会保存这个设置,并把 pod 分配给节点。
-
restricted
策略
-
对于带有
restricted
拓扑管理策略的 pod 中的每个容器,kubelet 会调用每个 Hint 提供者来发现其资源的可用性。使用这些信息,拓扑管理器会保存那个容器的首选 NUMA 节点关联性设置。如果关联性没有被首选,则拓扑管理器会从节点拒绝这个 pod,从而导致 pod 处于
Terminated
状态,且 pod 准入失败。
-
single-numa-node
策略
-
对于带有
single-numa-node
拓扑管理策略的 pod 中的每个容器,kubelet 会调用每个 Hint 提供者来发现其资源的可用性。使用这个信息,拓扑管理器会决定单个 NUMA 节点关联性是否可能。如果是,pod 将会分配给该节点。如果无法使用单一 NUMA 节点关联性,则拓扑管理器会拒绝来自节点的 pod。这会导致 pod 处于 Terminated 状态,且 pod 准入失败。
要使用拓扑管理器,您必须在
cpumanager-enabled
自定义资源(CR)中配置分配策略。如果您设置了 CPU Manager,则该文件可能会存在。如果这个文件不存在,您可以创建该文件。
将 CPU Manager 策略配置为
static
。请参考扩展和性能文档中的使用 CPU Manager 部分 。
激活 Topolgy Manager:
在
cpumanager-enabled
自定义资源(CR)中配置拓扑管理器分配策略。
$ oc edit KubeletConfig cpumanager-enabled
apiVersion: machineconfiguration.openshift.io/v1
kind: KubeletConfig
metadata:
name: cpumanager-enabled
spec:
machineConfigPoolSelector:
matchLabels:
custom-kubelet: cpumanager-enabled
kubeletConfig:
cpuManagerPolicy: static 1
cpuManagerReconcilePeriod: 5s
topologyManagerPolicy: single-numa-node 2
-
1
-
此参数必须是
static
。
指定所选拓扑管理器分配策略。在这里,策略是
single-numa-node
。有效值为:
default
、
best-effort
、
restricted
、
single-numa-node
。
有关 CPU Manager 的详情请参考
使用 CPU Manager
。
以下的
Pod
specs 示例演示了 Pod 与 Topology Manager 的交互。
因为没有指定资源请求或限制,以下 pod 以
BestEffort
QoS 类运行。
spec:
containers:
- name: nginx
image: nginx
因为请求小于限制,下一个 pod 以
Burstable
QoS 类运行。
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "200Mi"
requests:
memory: "100Mi"
如果所选策略不是
none
,则拓扑管理器将不考虑其中任何一个
Pod
规格。
因为请求等于限制,最后一个 pod 以 Guaranteed QoS 类运行。
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "200Mi"
cpu: "2"
example.com/device: "1"
requests:
memory: "200Mi"
cpu: "2"
example.com/device: "1"
拓扑管理器将考虑这个 pod。拓扑管理器会参考 CPU Manager 的静态策略,该策略可返回可用 CPU 的拓扑结构。拓扑管理器还参考设备管理器来发现可用设备的拓扑结构,如 example.com/device。
拓扑管理器将使用此信息存储该容器的最佳拓扑。在本 pod 中,CPU Manager 和设备管理器将在资源分配阶段使用此存储的信息。
第 9 章 扩展 Cluster Monitoring Operator
OpenShift Container Platform 会提供 Cluster Monitoring Operator 在基于 Prometheus 的监控堆栈中收集并存储的数据。作为管理员,您可以在一个 dashboard 接口(Grafana)中查看系统资源、容器和组件指标。
如果您使用附加的 Prometheus PVC 运行集群监控,在集群升级过程中可能会出现 OOM 终止的情况。当 Prometheus 使用持久性存储时,Prometheus 内存在升级过程中会加倍,并在升级完成后的几小时内仍会是这个情况。为了避免 OOM 终止问题,允许升级前有双倍可用内存的 worker 节点。例如,如果您在最低推荐节点上运行监控(2 个内核,8 GB RAM),将内存增加到 16 GB。如需更多信息,请参阅
BZ#1925061
。
红帽对不同的扩展大小进行了各种测试。
以下 Prometheus 存储要求并不具有规定性。取决于工作负载活动和资源使用情况,集群中可能会观察到更高资源消耗。
表 9.1. Prometheus 数据库的存储要求取决于集群中的节点/pod 数量
节点数量
|
pod 数量
|
每天增加的 Prometheus 存储
|
每 15 天增加的 Prometheus 存储
|
RAM 空间(每个缩放大小)
|
网络(每个 tsdb 块)
|
6.3 GB
94 GB
16 MB
13 GB
195 GB
10 GB
26 MB
19 GB
283 GB
12 GB
36 MB
25 GB
375 GB
14 GB
46 MB
大约 20%的预期大小被添加为开销,以保证存储要求不会超过计算的值。
上面的计算用于默认的 OpenShift Container Platform Cluster Monitoring Operator。
CPU 利用率会有轻微影响。这个比例为在每 50 个节点和 1800 个 pod 的 40 个内核中大约有 1 个。
针对 OpenShift Container Platform 的建议
至少使用三个基础架构(infra)节点。
至少使用三个带有 NVMe(non-volatile memory express)驱动的
openshift-container-storage
节点。
您可以为集群监控堆栈中的 Prometheus 组件增加存储容量。
为 Prometheus 增加存储容量:
创建 YAML 配置文件
cluster-monitoring-config.yaml
。例如:
apiVersion: v1
kind: ConfigMap
data:
config.yaml: |
prometheusK8s:
retention: {{PROMETHEUS_RETENTION_PERIOD}} 1
nodeSelector:
node-role.kubernetes.io/infra: ""
volumeClaimTemplate:
spec:
storageClassName: {{STORAGE_CLASS}} 2
resources:
requests:
storage: {{PROMETHEUS_STORAGE_SIZE}} 3
alertmanagerMain:
nodeSelector:
node-role.kubernetes.io/infra: ""
volumeClaimTemplate:
spec:
storageClassName: {{STORAGE_CLASS}} 4
resources:
requests:
storage: {{ALERTMANAGER_STORAGE_SIZE}} 5
metadata:
name: cluster-monitoring-config
namespace: openshift-monitoring
-
1
-
一个典型的值是
PROMETHEUS_retention_PERIOD=15d
。时间单位使用以下后缀之一 : s 、m 、h 、d。
集群的存储类。
一个典型的值是
PROMETHEUS_STORAGE_SIZE=2000Gi
。存储值可以是一个纯整数,也可以是带有以下后缀之一的整数: E 、P 、T 、G 、M 、K。您也可以使用以下效果相同的后缀:Ei 、Pi 、Ti 、Gi 、Mi 、Ki。
一个典型的值
是 alertmanager_STORAGE_SIZE=20Gi
。存储值可以是一个纯整数,也可以是带有以下后缀之一的整数: E 、P 、T 、G 、M 、K。您也可以使用以下效果相同的后缀:Ei 、Pi 、Ti 、Gi 、Mi 、Ki。
为保留周期、存储类和存储大小添加值。
保存该文件。
运行以下命令应用这些更改:
$ oc create -f cluster-monitoring-config.yaml
在规划 OpenShift Container Platform 集群时,请考虑以下对象限制。
这些限制基于最大可能的集群。对于较小的集群,最大值限制会较低。很多因素会影响指定的阈值,包括 etcd 版本或者存储数据格式。
这些指南适用于带有软件定义网络(SDN)而不是开放虚拟网络(OVN)的 OpenShift Container Platform。
在大多数情况下,超过这些限制会降低整体性能。它不一定意味着集群会出现错误。
10.1. OpenShift Container Platform 为主发行版本测试了集群最大值
为 OpenShift Container Platform 3.x 测试的云平台: Red Hat OpenStack Platform(RHOSP)、Amazon Web Services 和 Microsoft Azure。为 OpenShift Container Platform 4.x 测试的云平台: Amazon Web Services、Microsoft Azure 和 Google Cloud Platform。
最大类型
|
3.x 测试的最大值
|
4.x 测试的最大值
|
2,000
2,000
pod 数量
[1]
150,000
150,000
每个节点的 pod 数量
500
[2]
每个内核的 pod 数量
没有默认值。
没有默认值。
命名空间数量
[3]
10,000
10,000
构建(build)数
10,000(默认 pod RAM 512 Mi)- 管道 (Pipeline) 策略
10,000(默认 pod RAM 512 Mi)- Source-to-Image (S2I) 构建策略
每个命名空间的 pod 数量
[4]
25,000
25,000
每个 Ingress Controller 的路由和后端数量
每个路由器有 2,000 个
每个路由器有 2,000 个
secret 的数量
80,000
80,000
配置映射数量
90,000
90,000
服务数量
[5]
10,000
10,000
每个命名空间的服务数
5,000
5,000
每个服务中的后端数
5,000
5,000
每个命名空间的部署数量
[4]
2,000
2,000
构建配置数
12,000
12,000
secret 的数量
40,000
40,000
自定义资源定义(CRD)的数量
没有默认值。
512
[6]
这里的 pod 数量是 test pod 的数量。实际的 pod 数量取决于应用程序的内存、CPU 和存储要求。
这在一个有 100 个 work 节点,每个 worker 节点有 500 个 pod 的集群中测试。默认
maxPods
仍为 250。要获得 500
maxPods
,则必须使用自定义 kubelet 配置将
maxPods
设置为
500
来创建集群。如果需要 500 个用户 Pod,则需要
hostPrefix
为
22
,因为节点上已经运行了 10-15 个系统 pod。带有 Persistent VolumeClaim (PVC) 的最大 pod 数量取决于分配 PVC 的后端存储。在我们的测试中,只有 OpenShift Container Storage (OCS v4) 能够满足本文档中提到的每个节点的 pod 数量。
当有大量活跃的项目时,如果键空间增长过大并超过空间配额,etcd 的性能将会受到影响。强烈建议您定期维护 etcd 存储(包括整理碎片)来释放 etcd 存储。
系统中有一些控制循环,它们必须对给定命名空间中的所有对象进行迭代,以作为对一些状态更改的响应。在单一命名空间中有大量给定类型的对象可使这些循环的运行成本变高,并降低对给定状态变化的处理速度。限制假设系统有足够的 CPU 、内存和磁盘来满足应用程序的要求。
每个服务端口和每个服务后端在 iptables 中都有对应条目。给定服务的后端数量会影响端点对象的大小,这会影响到整个系统发送的数据大小。
OpenShift Container Platform 的限制是 512 个总自定义资源定义(CRD),其中包括由 OpenShift Container Platform 安装的产品、与 OpenShift Container Platform 集成并创建了 CRD 的产品。如果创建超过 512 CRD,则
oc
命令请求可能会节流。
红帽不提供针对 OpenShift Container Platform 集群大小调整的直接指导。这是因为,判断集群是否在 OpenShift Container Platform 支持的边界内,需要仔细考虑限制集群扩展的所有多维因素。
10.2. 测试集群最大值的 OpenShift Container Platform 环境和配置
AWS 云平台:
节点
|
Flavor
|
vCPU
|
RAM(GiB)
|
磁盘类型
|
磁盘大小(GiB)/IOS
|
数量
|
区域
|
Master/etcd
[1]
r5.4xlarge
220 / 3000
us-west-2
Infra
[2]
m5.12xlarge
us-west-2
Workload
[3]
m5.4xlarge
500
[4]
us-west-2
Worker
m5.2xlarge
3/25/250/500
[5]
us-west-2
带有 3000 个 IOPS 的 io1 磁盘用于 master/etcd 节点,因为 etcd 非常大,且敏感延迟。
Infra 节点用于托管 Monitoring、Ingress 和 Registry 组件,以确保它们有足够资源可大规模运行。
工作负载节点专用于运行性能和可扩展工作负载生成器。
使用更大的磁盘,以便有足够的空间存储在运行性能和可扩展性测试期间收集的大量数据。
在迭代中扩展了集群,且性能和可扩展性测试是在指定节点数中执行的。
10.3. 如何根据经过测试的集群限制规划您的环境
在节点中过度订阅物理资源会影响在 pod 放置过程中对 Kubernetes 调度程序的资源保证。了解可以采取什么措施避免内存交换。
某些限制只在单一维度中扩展。当很多对象在集群中运行时,它们会有所不同。
本文档中给出的数字基于红帽的测试方法、设置、配置和调整。这些数字会根据您自己的设置和环境而有所不同。
在规划您的环境时,请确定每个节点会运行多少 个 pod :
required pods per cluster / pods per node = total number of nodes needed
每个节点上的 Pod 数量做多为 250。而在某个节点中运行的 pod 的具体数量取决于应用程序本身。请参阅
如何根据应用程序要求规划您的环境
中的内容来计划应用程序的内存、CPU 和存储要求。
如果您计划把集群的规模限制在有 2200 个 pod,则需要至少有 5 个节点,假设每个节点最多有 500 个 pod:
2200 / 500 = 4.4
如果将节点数量增加到 20,那么 pod 的分布情况将变为每个节点有 110 个 pod:
2200 / 20 = 110
required pods per cluster / total number of nodes = expected pods per node
考虑应用程序环境示例:
pod 类型
|
pod 数量
|
最大内存
|
CPU 内核
|
持久性存储
|
Apache
500 MB
node.js
postgresql
10 GB
JBoss EAP
推断的要求: 550 个 CPU 内核、450GB RAM 和 1.4TB 存储。
根据您的具体情况,节点的实例大小可以被增大或降低。在节点上通常会使用资源过度分配。在这个部署场景中,您可以选择运行多个额外的较小节点,或数量更少的较大节点来提供同样数量的资源。在做出决定前应考虑一些因素,如操作的灵活性以及每个实例的成本。
节点类型
|
数量
|
CPU
|
RAM (GB)
|
节点(选择 1)
节点(选择 2)
节点(选择 3)
有些应用程序很适合于过度分配的环境,有些则不适合。大多数 Java 应用程序以及使用巨页的应用程序都不允许使用过度分配功能。它们的内存不能用于其他应用程序。在上面的例子中,环境大约会出现 30% 过度分配的情况,这是一个常见的比例。
应用程序 pod 可以使用环境变量或 DNS 访问服务。如果使用环境变量,当 pod 在节点上运行时,对于每个活跃服务,则 kubelet 的变量都会注入。集群感知 DNS 服务器监视 Kubernetes API 提供了新服务,并为每个服务创建一组 DNS 记录。如果整个集群中启用了 DNS,则所有 pod 都应自动根据其 DNS 名称解析服务。如果您必须超过 5000 服务,可以使用 DNS 进行服务发现。当使用环境变量进行服务发现时,参数列表超过了命名空间中 5000 服务后允许的长度,则 pod 和部署将失败。要解决这个问题,请禁用部署的服务规格文件中的服务链接:
apiVersion: template.openshift.io/v1
kind: Template
metadata:
name: deployment-config-template
creationTimestamp:
annotations:
description: This template will create a deploymentConfig with 1 replica, 4 env vars and a service.
tags: ''
objects:
- apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
name: deploymentconfig${IDENTIFIER}
spec:
template:
metadata:
labels:
name: replicationcontroller${IDENTIFIER}
spec:
enableServiceLinks: false
containers:
- name: pause${IDENTIFIER}
image: "${IMAGE}"
ports:
- containerPort: 8080
protocol: TCP
- name: ENVVAR1_${IDENTIFIER}
value: "${ENV_VALUE}"
- name: ENVVAR2_${IDENTIFIER}
value: "${ENV_VALUE}"
- name: ENVVAR3_${IDENTIFIER}
value: "${ENV_VALUE}"
- name: ENVVAR4_${IDENTIFIER}
value: "${ENV_VALUE}"
resources: {}
imagePullPolicy: IfNotPresent
capabilities: {}
securityContext:
capabilities: {}
privileged: false
restartPolicy: Always
serviceAccount: ''
replicas: 1
selector:
name: replicationcontroller${IDENTIFIER}
triggers:
- type: ConfigChange
strategy:
type: Rolling
- apiVersion: v1
kind: Service
metadata:
name: service${IDENTIFIER}
spec:
selector:
name: replicationcontroller${IDENTIFIER}
ports:
- name: serviceport${IDENTIFIER}
protocol: TCP
port: 80
targetPort: 8080
portalIP: ''
type: ClusterIP
sessionAffinity: None
status:
loadBalancer: {}
parameters:
- name: IDENTIFIER
description: Number to append to the name of resources
value: '1'
required: true
- name: IMAGE
description: Image to use for deploymentConfig
value: gcr.io/google-containers/pause-amd64:3.0
required: false
- name: ENV_VALUE
description: Value to use for environment variables
generate: expression
from: "[A-Za-z0-9]{255}"
required: false
labels:
template: deployment-config-template
可在命名空间中运行的应用程序 pod 数量取决于服务数量以及环境变量用于服务发现时的服务名称长度。系统中的
ARG_MAX
为新进程定义最大参数长度,默认设置为
2097152 KiB
。Kubelet 将环境变量注入到要在命名空间中运行的每个 pod 中,包括:
<SERVICE_NAME>_SERVICE_HOST=<IP>
<SERVICE_NAME>_SERVICE_PORT=<PORT>
<SERVICE_NAME>_PORT=tcp://<IP>:<PORT>
<SERVICE_NAME>_PORT_<PORT>_TCP=tcp://<IP>:<PORT>
<SERVICE_NAME>_PORT_<PORT>_TCP_PROTO=tcp
<SERVICE_NAME>_PORT_<PORT>_TCP_PORT=<PORT>
<SERVICE_NAME>_PORT_<PORT>_TCP_ADDR=<ADDR>
如果参数长度超过允许的值,服务名称中的字符数会受到影响,命名空间中的 pod 将开始失败。例如,在一个带有 5000 服务的命名空间中,服务名称的限制为 33 个字符,它可让您在命名空间中运行 5000 个 Pod。
优化存储有助于最小化所有资源中的存储使用。通过优化存储,管理员可帮助确保现有存储资源以高效的方式工作。
了解持久性存储选项,以便可以优化 OpenShift Container Platform 环境。
表 11.1. 可用存储选项
存储类型
|
描述
|
例子
|
Block
在操作系统 (OS) 中作为块设备
适用于需要完全控制存储,并绕过文件系统在低层直接操作文件的应用程序
也称为存储区域网络 (SAN)
不可共享,这意味着,每次只有一个客户端可以挂载这种类型的端点
AWS EBS 和 VMware vSphere 支持在 OpenShift Container Platform 中的原生动态持久性卷 (PV)置备 。
在 OS 中作为要挂载的文件系统导出
也称为网络附加存储(Network Attached Storage,NAS)
取决于不同的协议、实现、厂商及范围,其并行性、延迟、文件锁定机制和其它功能可能会有很大不同。
RHEL NFS、NetApp NFS
[1]
和供应商 NFS
Object
通过 REST API 端点访问
可配置用于 OpenShift Container Platform Registry
应用程序必须在应用程序和(/或)容器中构建其驱动程序。
AWS S3
NetApp NFS 在使用 Trident 插件时支持动态 PV 置备。
目前,OpenShift Container Platform 4.7 不支持 CNS。
下表总结了为给定的 OpenShift Container Platform 集群应用程序推荐的可配置存储技术。
表 11.2. 推荐的、可配置的存储技术
存储类型
|
ROX
1
|
RWX
2
|
Registry
|
扩展的 registry
|
Metrics
3
|
日志记录
|
Apps
|
1
ReadOnlyMany
2
ReadWriteMany
3
Prometheus 是用于指标数据的底层技术。
4
这不适用于物理磁盘、虚拟机物理磁盘、VMDK 、NFS 回送、AWS EBS 和 Azure 磁盘。
5
对于指标数据,使用
ReadWriteMany
(RWX) 访问模式的文件存储是不可靠的。如果使用文件存储,请不要在配置用于指标数据的持久性卷声明(PVC)上配置 RWX 访问模式。
6
用于日志记录,使用任何共享存储都将是一个反模式。每个 elasticsearch 都需要一个卷。
7
对象存储不会通过 OpenShift Container Platform 的 PV 或 PVC 使用。应用程序必须与对象存储 REST API 集成。
Block
Yes
4
Yes
4
Configurable
5
Configurable
6
Not configurable
7
扩展的容器镜像仓库(registry)是一个 OpenShift Container Platform 容器镜像仓库,它有两个或更多个 pod 运行副本。
测试显示在 Red Hat Enterprise Linux(RHEL)中使用 NFS 服务器作为核心服务的存储后端的问题。这包括 OpenShift Container Registry 和 Quay,Prometheus 用于监控存储,以及 Elasticsearch 用于日志存储。因此,不建议使用 RHEL NFS 作为 PV 后端用于核心服务。
市场上的其他 NFS 实现可能没有这些问题。如需了解更多与此问题相关的信息,请联络相关的 NFS 厂商。
在一个非扩展的/高可用性 (HA) OpenShift Container Platform registry 集群部署中:
存储技术不需要支持 RWX 访问模式。
存储技术必须保证读写一致性。
首选存储技术是对象存储,然后是块存储。
对于应用于生产环境工作负载的 OpenShift Container Platform Registry 集群部署,我们不推荐使用文件存储。
在扩展的/HA OpenShift Container Platform registry 集群部署中:
存储技术必须支持 RWX 访问模式。
存储技术必须保证读写一致性。
首选存储技术是对象存储。
支持 Amazon Simple Storage Service(Amazon S3)、Google Cloud Storage(GCS)、Microsoft Azure Blob Storage 和 OpenStack Swift。
对象存储应该兼容 S3 或 Swift。
对于非云平台,如 vSphere 和裸机安装,唯一可配置的技术是文件存储。
块存储是不可配置的。
在 OpenShift Container Platform 托管的 metrics 集群部署中:
首选存储技术是块存储。
对象存储是不可配置的。
在带有生产环境负载的托管 metrics 集群部署中不推荐使用文件存储。
在 OpenShift Container Platform 托管的日志集群部署中:
首选存储技术是块存储。
对象存储是不可配置的。
应用程序的用例会根据不同应用程序而不同,如下例所示:
支持动态 PV 部署的存储技术的挂载时间延迟较低,且不与节点绑定来支持一个健康的集群。
应用程序开发人员需要了解应用程序对存储的要求,以及如何与所需的存储一起工作以确保应用程序扩展或者与存储层交互时不会出现问题。
不建议在
Write
密集型工作负载(如
etcd
)中使用 RAID 配置。如果您使用 RAID 配置运行
etcd
,您可能会遇到工作负载性能问题的风险。
Red Hat OpenStack Platform(RHOSP)Cinder: RHOSP Cinder 倾向于在 ROX 访问模式用例中使用。
数据库:数据库(RDBMS 、nosql DBs 等等)倾向于使用专用块存储来获得最好的性能。
etcd 数据库必须具有足够的存储和适当的性能容量才能启用大型集群。有关监控和基准测试工具的信息,以建立基本存储和高性能环境,请参阅
推荐 etcd 实践
。
下表总结了 OpenShift Container Platform 组件写入数据的主要目录。
表 11.3. 用于存储 OpenShift Container Platform 数据的主目录
目录
|
备注
|
大小
|
预期增长
|
/var/log
所有组件的日志文件。
10 到 30 GB。
日志文件可能会快速增长 ; 大小可以通过增加磁盘或使用日志轮转来管理。
/var/lib/etcd
用于存储数据库的 etcd 存储。
小于 20 GB。
数据库可增大到 8 GB。
随着环境增长会缓慢增长。只存储元数据。
每多加 8 GB 内存需要额外 20-25 GB。
/var/lib/containers
这是 CRI-O 运行时的挂载点。用于活跃容器运行时的存储,包括 Pod 和本地镜像存储。不适用于 registry 存储。
有 16 GB 内存的节点需要 50 GB。请注意,这个大小不应该用于决定最小集群要求。
每多加 8 GB 内存需要额外 20-25 GB。
增长受运行容器容量的限制。
/var/lib/kubelet
pod 的临时卷(Ephemeral volume)存储。这包括在运行时挂载到容器的任何外部存储。包括环境变量、kube secret 和不受持久性卷支持的数据卷。
如果需要存储的 pod 使用持久性卷,则最小。如果使用临时存储,可能会快速增长。
|
OpenShift Container Platform HAProxy 路由器扩展以优化性能。
|
|
|
|
|
|
|
|
|