TKE集群给pod设置内核参数

2021-08-26 14:13:02 浏览数 (1)

使用tke的过程中,很多时候我们希望对容器内的一些内核参数进行优化修改,可以通过init容器或者securityContext来修改pod内的内核参数。

1. 常用内核参数说明

网络类

参数

说明

初始化配置

net.ipv4.tcp_tw_recycle

该参数用于快速回收 TIME_WAIT 连接。关闭时,内核不检查包的时间戳。开启时则会进行检查。不建议开启该参数,在时间戳非单调增长的情况下,会引起丢包问题,高版本内核已经移除了该参数。

0

net.core.somaxconn

对应三次握手结束,还没有 accept 队列时的 establish 状态。accept 队列较多则说明服务端 accept 效率不高,或短时间内突发了大量新建连接。该值过小会导致服务器收到 syn 不回包,是由于 somaxconn 表满而删除新建的 syn 连接引起。若为高并发业务,则可尝试增大该值,但有可能增大延迟。

128

net.ipv4.tcp_max_syn_backlog

对应半连接的上限,曾用来防御常见的 synflood 攻击,但当 tcp_syncookies=1 时半连接可超过该上限。

-

net.ipv4.tcp_syncookies

对应开启 SYN Cookies,表示启用 Cookies 来处理,可防范部分 SYN 攻击,当出现 SYN 等待队列溢出时也可继续连接。但开启后会使用 SHA1 验证 Cookies,理论上会增大 CPU 使用率。

1

net.core.rmem_default

net.core.rmem_max

net.ipv4.tcp_mem

net.ipv4.tcp_rmem

这些参数配置了数据接收的缓存大小。配置过大容易造成内存资源浪费,过小则会导致丢包。建议判断自身业务是否属于高并发连接或少并发高吞吐量情形,进行优化配置。rmem_default 的理论最优配置策略为带宽/RTT 积,其配置会覆盖 tcp_rmem,tcp_rmem 不单独配置。rmem_max 配置约为 rmem_default 的5倍。tcp_mem 为总的 TCP 占用内存,一般由 OS 自动配置为 CVM 可用内存的3/32、1/8或3/16,tcp_mem 及 rmem_default 也决定了最大并发链接数。

rmem_default=655360

rmem_max=3276800

net.core.wmem_default

net.core.wmem_max

net.ipv4.tcp_wmem

这些参数用于配置数据发送缓存,腾讯云平台上数据发送通常不会出现瓶颈,可不做配置。

-

net.ipv4.tcp_keepalive_intvl

net.ipv4.tcp_keepalive_probes

net.ipv4.tcp_keepalive_time

这些参数与 TCP KeepAlive 有关,默认为75/9/7200。表示某个 TCP 连接在空闲7200秒后,内核才发起探测,探测9次(每次75秒)不成功,内核才发送 RST。对服务器而言,默认值比较大,可结合业务调整到30/3/1800。

-

net.ipv4.ip_local_port_range

配置可用端口的范围,请按需调整。

-

tcp_tw_reuse

该参数允许将 TIME-WAIT 状态的 socket 用于新的 TCP 连接。对快速重启动某些占用固定端口的链接有帮助,但基于 NAT 网络有潜在的隐患,高版本内核变为0/1/2三个值,并配置为2。

-

net.ipv4.ip_forward

net.ipv6.conf.all.forwarding

IP 转发功能,若用于 docker 的路由转发场景可将其配置为1。

0

net.ipv4.conf.default.rp_filter

该参数为网卡对接收到的数据包进行反向路由验证的规则,可配置为0/1/2。根据 RFC3704建议,推荐设置为1,打开严格反向路由验证,可防止部分 DDos 攻击及防止 IP Spoofing 等。

-

net.ipv4.conf.default.accept_source_route

根据 CentOS 官网建议,默认不允许接受含有源路由信息的 IP 包。

0

net.ipv4.conf.all.promote_secondaries

net.ipv4.conf.default.promote_secondaries

当主 IP 地址被删除时,第二 IP 地址是否成为新的主 IP 地址。

1

net.ipv6.neigh.default.gc_thresh3

net.ipv4.neigh.default.gc_thresh3

保存在 ARP 高速缓存中的最多记录的限制,一旦高速缓存中的数目高于设定值,垃圾收集器将马上运行。

4096

内存类

参数

说明

初始化配置

vm.vfs_cache_pressure

原始值为100,表示扫描 dentry 的力度。以100为基准,该值越大内核回收算法越倾向于回收内存。很多基于 curl 的业务上,通常由于 dentry 的积累导致占满所有可用内存,容易触发 OOM 或内核 bug 之类的问题。综合考虑回收频率和性能后,选择配置为250,可按需调整。

250

vm.min_free_kbytes

该值是启动时根据系统可用物理内存 MEM 自动计算出:4 * sqrt(MEM)。其含义是让系统运行时至少要预留出的 KB 内存,一般情况下提供给内核线程使用,该值无需设置过大。当机器包量出现微突发,则有一定概率会出现击穿 vm.min_free_kbytes,造成 OOM。建议大配置的机器下默认将 vm.min_free_kbytes 配置为总内存的1%左右。

