You need to enable JavaScript to run this app.
导航
容器网络内核参数优化
最近更新时间:2024.07.15 16:57:20首次发布时间:2024.07.15 16:57:20

容器服务已经对节点网络参数进行了优化和适配,能够满足大部分场景。如果默认的内核参数不适合您的业务场景,支持用户根据自身业务场景对节点或 Pod 的网络参数进行进一步的自定义优化。

注意

  • 修改集群网络内核参数时应该从实际的场景需求出发,并在测试环境中完成充分的测试和小批量验证,观察无异常且符合预期后,再确定是否在生产环境中进行变更。不建议直接调整内核参数,变更不当或测试不充分可能造成集群故障或业务受损。
  • 进行网络参数变更前,请首先了解参数的具体作用。请注意,不同类型或版本的集群环境中,内核参数可能有所不同。
  • 修改节点系统参数具有一定的风险,建议做好充分的评估和测试后,在业务低峰期进行变更修改。

在容器场景中,非 hostNetwork 类型的容器运行在独立的网络命名空间中。因此,容器集群中的内核网络参数主要分为 节点级别的网络参数Pod 级别的网络参数。本文介绍如何修改节点和 Pod 的网络内核参数。

修改节点网络内核参数

说明

  • 此配置方式仅支持修改新增节点的内核参数。包括:新创建节点池中的新增节点和存量节点池修改配置后的新增节点。
  • 如需修改存量节点内核参数的需求,支持通过 ECS 提供的 批量作业 功能进行修改。详情请参见 批量作业概述。使用时,请先确保所有节点都安装完成批量作业客户端后,再执行批量作业。

创建或修改节点池时,支持通过节点池启动脚本配置新增节点的网络内核参数。本文以创建节点池的步骤为例。

  1. 登录 容器服务控制台
  2. 在容器服务的左侧导航栏,选择 集群。在集群列表中,单击目标集群名称,进入集群管理页面。
  3. 在左侧导航栏中选择 节点管理 > 节点池
  4. 单击 创建节点池,并在 高级配置部署执行脚本 文本框内填写修改网络参数的脚本配置。

alt

执行脚本内容举例如下:

#!/bin/bash

# 为节点池添加网络内核参数,实际使用时,需要替换为实际的值。
# 这里有多少条配置修改,就添加多少条配置。
echo "kernel_parameter1 = value1" >> /etc/sysctl.conf
echo "kernel_parameter2 = value2" >> /etc/sysctl.conf
echo "kernel_parameter3 = value3" >> /etc/sysctl.conf

# 应用更改
sysctl -p

echo "end"

说明

上述配置中,kernel_parameter1代表内核参数名,value1代表内核参数值。具体内核参数说明请参见 网络内核参数说明

修改 Pod 网络内核参数

方式一:通过 initContainer 配置

说明

该方式不适用弹性容器实例(VCI)场景。

支持创建工作负载或 Pod 时,通过添加initContainer配置,来定义 Pod 网络内核参数。举例如下:

apiVersion: v1
kind: Pod
metadata:
  name: sysctl-example-init
spec:
  initContainers:
  - image: busybox
    command:
    - sh
    - -c
    - |
      sysctl -w kernel_parameter1 = value1
    imagePullPolicy: Always
    name: netsysctl
    securityContext:
      privileged: true
  containers:
  ...

方式二 :通过 SecurityContext 配置

在 Kubernetes 中,支持通过 Pod 的 sysctl 安全上下文(Security Context)对内核参数进行配置。详情请参考 官方文档

Kubernetes 将 sysctl 参数分为 安全非安全。其中,安全 的 sysctl 参数可以直接配置,主要参数包括:

  • net.ipv4.ip_local_port_range
  • net.ipv4.tcp_syncookies
  • net.ipv4.ping_group_range(从 Kubernetes 1.18 开始)
  • net.ipv4.ip_unprivileged_port_start(从 Kubernetes 1.22 开始)
  • net.ipv4.ip_local_reserved_ports(从 Kubernetes 1.27 开始,需要 kernel 3.16+)
  • net.ipv4.tcp_keepalive_time(从 Kubernetes 1.29 开始,需要 kernel 4.5+)
  • net.ipv4.tcp_fin_timeout(从 Kubernetes 1.29 开始,需要 kernel 4.6+)
  • net.ipv4.tcp_keepalive_intvl(从 Kubernetes 1.29 开始,需要 kernel 4.5+)
  • net.ipv4.tcp_keepalive_probes(从 Kubernetes 1.29 开始,需要 kernel 4.5+)

