IBM Cloud Docs
调整性能

调整性能

如果您具有特定的性能优化需求,那么可以在 IBM Cloud® Kubernetes Service 中更改某些集群组件的缺省设置。

如果选择更改缺省设置,由此带来的风险由您自行承担。 对任何已更改的设置运行测试是您的责任,并且对环境中因更改的设置而导致的任何潜在中断也由您负责。

缺省工作程序节点设置

默认情况下,您的 Worker 节点具有您在创建 Worker 池时选择的 Worker 节点类型的操作系统和计算硬件。

定制操作系统

您可以在 Kubernetes 版本信息 中按集群版本查找受支持操作系统的列表。 集群无法混合使用操作系统或使用不同的操作系统。

要优化工作程序节点,请考虑以下信息。

  • 映像和版本更新: IBM 为您提供工作程序节点更新,例如映像的安全补丁或 Kubernetes 版本。 但是,您可以选择何时将更新应用于工作程序节点。 有关更多信息,请参阅 更新集群,工作程序节点和集群组件
  • 临时修改: 如果登录到 pod 或使用其他过程来修改工作程序节点设置,那么这些修改是临时的。 工作程序节点生命周期操作 (例如自动恢复,重新装入,更新或替换工作程序节点) 将任何修改更改回缺省设置。
  • 持久修改: 要使修改在工作程序节点生命周期操作之间持久存在,请创建使用 init 容器的守护程序集。 有关更多信息,请参阅 修改缺省工作程序节点设置以优化性能

不支持对操作系统的修改。 如果修改缺省设置,那么您负责调试和解决可能发生的问题。

硬件更改

要更改计算硬件 (例如,每个工作程序节点的 CPU 和内存),请在以下选项中进行选择。

修改工作程序节点内核设置以优化性能

集群工作程序节点配置为具有期望满足大多数工作负载需求的稳定性,优化和性能级别。 通常,不建议更改工作程序节点内核设置,因为此类更改可能会产生异常和意外的问题。 但是,如果工作负载具有需要更改内核设置的高度唯一的性能优化需求,那么可以应用定制 Kubernetes daemonset 来更改内核配置。 了解这些更改可能会产生严重的负面后果,并且您 在自行承担风险的情况下实施对内核设置配置的更改。

如果更改内核设置的配置,请确保记录并保存所做的准确更改。 如果针对与集群相关的任何问题开具支持凭单,那么必须指定这些更改。 这些配置更改可能对问题负责,并且可能会要求您在问题调查过程中还原这些更改。 在这种情况下,您将负责还原您实现的任何内核配置更改。

更改缺省内核设置可能会对集群产生负面影响。 请自行进行这些更改。

您可以通过将具有 init 容器 的定制 Kubernetes DaemonSet 应用于集群来更改缺省内核设置。 守护进程集会修改所有现有工作站的设置,并将这些设置应用到群集中配置的任何新工作站。 init 容器确保在工作程序节点上调度其他 pod 之前进行这些修改。 这不会影响任何 pod。

您必须拥有所有命名空间的 Manager IBM Cloud IAM 服务访问角色,才能运行示例特权 initContainer。 在初始化这些部署的容器之后,将删除这些特权。

开始之前 登录您的账户。 如果适用,请将相应的资源组设定为目标。 设置集群的上下文。

  1. 将以下守护程序集保存在名为 worker-node-kernel-settings.yaml 的文件中。 在 spec.template.spec.initContainers 部分中,添加要调整的 sysctl 参数的字段和值。 此示例守护程序集通过 net.core.somaxconn 设置来更改环境中允许的缺省最大连接数,并通过 net.ipv4.ip_local_port_range 设置来更改临时端口范围。
    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: kernel-optimization
      namespace: kube-system
      labels:
        tier: management
        app: kernel-optimization
    spec:
      selector:
        matchLabels:
          name: kernel-optimization
      template:
        metadata:
          labels:
            name: kernel-optimization
        spec:
          hostNetwork: true
          hostPID: true
          hostIPC: true
          initContainers:
            - command:
                - sh
                - -c
                - sysctl -w net.ipv4.tcp_syn_retries="5"; sysctl -w net.ipv4.tcp_fin_timeout="15";
              image: us.icr.io/armada-master/network-alpine:latest
              imagePullPolicy: Always
              name: sysctl
              resources: {}
              securityContext:
                privileged: true
                capabilities:
                  add:
                    - NET_ADMIN
              volumeMounts:
                - name: modifysys
                  mountPath: /sys
          containers:
            - resources:
                requests:
                  cpu: 0.01
              image: us.icr.io/armada-master/network-alpine:latest
              name: sleepforever
              command: ["/bin/sh", "-c"]
              args:
                - >
                  while true; do
                    sleep 100000;
                  done
          volumes:
            - name: modifysys
              hostPath:
                path: /sys
    
  2. 将守护程序集应用于工作程序节点。 这将立即应用更改。
    kubectl apply -f worker-node-kernel-settings.yaml
    