-

kernel.printk

内核 printk 函数打印级别,默认配置为大于5。

5 4 1 7

kernel.numa_balancing

该参数表示可以由内核自发的将进程的数据移动到对应的 NUMA 上,但是实际应用的效果不佳且有其他性能影响,redis 的场景下可以尝试开启。

0

kernel.shmall

kernel.shmmax

shmmax 设置一次分配 shared memory 的最大长度,单位为 byte。shmall 设置一共能分配 shared memory 的最大长度,单位为 page。

kernel.shmmax=68719476736

kernel.shmall=4294967296

进程类

参数

说明

初始化配置

fs.file-max

fs.nr_open

分别控制系统所有进程和单进程能同时打开的最大文件数量:file-max 由 OS 启动时自动配置,近似为10万/GB。nr_open 为固定值1048576,但为针对用户态打开最大文件数的限制,一般不改动这个值,通常设置 ulimit -n 实现,对应配置文件为 /etc/security/limits.conf。

ulimit 的 open files 为100001

fs.nr_open=1048576

kernel.pid_max

系统内最大进程数,官方镜像默认为32768,可按需调整。

-

kernel.core_uses_pid

该配置决定 coredump 文件生成的时候是否含有 pid。

1

kernel.sysrq

开启该参数后,后续可对 /proc/sysrq-trigger 进行相关操作。

1

kernel.msgmnb

kernel.msgmax

分别表示消息队列中的最大字节数和单个最大消息队列容量。

65536

kernel.softlockup_panic

当配置了 softlockup_panic 时,内核检测到某进程 softlockup 时,会发生 panic,结合 kdump 的配置可生成 vmcore,用以分析 softlockup 的原因。

-

IO 类

参数

说明

初始化配置

vm.dirty_background_bytes

vm.dirty_background_ratio

vm.dirty_bytes

vm.dirty_expire_centisecs

vm.dirty_ratio

vm.dirty_writeback_centisecs

这部分参数主要配置 IO 写回磁盘的策略:dirty_background_bytes/dirty_bytes 和 dirty_background_ratio/dirty_ratio 分别对应内存脏页阈值的绝对数量和比例数量,一般情况下设置 ratio。dirty_background_ratio 指当文件系统缓存脏页数量达到系统内存百分之多少时(默认10%)唤醒内核的 flush 等进程,写回磁盘。dirty_ratio 为最大脏页比例,当脏页数达到该比例时,必须将所有脏数据提交到磁盘,同时所有新的 IO 都会被阻塞,直到脏数据被写入磁盘,通常会造成 IO 卡顿。系统先会达到 vm.dirty_background_ratio 的条件然后触发 flush 进程进行异步的回写操作,此时应用进程仍然可以进行写操作,如果达到 vm.dirty_ratio 这个参数所设定的值,此时操作系统会转入同步地处理脏页的过程,阻塞应用进程。

vm.dirty_expire_centisecs 表示脏页能存活的时间,flush 进程会检查数据是否超过了该时间限制,单位为1/100秒。vm.dirty_writeback_centisecs 表示 flush 进程的唤醒周期,单位为1/100秒。

-

2. system -w的方式修改

代码语言:txt复制
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    k8s-app: sysctl-test-1
    qcloud-app: sysctl-test-1
  name: sysctl-test-1
spec:
  selector:
    matchLabels:
      k8s-app: sysctl-test-1
      qcloud-app: sysctl-test-1
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
    type: RollingUpdate
  template:
    metadata:
      labels:
        k8s-app: sysctl-test-1
        qcloud-app: sysctl-test-1
      containers:
      - command:
        - sleep
        - 700d
        image: centos:7
        imagePullPolicy: IfNotPresent
        name: sysctl-test-1
        resources:
          limits:
            cpu: 500m
            memory: 1000Mi
          requests:
            cpu: 50m
            memory: 512Mi
        securityContext:
          privileged: false
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      imagePullSecrets:
      - name: qcloudregistrykey
      initContainers:
      - command:
        - sh
        - -c
        - |
          sysctl -w net.ipv4.tcp_tw_reuse=1
          sysctl -w net.core.somaxconn=65535
          sysctl -w net.ipv4.ip_local_port_range="1024 65535"
          sysctl -w fs.file-max=1048576
        image: busybox:latest
        imagePullPolicy: Always
        name: setsysctl
        resources: {}
        securityContext:
          privileged: true
      restartPolicy: Always

3. 修改配置文件/etc/sysctl.conf的方式修改

代码语言:javascript复制
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    k8s-app: sysctl-test-2
    qcloud-app: sysctl-test-2
  name: sysctl-test-2