除上面提及的参数外,其他的参数均为 非安全 的 sysctl 参数,默认禁用。

说明

如需配置 非安全的 sysctl 参数,必须由集群管理员在每个节点上分别手动开启。如未开启,配置了非安全 sysctl 参数的 Pod 仍会被调度,但无法正常启动。

如需启用 非安全 的 sysctl 参数,请在每个节点上执行如下 kubelet 命令。

kubelet --allowed-unsafe-sysctls \
  'kernel.msg*,net.core.somaxconn' ...

在节点上启用 非安全 的 sysctl 参数后,允许通过如下配置,修改 Pod 的网络内核参数。

apiVersion: v1
kind: Pod
metadata:
  name: sysctl-example
spec:
  securityContext:
    sysctls:
    - name: net.ipv4.tcp_keepalive_time
      value: "60"
  ...

注意

Kubernetes 安全上下文(Security Context)提供的配置参数比较有限,配置时需要注意:

  • 注意安全上下文支持的 Kubernetes 版本和内核版本。
  • 配置 Pod 网络内核参数时,建议首先确认是否支持通过安全上下文进行配置。如果支持,优先使用此种方式。否则再考虑通过 initContainer 方式配置。
  • 在 VCI 场景中,大部分网络参数(net.ipv4.ip_local_port_range net.ipv4.tcp_syncookies除外)都支持通过安全上下文的方式进行配置,详情请参见 配置安全上下文

网络内核参数说明

常见网络内核参数的说明,如下表所示。

参数配置范围参数说明配置建议
net.core.netdev_max_backlog节点级别用于设置每个网络接口的最大接收数据包队列长度。当网络接口接收到数据包时,这些数据包首先被放置到接收队列(receive queue)中等待软中断处理。如果接收队列已满,新的数据包将被丢弃。当主机侧的处理性能相对不足时,可以适当调高该值。

net.core.optmem_max

节点级别

该参数为 Linux 内核参数,用于设置系统中所有套接字默认的最大的套接字缓冲区大小,以字节为单位。
这个参数影响套接字缓冲区的优化策略。当一个新套接字被创建时,系统会分配一定数量的内存作为套接字缓冲区。该参数可以限制这个缓冲区的最大大小,避免不必要的内存使用。

可以根据业务情况,适当提高该值,以提高 socket 的缓冲区大小。
容器服务集群的默认值为 20480。

net.ipv4.neigh.default.gc_stale_time
net.ipv4.neigh.default.gc_thresh1
net.ipv4.neigh.default.gc_thresh2
net.ipv4.neigh.default.gc_thresh3

节点级别

  • gc_stale_time 用于设置系统中 ARP 缓存项(即邻居缓存项)过期的时间。
  • gc_thresh1 表示最小可保留的表项数量,如果表项数量小于此值 GC(Garbage collector)不进行回收操作,默认为128。
  • gc_thresh2 当表项数量超过此值时,GC 将会清空大于 5 秒的表项,默认为 512。
  • gc_thresh3 最大可允许的非永久表项数量。如果系统拥有庞大的接口数量,或者直连了大量的设备,应增大此值。默认值为 1024。

这几个内核参数用于设置节点 ARP 表项的回收和阀值。在容器服务的 VPC-CNI 网络集群中,流量的访问会依赖系统 ARP 表。

说明

容器服务集群已经对内核参数进行了调优,默认值分别为:

  • gc_thresh1:10240
  • gc_thresh2:20480
  • gc_thresh3:40960

在更大规模的集群中,您可以根据需求再对这些值进行调整。

net.ipv4.tcp_mem

节点级别

用于设置 TCP 的总缓冲区大小/范围。格式为[min, default, max],参数的单位均为 page,每个 page 的大小为 4kb,具体取值是在系统启动时,根据系统内存大小计算得到的。

  • 当 TCP 内存小于 min 值时,接收缓冲区不需要进行自动调节。
  • 当 TCP 内存处于 min 值和 default 值之间时,内核开始调节接收缓冲区的大小。
  • 当 TCP 内存大于 max 值时,内核不再为 TCP 分配新内存,此时无法继续建立新连接。

该值根据不同规格,系统默认值一般不同。作为节点的 TCP 缓冲全局性配置,可以根据场景和规格调高该值。

net.core.somaxconn

Pod 级别

用于设置系统中每一个端口的最大监听队列长度,这是个全局的参数,默认值为 128。限制了每个端口接收新 TCP 连接监听队列的大小。

调大此参数可以一定程度上避免高并发服务遇到突发流量导致失败。
对于 Server 类服务,可以适当调高该值。