要将工作节点 sysctl 的参数恢复为默认值,请按照以下步骤操作。

  1. 删除守护程序集。 这将除去应用了定制设置的 initContainers
    kubectl delete ds kernel-optimization
    
  2. 重新引导集群中的所有工作程序节点。 工作程序节点恢复为应用了缺省值的联机状态。

优化 pod 性能

如果您具有特定的性能工作负载需求,那么可以更改 pod 网络名称空间上 Linux 内核 sysctl 参数的缺省设置。

要优化应用程序 pod 的内核设置,可以在每个部署的 initContainer 补丁到 pod/ds/rs/deployment YAML 中。 initContainer 将添加到 pod 网络名称空间中要优化其性能的每个应用程序部署。

在开始之前,请确保您拥有所有命名空间的 Manager IBM Cloud IAM 服务访问角色,以运行示例特权 initContainer。 在初始化这些部署的容器之后,将删除这些特权。

  1. 将以下 initContainer 补丁保存在名为 pod-patch.yaml 的文件中,并为要调整的 sysctl 参数添加字段和值。 此示例 initContainer 通过 net.core.somaxconn 设置来更改环境中允许的缺省最大连接数,并通过 net.ipv4.ip_local_port_range 设置来更改临时端口范围。
    spec:
      template:
        spec:
          initContainers:
          - command:
            - sh
            - -c
            - sysctl -e -w net.core.somaxconn=32768;  sysctl -e -w net.ipv4.ip_local_port_range="1025 65535";
            image: alpine:3.6
            imagePullPolicy: IfNotPresent
            name: sysctl
            resources: {}
            securityContext:
              privileged: true
    
  2. 修补每个部署。
    kubectl patch deployment <deployment_name> --patch pod-patch.yaml
    
  3. 如果在内核设置中更改了 net.core.somaxconn 值,那么大多数应用程序可以自动使用更新后的值。 但是,某些应用程序可能会要求您手动更改应用程序代码中的对应值以与内核值相匹配。 例如,如果要调整运行 NGINX 应用程序的 pod 的性能,那么必须更改 NGINX 应用程序代码中 backlog 字段的值以进行匹配。 更多信息,请参阅 NGINX 博客文章

优化网络保持活动 sysctl 设置

如果 pod 长时间运行的 TCP 连接在空闲一段时间时偶尔会断开连接,那么可能有助于更改 pod 的 sysctl keepalive 设置。

缺省情况下,当前无法在集群中的所有 pod 上设置这些 sysctl 保持活动设置。 修改所有 pod 上的设置的最佳方法是使用特权 initContainer。 查看以下示例,了解如何为 test-ns 名称空间中的部署设置 initContainer

部署以下示例 initContainer。 请记住将 containers: 部分更改为您自己的应用程序容器。 然后,initContainer 将为 pod 中的所有常规容器设置 sysctl 设置,因为它们都共享同一个网络名称空间。

