一、缘由
我司从云主机向k8s迁移的过程中,由于在云主机上对内核参数进行过优化,所以尽量想K8s也和云主机的内存参数保持一致。
二、解决办法:
k8s并不是支持所有的linux的内核参数,具体支持情况看k8s集群环境和参考官方文档。
实际设定还是结合产品自身用以下方式进行操作了,原则就是pod镜像系统里面进去看没有的就不能开启了,具体进容器里面看一下/proc/sys/的文件信息。
1、设置集群的PSP
1.1 解释
可以通过在 PodSecurityPolicy 的 forbiddenSysctls
或 allowedUnsafeSysctls
字段中,指定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 具体操作
通过
kubectl describe PodSecurityPolicy
查询psp内容,看是否有内核参数的相关内容通过
kubectl edit PodSecurityPolicy
修改psp内容,加入allowed的内核参数的配置再次查询psp的内容,确认修改是否生效。
2、启用非安全的sysctl参数
2.1 解释
所有的安全sysctl参数都默认启用。
集群管理员只有在一些非常特殊的情况下(如:高可用或实时应用调整), 才可以启用特定的 非安全的 sysctl 参数。 如需启用 非安全的 sysctl 参数,请你在每个节点上分别设置 kubelet 命令行参数。例如:
kubelet --allowed-unsafe-sysctls \
'kernel.msg*,net.core.somaxconn' ...
2.2 具体操作
在所有的node节点上找到kubelet启动的配置文件,比如
/etc/systemd/system/kubelet.service.d/10-kubeadm.conf
在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
重启kubelet,
systemctl daemon-reload && systemctl restart kubelet
。若启动不成功,请查看日志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