K8S启用非安全内核参数

一、缘由

我司从云主机向k8s迁移的过程中,由于在云主机上对内核参数进行过优化,所以尽量想K8s也和云主机的内存参数保持一致。

二、解决办法:

k8s并不是支持所有的linux的内核参数,具体支持情况看k8s集群环境和参考官方文档

实际设定还是结合产品自身用以下方式进行操作了,原则就是pod镜像系统里面进去看没有的就不能开启了,具体进容器里面看一下/proc/sys/的文件信息。

1、设置集群的PSP

1.1 解释

可以通过在 PodSecurityPolicy 的 forbiddenSysctlsallowedUnsafeSysctls 字段中,指定sysctl 或填写 sysctl 匹配模式来进一步为 Pod 设置 sysctl 参数。 sysctl 参数匹配模式以 * 字符结尾,如 kernel.*。 单独的 * 字符匹配所有 sysctl 参数。

以下示例设置启用了以 kernel.msg 为前缀的非安全的 sysctl 参数,同时禁用了 sysctl 参数 kernel.shm_rmid_forced

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: sysctl-psp
spec:
  allowedUnsafeSysctls:
  - kernel.msg*
  forbiddenSysctls:
  - kernel.shm_rmid_forced
 ...

1.2 具体操作

  1. 通过kubectl describe PodSecurityPolicy 查询psp内容,看是否有内核参数的相关内容

  2. 通过kubectl edit PodSecurityPolicy 修改psp内容,加入allowed的内核参数的配置

  3. 再次查询psp的内容,确认修改是否生效。

2、启用非安全的sysctl参数

2.1 解释

所有的安全sysctl参数都默认启用。

集群管理员只有在一些非常特殊的情况下(如:高可用或实时应用调整), 才可以启用特定的 非安全的 sysctl 参数。 如需启用 非安全的 sysctl 参数,请你在每个节点上分别设置 kubelet 命令行参数。例如:

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

2.2 具体操作

  1. 在所有的node节点上找到kubelet启动的配置文件,比如/etc/systemd/system/kubelet.service.d/10-kubeadm.conf

  2. 在ExecStart=后面添加启动非安全内存参数的配置--allowed-unsafe-sysctls=net.core.somaxconn

    [Service]
    Environment="KUBELET_EXTRA_ARGS=--node-labels=alibabacloud.com/nodepool-"
    .............................................
    ExecStart=
    ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_SYSTEM_PODS_ARGS $KUBELET_NETWORK_ARGS $KUBELET_DNS_ARGS $KUBELET_AUTHZ_ARGS $KUBELET_
    CGROUP_ARGS $KUBELET_CERTIFICATE_ARGS $KUBELET_EXTRA_ARGS $KUBELET_CUSTOMIZED_ARGS  --allowed-unsafe-sysctls=net.core.somaxconn,kernel.msgmax,net.i
    pv4.*,net.core.netdev_max_backlog,net.nf_conntrack_max,net.netfilter.nf_conntrack_tcp_timeout_established
    
  3. 重启kubelet,systemctl daemon-reload && systemctl restart kubelet。若启动不成功,请查看日志

  4. ps -ef|grep kubelet 确认参数已生效

    /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --max-pods 256 --pod-max-pids 16384 --pod-manifest-path=/etc/kubernetes/manifests --feature-gates=IPv6DualStack=true --network-plugin=cni .................................
    --system-reserved=cpu=100m,memory=1280Mi --kube-reserved=cpu=100m,memory=1280Mi --kube-reserved=pid=1000 --system-reserved=pid=1000 --allowed-unsafe-sysctls=net.core.somaxconn,kernel.msgmax,net.ipv4.*,net.core.netdev_max_backlog,net.nf_conntrack_max,net.netfilter.nf_conntrack_tcp_timeout_established
    

3、设置Pod的Sysctl参数

apiVersion: v1
kind: Pod
metadata:
  name: sysctl-example
spec:
  securityContext:
    sysctls:
    - name: kernel.shm_rmid_forced
      value: "0"
    - name: net.core.somaxconn
      value: "1024"
    - name: kernel.msgmax
      value: "65536"
  ...

注意:deployment的sysctl参数设置在spec.template.spec.securityContext.sysctls

三、其他解决方案

1、使用 initContainers

如果希望设置内核参数更简单通用,可以在 initContainer 中设置,不过这个要求给 initContainer 打开 privileged 权限。

apiVersion: v1
kind: Pod
metadata:
  name: sysctl-example-init
spec:
  initContainers:
  - image: busybox
    command:
    - sh
    - -c
    - |
      sysctl -w net.core.somaxconn=65535
      sysctl -w net.ipv4.ip_local_port_range="1024 65535"
      sysctl -w net.ipv4.tcp_tw_reuse=1
      sysctl -w fs.file-max=1048576
    imagePullPolicy: Always
    name: setsysctl
    securityContext:
      privileged: true
  containers:
  ......

2、使用 tuning CNI 插件统一设置 sysctl

如果想要为所有 Pod 统一配置某些内核参数,可以使用 tuning 这个 CNI 插件来做:

{
  "name": "mytuning",
  "type": "tuning",
  "sysctl": {
          "net.core.somaxconn": "500",
          "net.ipv4.tcp_tw_reuse": "1"
  }
}

四、参考文档


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 lxwno.1@163.com

×

喜欢就点赞,疼爱就打赏