```sh {: pre}
kubectl apply -f - << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-sysctl
  namespace: test-ns
  labels:
    run: test-sysctl
spec:
  replicas: 2
  selector:
    matchLabels:
      run: test-sysctl
  template:
    metadata:
      labels:
        run: test-sysctl
    spec:
      initContainers:
      - command:
        - sh
        - -c
        - sysctl -e -w net.ipv4.tcp_keepalive_time=40; sysctl -e -w net.ipv4.tcp_keepalive_intvl=15; sysctl -e -w net.ipv4.tcp_keepalive_probes=6;
        image: us.icr.io/armada-master/alpine:latest
        imagePullPolicy: IfNotPresent
        name: sysctl-init
        resources: {}
        securityContext:
          privileged: true
      containers:
      - name: test-sysctl
        image: us.icr.io/armada-master/alpine:latest
        command: ["sleep", "2592000"]
  EOF
```

调整集群度量值提供程序资源

集群具有由 kube-system 名称空间中的 metrics-server 部署提供的度量服务。 metrics-server 资源请求基于集群中的节点数,并针对每个工作程序节点具有 30 个或更少 pod 的集群进行优化。 度量服务与资源请求的内存和 CPU 限制相匹配。

如果内存请求过低,那么 metrics-service 容器可能“内存耗尽”。 由于 CPU 调速 (如果 CPU 请求过低),它们可能响应非常慢或失败的活动性和就绪性探测器。

内存使用由集群中的 pod 数驱动。 CPU 使用由针对度量值 (HPA,kubectl top nodes / pods 等) 的请求数以及 API 发现请求所驱动。 metrics-server 提供了 Kubernetes API,因此使用 API 发现的客户机 (例如 kubectl ) 即使不使用度量值,也会在 metrics-server 上放置一些负载。

以下症状可能指示需要调整 metrics-server 资源:

  • metrics-server 频繁重启。

  • 删除命名空间会导致命名空间停留在 Terminating 状态,kubectl describe namespace 包括报告度量 API 发现错误的条件。

  • kubectl top podskubectl top nodes、其他 kubectl 命令,或使用 Kubernetes API 记录 Kubernetes 错误(如)的应用程序:

The server is currently unable to handle the request (get pods.metrics.k8s.io)
Discovery failed for some groups, 1 failing: unable to retrieve the complete list of server APIs: metrics.k8s.io/v1beta1: the server is currently unable to handle the request
  • HorizontalPodAutoscalers (HPA) 无法扩展部署。

  • 运行 kubectl get apiservices v1beta1.metrics.k8s.io 会出现类似的状态:

NAME                     SERVICE                      AVAILABLE                      AGE
v1beta1.metrics.k8s.io   kube-system/metrics-server   False (FailedDiscoveryCheck)   139d

修改 metrics-server-config 配置映射

CPU 和内存都具有用于计算总请求的可调参数 "base" 和 "per node" 设置。

  • baseCPU
  • cpuPerNode
  • baseMemory
  • memoryPerNode

其中:

cpuRequest = baseCPU + cpuPerNode * number_of_nodes
memoryRequest = baseMemory + memoryPerNode * number_of_nodes

这些计算中的节点数来自一组“存储区大小”,并且最小大小为 16 个节点。

在核心中请求 CPU,值如 1 或小数值如 100m (100 millicores)。

请求的内存以字节为单位,可选后缀为:

  • 基 2 1Ki = 1024):Ki (千字节),Mi (兆字节),Gi (千兆字节)。
  • 公制 1k = 1000):k, M, G

如果期望集群中的节点数随时间推移而增长 (或仅更改),那么您可能想要调整“每个节点”设置。 如果节点数是静态的,请调整“基本”设置。 最终,将在 metrics-server 部署资源请求中设置总 CPU 和内存值。

您可以通过编辑度量值提供程序的配置映射来更改缺省资源。 请勿直接在 metrics-server 部署中修改资源请求或限制,值将由 metrics-server-nanny 容器覆盖。

缺省 metrics-server-config configmap 为:

apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    addonmanager.kubernetes.io/mode: EnsureExists
    kubernetes.io/cluster-service: "true"
  name: metrics-server-config
  namespace: kube-system
data:
  NannyConfiguration: |-
    apiVersion: nannyconfig/v1alpha1
    kind: NannyConfiguration

此示例显示了定义了所有值的 ConfigMap。

apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    addonmanager.kubernetes.io/mode: EnsureExists
    kubernetes.io/cluster-service: "true"
  name: metrics-server-config
  namespace: kube-system
data:
  NannyConfiguration: |-
    apiVersion: nannyconfig/v1alpha1
    kind: NannyConfiguration
    baseCPU: 200m
    cpuPerNode: 1m
    baseMemory: 40Mi
    memoryPerNode: 6Mi

缺省值如下所示:

baseCPU: 200m
cpuPerNode: 1m
baseMemory: 40Mi
memoryPerNode: 6Mi

编辑 configmap

您可以使用 kubectl edit 命令编辑 ConfigMap:

kubectl edit cm metrics-server-config -n kube-system

添加或编辑要更改的字段,然后保存 ConfigMap 并退出编辑器。

IBM Cloud提供的 metrics-server 监视 ConfigMap 以获取更改并自动更新部署资源请求。 metrics-server 可能最多需要 10 分钟来检测更改,并根据更新后的设置推出一组新的 pod。

复原缺省设置

要将 metrics-server 复原为缺省设置,请删除配置映射。 它将在几分钟内重新创建。

kubectl delete cm metrics-server-config -n kube-system

确定要调整的资源

使用 kubectl describe pod 命令可获取 pod 定义,状态信息和最近的事件:

kubectl get pod -n kube-system -l k8s-app=metrics-server
NAME                             READY   STATUS    RESTARTS   AGE
metrics-server-9fb4947d6-s6sgl   3/3     Running   0          2d4h
kubectl describe pod -n kube-system metrics-server-9fb4947d6-s6sgl

示例输出

Containers:
  metrics-server:
    Container ID:  containerd://fe3d07c9a2541242d36da8097de3896f740c1363f6d2bfd01b8d96a641192b1b
    Image:         registry.ng.bluemix.net/armada-master/metrics-server:v0.4.4
    Image ID:      registry.ng.bluemix.net/armada-master/metrics-server@sha256:c2c63900d0e080c2413b5f35c5a59b5ed3b809099355728cf47527aa3f35477c
    Port:          4443/TCP
    Host Port:     0/TCP
    Command:
      /metrics-server
      --metric-resolution=45s
      --secure-port=4443
      --tls-cert-file=/etc/metrics-server-certs/tls.crt
      --tls-private-key-file=/etc/metrics-server-certs/tls.key
    State:          Running
      Started:      Fri, 10 Sep 2021 17:31:39 +0000
    Last State:     Terminated
      Reason:       OOMKilled
      Exit Code:    137
      Started:      Fri, 10 Sep 2021 05:59:51 +0000
      Finished:     Fri, 10 Sep 2021 17:31:37 +0000
    Ready:          True
    Restart Count:  36

如果 Last State 显示 OOMKilledReason,请以 100Mi 增量或更大的增量增加 metrics-server-config ConfigMap 中的内存请求,直到 metrics-server 保持稳定并运行数小时或更长时间而不需要 OOMkilled

Last State:     Terminated
  Reason:       OOMKilled
  Exit Code:    137

如果 Last state 显示 Reason Error 和事件 (例如以下示例中的事件),请以 100m 增量或更大的增量增加 metrics-server-config ConfigMap 中的 CPU 请求,直到 metrics-server 保持稳定并运行数小时或更长时间而不因探测器超时而终止。

Last State:     Terminated
  Reason: Error
  Exit Code: 137
Events:
Warning Unhealthy 46m (x5 over 80m) kubelet Liveness probe failed: Get "https://198.18.68.236:4443/livez": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
Warning Unhealthy 26m (x65 over 89m) kubelet Liveness probe failed: Get "https://198.18.68.236:4443/livez": net/http: TLS handshake timeout
Warning Unhealthy 21m (x10 over 76m) kubelet Readiness probe failed: Get "https://198.18.68.236:4443/readyz": net/http: request canceled (Client.Timeout exceeded while awaiting headers)
Warning Unhealthy 115s (x93 over 90m) kubelet Readiness probe failed: Get "https://198.18.68.236:4443/readyz": net/http: TLS handshake timeout