net.ipv4.tcp_max_syn_backlog

Pod 级别

最大 TCP 半连接队列/SYN 队列大小,默认值为 1024。
如果队列已满,新的连接请求将被拒绝或丢弃。
该参数较小时,可能会导致 SYN 队列溢出,从而无法处理所有的连接请求。这可能会导致客户端无法成功建立连接,出现连接超时或连接被拒绝的情况。

可以根据业务场景,调大该值,提高服务端的并发连接数。

net.ipv4.tcp_rmem

Pod 级别

用于设置接收缓冲区大小和范围,格式为[min, default, max],默认值分别是[4096, 87380, 6291456],参数的单位均为 byte。

  • 第一个值用于设置接收缓冲区的最小值。
  • 第二个值用于设置接收缓冲区的初始默认值。
  • 第三个值用于设置接收缓冲区的最大值。

可以根据 Pod 的业务场景,调节该值,提高并发连接性能。

net.ipv4.tcp_wmem

Pod 级别

用于设置发送缓冲区大小和范围,格式为[min, default, max]。默认值分别是[4096, 16384, 4194304]

  • 第一个值用于设置发送缓冲区的最小值。
  • 第二个值用于设置发送缓冲区的初始默认值。
  • 第三个值用于设置发送缓冲区的最大值。

可以根据 Pod 的业务场景,调节该值,提高并发连接性能。

net.ipv4.tcp_max_tw_buckets

Pod 级别

用于设置处于TIME_WAIT状态的 TCP 连接的最大值,默认值为 5000,默认值会根据系统内存进行调整。
当系统中处TIME_WAIT状态的 TCP 连接数超过该值时,新关闭的连接就不再经历 TIME_WAIT状态,而是直接关闭并打印警告日志。

当系统的连接数多时,可能就需要根据需要调高该值。该参数值过大时易耗尽节点资源。

net.ipv4.tcp_tw_reuse

Pod 级别

用于设置是否复用处于TIME_WAIT 状态的 TCP 连接,默认为 0,表示禁止复用连接。该配置仅适用于主动发起建立 TCP 连接的一方,也就是仅适用于客户端。
开启该选项后,主动发起建立连接的一方在调用connect()函数时,如果选择的端口,已经被相同四元组的连接占用,那么就判断该连接是否处于TIME_WAIT状态,如果该连接处于TIME_WAIT状态并且TIME_WAIT状态持续时间已超过 1 秒,那么就重用这个连接,然后就可以正常使用该端口了。
该参数只对客户端(反向代理服务器连接 upstream 时也可认为是客户端)有效。

对于大量客户端连接的请求的场景,可以打开该配置,也就是设置成 1,提高性能。
容器服务集群的默认值为 2。

net.ipv4.tcp_fin_timeoutPod 级别指定主动关闭连接方等待被动关闭连接方返回 FIN 报文(第三次挥手)的最长时间,也就是设置主动关闭连接方处于FIN-WAIT-2状态的最长时间,默认为 60 秒。调小该参数,以便加快系统关闭处于FIN_WAIT2状态的 TCP 连接。对于 Server 端服务,如果客户端长时间不关闭连接,会长时间挤FIN_WAIT2状态,进而导致内核 Crash。
net.ipv4.tcp_keepalive_timePod 级别该参数是 TCP 协议中的一个参数,表示 TCP 连接的空闲时间。当一个 TCP 连接在这个时间内没有任何数据传输时,系统会发送一个探测包来检测连接是否还存活。默认值为 7200 秒(2 小时),可以通过修改系统的配置文件来修改参数。TCP 内核超时时间配置,可以根据业务需求进行调整。
net.ipv4.tcp_keepalive_intvlPod 级别探测消息未获得响应时,重发该消息的间隔时间,单位为秒。TCP 内核超时时间配置,可以根据业务需求进行调整。
net.ipv4.tcp_keepalive_probesPod 级别在认定 TCP 连接失效之前,最多发送多少个 keepalive 探测消息。TCP 内核超时时间配置,可以根据业务需求进行调整。
net.netfilter.nf_conntrack_bucketsPod 级别设置 Linux 系统中连接跟踪表(Connection Tracking Table)的哈希桶(buckets)数量。连接跟踪表容量,可视业务场景调整。
net.netfilter.nf_conntrack_maxPod 级别连接跟踪表的大小。 默认值为net.netfilter.nf_conntrack_buckets * 4连接跟踪表最大条数,可视业务场景调整。当连接跟踪表满时,会出现无法连接的现象。