spec:
  progressDeadlineSeconds: 600
  replicas: 0
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      k8s-app: sysctl-test-2
      qcloud-app: sysctl-test-2
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
    type: RollingUpdate
  template:
    metadata:
      labels:
        k8s-app: sysctl-test-2
        qcloud-app: sysctl-test-2
    spec:
      containers:
      - command:
        - sleep
        - 700d
        image: centos:7
        imagePullPolicy: IfNotPresent
        name: sysctl-test-2
        resources:
          limits:
            cpu: 500m
            memory: 1000Mi
          requests:
            cpu: 50m
            memory: 512Mi
        securityContext:
          privileged: false
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      imagePullSecrets:
      - name: qcloudregistrykey
      initContainers:
      - command:
        - sh
        - -c
        - |
          echo 'net.ipv4.tcp_tw_reuse=1' >>/etc/sysctl.conf
          echo 'net.core.somaxconn=65535' >>/etc/sysctl.conf
          sysctl -p
        image: busybox:latest
        imagePullPolicy: Always
        name: setsysctl
        resources: {}
        securityContext:
          privileged: true
      restartPolicy: Always

4. securityContext 中指定 sysctls修改

使用该方法,默认情况下有些认为是 unsafe 的参数是不能改的,需要将其配到 kubelet 的 --allowed-unsafe-sysctls 中才可以用。

sysctl 参数分为 安全非安全的安全 sysctl 参数除了需要设置恰当的命名空间外,在同一 node 上的不同 Pod 之间也必须是 相互隔离的。这意味着在 Pod 上设置 安全 sysctl 参数

  • 必须不能影响到节点上的其他 Pod
  • 必须不能损害节点的健康
  • 必须不允许使用超出 Pod 的资源限制的 CPU 或内存资源。

至今为止,大多数 有命名空间的 sysctl 参数不一定被认为是 安全 的。 以下几种 sysctl 参数是 安全的

  • kernel.shm_rmid_forced
  • net.ipv4.ip_local_port_range
  • net.ipv4.tcp_syncookies
  • net.ipv4.ping_group_range (从 Kubernetes 1.18 开始)

以下列出有命名空间的 sysctl 参数,在未来的 Linux 内核版本中,此列表可能会发生变化。

  • kernel.shm*,
  • kernel.msg*,
  • kernel.sem,
  • fs.mqueue.*,
  • net.*(内核中可以在容器命名空间里被更改的网络配置项相关参数)。然而也有一些特例 (例如,net.netfilter.nf_conntrack_maxnet.netfilter.nf_conntrack_expect_max 可以在容器命名空间里被更改,但它们是非命名空间的)。

tke集群的修改可以在节点的kubelet配置文件/etc/kubernetes/kubelet加上allowed-unsafe-sysctls配置,然后在/usr/lib/systemd/system/kubelet.service启动命令加上变量后重新加载配置启动kuebelet

代码语言:javascript复制
[root@VM-0-2-centos system]# cat /etc/kubernetes/kubelet | grep SYSCTL
SYSCTL="--allowed-unsafe-sysctls=kernel.shm*,kernel.msg*,kernel.sem,fs.mqueue.*,net.*"

[root@VM-0-2-centos system]# cat /usr/lib/systemd/system/kubelet.service | grep SYSCTL
ExecStart=/usr/bin/kubelet ${SYSCTL} ${SERIALIZE_IMAGE_PULLS} ${REGISTER_SCHEDULABLE} ${V} ${CLOUD_PROVIDER} ${FAIL_SWAP_ON} ${AUTHORIZATION_MODE} ${CLOUD_CONFIG} ${CLUSTER_DNS} ${IMAGE_PULL_PROGRESS_DEADLINE} ${HOSTNAME_OVERRIDE} ${EVICTION_HARD} ${CLIENT_CA_FILE} ${NON_MASQUERADE_CIDR} ${KUBE_RESERVED} ${MAX_PODS} ${AUTHENTICATION_TOKEN_WEBHOOK} ${POD_INFRA_CONTAINER_IMAGE} ${ANONYMOUS_AUTH} ${KUBECONFIG} ${NETWORK_PLUGIN} ${CLUSTER_DOMAIN}

[root@VM-0-2-centos system]# systemctl daemon-reload
[root@VM-0-2-centos system]# systemctl restart kubelet

修改节点的kubelet配置后,用下面的yaml进行内核参数修改即可

代码语言:javascript复制
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    k8s-app: sysctl-test
    qcloud-app: sysctl-test
  name: sysctl-test
spec:
  selector:
    matchLabels:
      k8s-app: sysctl-test
      qcloud-app: sysctl-test
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
    type: RollingUpdate
  template:
    metadata:
      labels:
        k8s-app: sysctl-test
        qcloud-app: sysctl-test
    spec:
      containers:
      - command:
        - sleep
        - 700d
        image: centos:7
        imagePullPolicy: Always
        name: sysctl-test
        resources:
          limits:
            cpu: 500m
            memory: 1000Mi
          requests:
            cpu: 50m
            memory: 512Mi
        securityContext:
          privileged: true
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      imagePullSecrets:
      - name: qcloudregistrykey
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext:
        sysctls:
        - name: net.ipv4.tcp_tw_reuse
          value: "1"
        - name: net.core.somaxconn
          value: "1024"

0 人点赞