您可能需要重复此过程几次以达到稳定的配置,方法是先调整内存请求,然后再调整 CPU 请求。

启用超大页面

经典基础架构 Virtual Private Cloud

您可以在运行 Kubernetes V 1.19 或更高版本的集群中启用 Kubernetes HugePages 调度。 唯一受支持的页面大小为每页 2 MB,这是 Kubernetes 功能部件门的缺省大小。

超大页面调度是 IBM Cloud Kubernetes Service 中的 Beta 功能,可随时更改。

缺省情况下,工作程序节点的 CPU 在 4 KB 的块或页面中分配 RAM。 当应用程序需要更多 RAM 时,系统必须继续查找更多页面,这会降低处理速度。 使用超大页面,您可以将页面大小增加到 2 MB,以提高 RAM 密集型应用程序 (例如,用于人工智能 (AI),物联网 (IoT) 或机器学习工作负载的数据库) 的性能。 有关超大页面的更多信息,请参阅 Linux 内核文档

您可以重新引导工作程序节点,并且超大页面配置仍然存在。 不过,在其他 Worker 节点生命周期操作中,巨量页面配置不会持续存在。 每次更新,重新装入,替换或添加工作程序节点时,都必须重复启用步骤。

  • IBM Cloud IAM 中集群的 操作员 平台访问角色和 管理者 服务访问角色

开始之前 登录您的账户。 如果适用,请将相应的资源组设定为目标。 设置集群的上下文。

  1. 创建 hugepages-ds.yaml 配置文件以启用超大页面。 以下样本 YAML 使用守护程序集在集群中的每个工作程序节点上运行 pod。 您可以使用 vm.nr_hugepages 参数来设置工作程序节点上可用的超大页面的分配。 此示例分配 512 页 (每页 2 MB),用于 1 GB 专门为超大页面分配的 RAM 总量。

    要仅对某些工作程序节点 (例如,用于 RAM 密集型应用程序的工作程序池) 启用超大页面吗? 标记污点 工作程序池,然后将 亲缘关系规则 添加到守护程序集,以便仅将 pod 部署到您指定的工作程序池中的工作程序节点。

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: hugepages-enablement
      namespace: kube-system
      labels:
        tier: management
        app: hugepages-enablement
    spec:
      selector:
        matchLabels:
          name: hugepages-enablement
      template:
        metadata:
          labels:
            name: hugepages-enablement
        spec:
          hostPID: true
          initContainers:
            - command:
                - sh
                - -c
                # Customize allocated Hugepages by providing the value
                - "echo vm.nr_hugepages=512 > /etc/sysctl.d/90-hugepages.conf"
              image: alpine:3.6
              imagePullPolicy: IfNotPresent
              name: sysctl
              resources: {}
              securityContext:
                privileged: true
              volumeMounts:
                - name: modify-sysctld
                  mountPath: /etc/sysctl.d
          containers:
            - resources:
                requests:
                  cpu: 0.01
              image: alpine:3.6
              # once the init container completes, keep the pod running for worker node changes
              name: sleepforever
              command: ["/bin/sh", "-c"]
              args:
                - >
                  while true; do
                      sleep 100000;
                  done
          volumes:
            - name: modify-sysctld
              hostPath:
                path: /etc/sysctl.d
    
  2. 应用之前创建的文件。

    kubectl apply -f hugepages-ds.yaml
    
  3. 确认 pod 正在运行

    kubectl get pods
    
  4. 通过重新引导工作程序节点,重新启动在每个工作程序节点上运行的 kubelet。 请勿 重新装入工作程序节点以重新启动 kubelet。 在启用超大页面上的 kubelet 选取之前重新装入工作程序节点会导致启用失败。

    1. 列出集群中的工作程序节点。
      ibmcloud ks worker ls -c <cluster_name_or_ID>
      
    2. 重新引导工作程序节点。 您可以通过包含多个 -w 选项来重新引导多个工作程序节点,但请确保为应用程序同时运行足够多的工作程序节点以避免中断。
      ibmcloud ks worker reboot -c <cluster_name_or_ID> -w <worker1_ID> -w <worker2_ID>
      
  5. 创建 hugepages-test.yaml 测试 pod,用于将超大页面安装为卷,并使用资源限制和请求来设置该 pod 使用的超大页面资源量。 : 如果使用标签,污点和亲缘关系规则仅在所选工作程序节点上启用超大页面,请在测试 pod 中包含这些相同的规则。

    apiVersion: v1
    kind: Pod
    metadata:
      name: hugepages-example
    spec:
      containers:
      - name: hugepages-example
        image: fedora:34
        command:
        - sleep
        - inf
        volumeMounts:
        - mountPath: /hugepages-2Mi
          name: hugepage-2mi
        resources:
          limits:
            hugepages-2Mi: 100Mi
            memory: 100Mi
          requests:
            memory: 100Mi
      volumes:
      - name: hugepage-2mi
        emptyDir:
          medium: HugePages-2Mi
    
  6. 应用之前创建的 pod 文件。

    kubectl apply -f hugepages-pod.yaml
    
  7. 验证 pod 是否使用超大页面资源。

    1. 检查 pod 是否 正在运行。 如果没有具有超大页面的工作程序节点可用,那么 pod 不会运行。
      kubectl get pods
      
    2. 登录 pod。
      kubectl exec -it <pod> /bin/sh
      
    3. 验证 pod 是否可以查看超大页面的大小。
      ls /sys/kernel/mm/hugepages
      
      示例输出
      hugepages-1048576kB  hugepages-2048kB
      
  8. 可选: 除去启用守护程序集。 请记住,如果以后需要更新,重新装入,替换或添加具有超大页面的工作程序节点,那么必须重新创建守护程序集。

    kubectl -n kube-system delete daemonset hugepages-enablement
    
  9. 每当更新,重新装入,替换或添加工作程序节点时,请重复这些步骤。

