K8S实用整理(10)-Kubernetes配置POD内核参数sysctl
测试环境/生产环境中,docker创建oracle容器时,需配置一些内核参数--sysctl,以保证oracle或其他应用正常运行,创建命令如下。
docker run -itd --restart=always --net=host \
--name=centos01 --hostname=centos01 \
--sysctl kernel.msgmnb=13107200 \
--sysctl kernel.msgmni=256 \
--sysctl kernel.msgmax=65536 \
--sysctl kernel.shmmax=69719476736 \
--sysctl kernel.sem='500 256000 250 1024' \
-v /mnt:/update \
centos /bin/bash
docker exec centos01 sysctl -a |grep -E \
'kernel.msgmnb|kernel.msgmni|kernel.msgmax|kernel.shmmax|kernel.sem'
--sysctl kernel.msgmnb=13107200 \ --sysctl kernel.msgmni=256 \ --sysctl kernel.msgmax=65536 \ --sysctl kernel.shmmax=69719476736 \ --sysctl kernel.sem='500 256000 250 1024' \ -v /mnt:/update \ centos /bin/bash docker exec centos01 sysctl -a |grep -E \ 'kernel.msgmnb|kernel.msgmni|kernel.msgmax|kernel.shmmax|kernel.sem' docker run -itd --restart=always --net=macvlan_br0 --ip=21.1.9.11 \ --name=U00-DB1 --hostname=U00-DB1 \ --sysctl kernel.msgmnb=13107200 \ --sysctl kernel.msgmni=256 \ --sysctl kernel.msgmax=65536 \ --sysctl kernel.shmmax=69719476736 \ --sysctl kernel.sem='500 256000 250 1024' \ -v /mnt/update:/update \ 172.28.2.2:4000/rh6-db1:20171212 /bin/bash
那么k8s创建POD时,需要怎么处理呢?
1、在对应节点修改kubelet启动参数,Enabling Unsafe Sysctls
修改方法参见:K8S实用整理(08)-kubelet启动参数修改方法(配置Enabling Unsafe Sysctls) http://www.cnblogs.com/DaweiJ/articles/8529706.html
kubelet --experimental-allowed-unsafe-sysctls 'kernel.msg*,kernel.shmmax,kernel.sem,net.ipv4.route.min_pmtu'
2、编辑pod.yml
apiVersion: v1
kind: Pod
metadata:
name: centos1
labels:
app: test
annotations:
security.alpha.kubernetes.io/unsafe-sysctls: kernel.msgmnb=13107200,kernel.msgmni=256,kernel.msgmax=65536,kernel.shmmax=69719476736,kernel.sem=500 256000 250 1024
spec:
# restartPolicy: Always
nodeSelector:
cslckind1: test
containers:
- name: centos1
image: 172.28.2.2:4000/sie:20180112
# imagePullPolicy: IfNotPresent
command:
- sleep
- "360000"
# - /bin/bash
# - while true; do sleep 1; done
# ports:
# - containerPort: 80
# protocol: TCP
3、node1添加label
kubectl label node node1 cslckind1=test
4、创建pod查看
daweij@master:~/stady01/ipctest$ kubectl apply -f centos1.yml pod "centos1" created
若对应节点kubelet未配置,则会报下述类似错误:
daweij@master:~/stady01/ipctest$ kubectl get pods --show-all
NAME READY STATUS RESTARTS AGE
centos1 0/1 SysctlForbidden 0 20m
配置正确后,查看结果为:
daweij@master:~/stady01/ipctest$ kubectl get pod NAME READY STATUS RESTARTS AGE busybox-7c6c97f7cb-jnh4f 1/1 Running 1 22h centos1 1/1 Running 0 3s daweij@master:~/stady01/ipctest$ kubectl exec centos1 -i -t /bin/bash [root@centos1 /]# sysctl -a |grep -E 'kernel.msgmnb|kernel.msgmni|kernel.msgmax|kernel.shmmax|kernel.sem' kernel.msgmax = 65536 kernel.msgmnb = 13107200 kernel.msgmni = 256 error: "Operation not permitted" reading key "kernel.unprivileged_userns_apparmor_policy" kernel.sem = 500 256000 250 1024 kernel.sem_next_id = -1 kernel.shmmax = 69719476736 error: "Input/output error" reading key "net.ipv6.conf.all.stable_secret" error: "Input/output error" reading key "net.ipv6.conf.default.stable_secret" error: "Input/output error" reading key "net.ipv6.conf.eth0.stable_secret" error: "Input/output error" reading key "net.ipv6.conf.lo.stable_secret"
官网相关内容:
https://kubernetes.io/docs/concepts/cluster-administration/sysctl-cluster/
Enabling Unsafe Sysctls
With the warning above in mind, the cluster admin can allow certain unsafe sysctls for very special situations like e.g. high-performance or real-time application tuning. Unsafe sysctls are enabled on a node-by-node basis with a flag of the kubelet, e.g.:
$ kubelet --experimental-allowed-unsafe-sysctls 'kernel.msg*,net.ipv4.route.min_pmtu' ...
For minikube, this can be done via the extra-config
flag:
$ minikube start --extra-config="kubelet.AllowedUnsafeSysctls=kernel.msg*,net.ipv4.route.min_pmtu"...
Only namespaced sysctls can be enabled this way.
Setting Sysctls for a Pod
The sysctl feature is an alpha API in Kubernetes 1.4. Therefore, sysctls are set using annotations on pods. They apply to all containers in the same pod.
Here is an example, with different annotations for safe and unsafe sysctls:
apiVersion: v1
kind: Pod
metadata:
name: sysctl-example
annotations:
security.alpha.kubernetes.io/sysctls: kernel.shm_rmid_forced=1
security.alpha.kubernetes.io/unsafe-sysctls: net.ipv4.route.min_pmtu=1000,kernel.msgmax=1 2 3
spec:
...
Note: a pod with the unsafe sysctls specified above will fail to launch on any node which has not enabled those two unsafe sysctls explicitly. As with node-level sysctls it is recommended to use taints and toleration feature or taints on nodes to schedule those pods onto the right nodes.
PodSecurityPolicy Annotations
The use of sysctl in pods can be controlled via annotations on the PodSecurityPolicy.
Here is an example, it authorizes binding user creating pod with corresponding safe and unsafe sysctls.
apiVersion: extensions/v1beta1
kind: PodSecurityPolicy
metadata:
name: sysctl-psp
annotations:
security.alpha.kubernetes.io/sysctls: 'kernel.shm_rmid_forced'
security.alpha.kubernetes.io/unsafe-sysctls: 'net.ipv4.route.*,kernel.msg*'
spec:
...
kubenetes相关内容如下:
背景介绍
sysctl是一个允许改变正在运行中的Linux系统内核参数的接口。
可以通过sysctl修改Linux系统内核中的TCP/IP 堆栈和虚拟内存系统的高级选项,而且不需要重新启动Linux系统,就可以实现优化Linux系统和提高应用进程运行性能。
通过Linux系统中的/proc虚拟文件系统来实现动态配置Linux系统内核参数,在/proc/sys目录下有Linux系统绝大多数的内核参数。
这些内核参数可以在Linux系统运行时进行修改,并且不需要重新启动Linux系统便可以立刻生效。
但是这种修改在重新启动Linux系统后便会失效,要是想永久生效的话,需要更改配置文件/etc/sysctl.conf中相应的内核参数配置项。
可以通过下面命令获取sysctl可以操作的所有内核参数配置项和已经配置的数值:
# sysctl –a
这些内核参数主要包括下面几类配置项:
- 全局内核配置项:以“kernel.”为配置项前缀,举例:
- kernel.shmmax = 33554432(共享内存段的最大尺寸,以字节为单位)
- kernel.threads-max = 139264(Linux内核所能使用的线程最大数量)
- 网络配置项:以“net.”为配置项前缀,举例:
- net.ipv4.ipfrag_low_thresh = 196608(用于IP分片汇聚的最小内存用量)
- net.ipv4.ipfrag_high_thresh = 262144(用于IP分片汇聚的最大内存用量)
- 虚拟内存配置项:以“vm.”为配置项前缀,举例:
- vm.swappiness = 60(减少系统对于swap频繁的写入,将加快应用程序之间的切换,有助于提升系统性能)
- vm.dirty_ratio = 40(该文件表示如果进程产生的废数据到达系统整体内存的百分比,此时进程自信把废数据写回磁盘)
- 设备专用配置项:以“dev.”为配置项前缀,举例:
- dev.raid.speed_limit_max = 200000(需要初始化同步RAID的同步最大速度限制)
- dev.raid.speed_limit_min = 1000(需要初始化同步RAID的同步最小速度限制)
- 文件系统专用配置项:以“fs.”为配置项前缀
- fs.file-max = 779703(可以分配的文件句柄的最大数目)
- fs.file-nr = 3930 0 779703(已分配文件句柄的数目,已使用文件句柄的数目,文件句柄的最大数目,该文件是只读的,仅用于显示信息)
容器相关内核参数
上面介绍了通过sysctl可以操作Linux系统内核参数,在这些内核参数中,有些不但是操作系统全局级别的内核参数,还是命名空间级别的内核参数。
对于容器来说,是通过命名空间实现隔离的,那么就意味着这些命名空间级别的参数是容器相关的内核参数。
Linux系统命名空间的分类如下:
命名空间级别的内核参数包括:
- kernel.shm*(内核中共享内存相关参数),举例:
- kernel.shmall = 3774873(可以使用的共享内存的总量)
- kernel.shmmax = 15461882265(单个共享内存段的最大值)
- kernel.msg*(内核中SystemV消息队列相关参数)
- kernel.msgmnb = 16384(每个消息队列的最大字节限制)
- kernel.msgmni = 128(同时运行的最大的消息队列个数)
- kernel.sem(内核中信号量参数)
- kernel.sem = 250 32000 100 128(每个信号集中的最大信号量数目、系统范围内的最大信号量总数目、每个信号发生时的最大系统操作数目、系统范围内的最大信号集总数目)
- fs.mqueue.*(内核中POSIX消息队列相关参数)
- fs.mqueue. msg_max = 32678(队列里缓存的软最大消息数目)
- fs.mqueue. msgsize_max = 8192(最大消息长度上限)
- net.*(内核中网络配置项相关参数)
- net.ipv4.ipfrag_low_thresh = 196608(用于IP分片汇聚的最小内存用量)
- net.ipv4.ipfrag_high_thresh = 262144(用于IP分片汇聚的最大内存用量)
新特性
(docker 1.12之后版本支持--sysctl修改容器相关内核参数)
因为sysctl可以修改命名空间级别的内核参数,所以在Kubernetes1.4中通过sysctl来配置POD中Linux内核参数的功能。
通过修改POD中Linux内核参数,可以优化POD性能,提升POD中容器运行效率。在Kubernetes1.4中这还是一个阿尔法特性。
修改Linux内核参数存在安全风险,修改错误很可能会降低系统性能,甚至会引起系统崩溃,所以需要谨慎对待。
在Kubernetes1.4中将命名空间级别的内核参数分成了两类,一类是安全的内核参数,一类是不安全的内核参数。
所谓安全的命名空间级别内核参数,就是要能够实现相同节点上不同POD之间的完全隔离,要满足如下条件:
- 不能对相同节点上其他POD产生任何影响
- 不能对节点上操作系统健康造成影响
- 不能在POD资源限制以外获取更多的CPU和内存资源
根据上面三个条件可以发现,大多数的命名空间级别内核参数都不是安全的。
在Kubernetes1.4中,认为下面的命名空间级别内核参数是安全的:
- kernel.shm_rmid_forced = 1(表示是否强制将共享内存和一个进程联系在一起,这样的话可以通过杀死进程来释放共享内存)
- net.ipv4.ip_local_port_range =1024 65000(表示允许使用的端口范围)
- net.ipv4.tcp_syncookies = 1(表示是否打开TCP同步标签,同步标签可以防止一个套接字在有过多试图连接时引起过载)
在Kubernetes以后的版本中,还会继续扩充安全的命名空间级别内核参数。
在Kubernetes中,所有安全的命名空间级别内核参数默认都是启用状态的,所有不安全的命名空间级别内核参数默认都是禁用状态的,如果想设置不安全的内核参数,需要Kubernetes管理员手工启用。
如果管理员没有手工启用不安全的内核参数,那么Kubernetes仍然会进行调度,将这些带有不安全内核参数的POD分配到节点上,但是这些POD在启动时会失败。
在启动kubelet时通过增加参数“experimental-allowed-unsafe-sysctls”来启用不安全的命名空间级别内核参数:
可以在POD配置文件中设置已经被启用的命名空间级别内核参数:
上面的配置文件在POD中设置了安全的命名空间级内核参数:kernel.shm_rmid_forced;
并且在POD中设置了两个不安全的命名空间级内核参数:net.ipv4.route.min_pmte和kernet.msgmax。
在annotations中的“security.alpha.kubernetes.io/sysctls”参数上设置安全的命名空间级内核参数,
在annotations中的“security.alpha.kubernetes.io/unsafe-sysctls”参数上设置不安全的命名空间级内核参数。