要对具有超大页面的工作程序节点进行故障诊断,只能重新引导工作程序节点。 超大页面配置不会在任何其他工作程序节点生命周期操作 (例如,更新,重新装入,替换或添加工作程序节点) 中持久存储。 要从集群中除去超大页面配置,您可以更新,重新装入或替换所有工作程序节点。

更改 Calico 最大传输单元 (MTU)

增大或减小 Calico 插件的最大传输单元 (MTU),以满足环境的网络吞吐量需求。

这些步骤适用于运行 1.29 或更高版本的群集。 此外,所有 VPC 工作节点都支持巨型帧,但传统基础架构只在裸机工作节点上支持巨型帧。

更改最大传输单元 (MTU) 值可能会产生意想不到的结果,尤其是在复杂的网络环境中。 为避免干扰工作流程,强烈建议您在对生产集群进行任何更改之前,先在开发集群上测试这些更改。

默认情况下,IBM Cloud Kubernetes Service集群中的Calico网络插件的 MTU 值为:Satellite集群 1450 字节,Satellite卫星集群 1480 字节。 在大多数情况下,Calico默认 MTU 值足以防止数据包丢弃和分片。 由于大多数主机使用 1500 的 MTU 值,这些默认值为Satellite集群的 VXLAN 标头提供了 50 个额外字节,并为非Satellite集群的 IP 标头提供了 20 个额外字节,这些标头用于某些 pod 到 pod 的集群网络流量。 请注意,群集中的所有工作节点必须使用相同的CalicoMTU 值。

请查看以下可能需要修改缺省 Calico MTU 的情况:

  • 如果需要提高 pod 到 pod 的网络吞吐量,而且集群节点能够使用更高的主机 MTU,那么可以同时增加主机和Calico的 MTU。 这就是所谓的使用“巨型帧”。 典型的巨型帧 MTU 为 9000。 在这种情况下,可以将主机专用网络接口的 MTU 设置为 9000,将CalicoMTU 设置为稍低的值--Satellite群集为 8950,Satellite卫星群集为 8980。 请注意,某些云提供商硬件或资源(如Azure虚拟机)可能不支持巨型帧,或仅支持最大 4000 的 MTU 值。
  • 如果为集群设置了 VPN 连接,那么某些 VPN 连接需要的 Calico MTU 小于缺省值。 请咨询 VPN 服务提供商,以确定是否需要较小的 Calico MTU。
准备工作
如果工作程序节点仍运行缺省 MTU 值,请先增大工作程序节点的 MTU 值,然后再增大 Calico 插件的 MTU 值。 例如,您可以应用以下守护进程设置,将工作节点的 MTU 改为 9000 字节。 请注意,ip link 命令中使用的接口名称因工作程序节点的类型而异。
  • 裸机工作程序节点的示例命令: ip link set dev bond0 mtu 9000;ip link set dev bond1 mtu 9000;
  • 示例命令 VPC Gen 2 工作程序节点: ip link set dev ens3 mtu 9000;
  1. 运行以下命令登录集群工作节点,并在节点之间ping。 由于您的节点 MTU 只设置为 1500 或 1480,因此这次尝试预计会失败。 在接下来的步骤中,您可以再次运行这些命令来验证更改是否成功。

    1. 列出集群中的节点。 保存两个健康节点的名称和 IP 地址。

      kubectl get nodes -o wide
      
    2. 登录到其中一个节点。 指定节点名称。

      kubectl debug --image=us.icr.io/armada-master/network-alpine -it node/<NODE_NAME> -- sh
      
    3. 运行命令从一个节点 ping 到另一个节点。 指定上一步中未引用的节点的 IP 地址。

      ping -c1 -Mdo -s 8972 <OTHER_HOST_IP>
      
  2. 使用以下示例 daemonset 更改节点 MTU。 此 MTU 值适用于节点到节点的流量。 修改 - ip link set dev ens3 mtu <MTU_VALUE> 行,加入 MTU 值(示例使用的 MTU 值为 9000)。 请注意,如果ens3不适合您的节点,您可能还需要更改 "ens3 接口名称。

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      labels:
        app: set-host-mtu
      name: set-host-mtu
      namespace: kube-system
    spec:
      selector:
        matchLabels:
          name: set-host-mtu
      template:
        metadata:
          labels:
            name: set-host-mtu
        spec:
          containers:
          - args:
            - |
              while true; do
                sleep 100000;
              done
            command:
            - /bin/sh
            - -c
            image: us.icr.io/armada-master/network-alpine:latest
            imagePullPolicy: IfNotPresent
            name: sleepforever
            resources:
              requests:
                cpu: 10m
          hostNetwork: true
          initContainers:
          - command:
            - sh
            - -c
            - ip link set dev ens3 mtu 9000
            image: us.icr.io/armada-master/network-alpine:latest
            imagePullPolicy: IfNotPresent
            name: set-host-mtu
            securityContext:
              capabilities:
                add:
                - NET_ADMIN
              privileged: true
            volumeMounts:
            - mountPath: /sys
              name: modifysys
          restartPolicy: Always
          terminationGracePeriodSeconds: 2
          tolerations:
          - operator: Exists
          volumes:
          - hostPath:
              path: /sys
              type: ""
            name: modifysys
      updateStrategy:
        rollingUpdate:
          maxSurge: 0
          maxUnavailable: 1
        type: RollingUpdate
    
  3. 应用守护进程更改节点 MTU 值。

      kubectl apply -f <file_name>
    
  4. 重新运行命令登录节点,并使用较大的数据包大小从一台主机 ping 到另一台主机。 现在您已经增加了节点 MTU 值,"ping 命令有望成功执行。

    kubectl debug --image=us.icr.io/armada-master/network-alpine -it node/<NODE_NAME> -- sh
    
    ping -c1 -Mdo -s 8972 <OTHER_HOST_IP>
    
  5. 使用新的节点 MTU 值测试群集。 在继续更改CalicoMTU 值之前,建议您检查一下,以确保您的应用程序仍能按预期运行。

  6. 运行该命令更新CalicoMTU 值,以便 pod 之间的流量也能使用较大的 MTU。 对于SatelliteCore OS 群集,CalicoMTU 值应比节点 MTU 值少 50 字节。 对于所有其他集群,CalicoMTU 值应小于 20 字节。 例如,如果指定 9000 为节点 MTU,则“CalicoMTU 应为”SatelliteCore OS 群集的 8950,或所有其他群集的 8980。

    kubectl patch installation.operator.tigera.io default --type='merge' -p '{"spec":{"calicoNetwork":{"mtu":<MTU_VALUE>}}}'
    

    您也可以运行 "kubectl edit installation.operator.tigera.io default 直接编辑资源。

  7. 小心重启所有节点,将这些更改应用到所有节点。 在继续执行此步骤之前,请确保已在开发集群上测试了此过程,因为这些更改可能会导致工作负载中断。 要重启节点,建议您逐个 封锁、排空和重启 节点。

如果要在生产群集上完成这些步骤,则应使用与更新或替换生产节点相同的流程。 强烈建议您先在测试群集上测试整个过程,然后再在生产群集上完成这些步骤。

在重启过程中,有些 pod 使用新的较大 MTU,有些 pod 仍使用原来的较小 MTU。 通常情况下,这种情况不会造成问题,因为双方会协商正确的最大数据包大小。 但是,如果阻止 ICMP 数据包,协商可能无法进行,集群可能会出现 pod 连接问题,直到所有重启完成。 至关重要的是,首先要在开发集群上对这一过程进行测试。

禁用端口映射插件

Calico 容器网络接口 (CNI) 的 portmap 插件使您能够使用 hostPort 在工作程序节点上的特定端口上公开应用程序 pod。 通过从集群的 Calico CNI 配置中除去端口映射插件来防止 iptables 性能问题。

当集群中有许多服务 (例如,超过 500 个服务) 或许多服务端口 (例如,针对 10 个或更多服务的每个服务超过 50 个端口) 时,将为这些服务的 Calico 和 Kubernetes 网络策略生成许多 iptables 规则。 使用许多 iptables 规则可能会导致端口映射插件的性能问题,并且可能会阻止将来更新 iptables 规则,或者在未收到任何锁定以在指定时间内更新 iptables 规则时导致 calico-node 容器重新启动。 要防止出现这些性能问题,可以通过从集群的 Calico CNI 配置中除去端口映射插件来将其禁用。

如果必须使用 hostPorts,请勿禁用端口映射插件。

在 Kubernetes V 1.29 和更高版本中禁用端口映射插件

  1. 编辑 default Calico 安装资源。
    kubectl edit installation default -n calico-system
    
  2. spec.calicoNetwork 部分中,将 hostPorts 的值更改为 Disabled
    ...
    spec:
      calicoNetwork:
        hostPorts: Disabled
        ipPools:
        - cidr: 172.30.0.0/16
          encapsulation: IPIPCrossSubnet
          natOutgoing: Enabled
          nodeSelector: all()
        mtu: 1480
        nodeAddressAutodetectionV4:
          interface: (^bond0$|^eth0$|^ens6$|^ens3$)
      kubernetesProvider: OpenShift
      registry: registry.ng.bluemix.net/armada-master/
      variant: Calico
    status:
      variant: Calico
    
  3. 保存并关闭该文件。 您的更改将自动应用。

在 Kubernetes V 1.28 和更低版本中禁用端口映射插件

  1. 编辑 calico-config ConfigMap 资源。

    kubectl edit cm calico-config -n kube-system
    
  2. kubernetes 插件之后的 data.cni_network_config.plugins 部分中,除去 portmap 插件部分。 除去 portmap 部分后,配置如下所示:

    apiVersion: v1
    data:
      calico_backend: bird
      cni_network_config: |-
        {
          "name": "k8s-pod-network",
          "cniVersion": "0.3.1",
          "plugins": [
            {
              "type": "calico",
              ...
            },
            {
              "type": "tuning",
              ...
            },
            {
              "type": "bandwidth",
              ...
            }
          ]
        }
      typha_service_name: calico-typha
      ...
    

    不支持在此 ConfigMap 中更改 Calico 插件的任何其他设置。

  3. 通过重新启动所有 calico-node pod 将更改应用于集群。

    kubectl rollout restart daemonset -n kube-system calico-node