[转帖]给容器设置内核参数

容器,设置,内核,参数 · 浏览次数 : 0

小编点评

**设置内核参数** **namespaced 参数** * 使用 `security.alpha.kubernetes.io/sysctls` annotation 设置参数。 * 在 `kubelet` 中配置 `--experimental-allowed-unsafe-sysctls` 启动参数。 **非 namespaced 参数** * 使用 `security.alpha.kubernetes.io/sysctls` annotation 设置参数。 * 在 `kubelet` 中配置 `--experimental-allowed-unsafe-sysctls` 启动参数。 * 通过 `limits` 命令查看和设置参数。 **注意事项** * 确保设置的参数不会影响其他容器或主机。 * 设置参数之前备份它们。 * 通过 `ulimit` 命令查看和设置硬限制。 * 在容器中设置内核参数可能会影响主机上的设置。

正文

http://www.manongjc.com/detail/55-sgvseudnytygddj.html

 

 
本文章向大家介绍给容器设置内核参数,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
 

怎么给docker容器设置内核参数? 怎么给k8s POD设置内核参数? 为什么给容器设置某些内核参数之后,主机也会受影响?

容器与sysctl

内核方面做了大量的工作,把一部分sysctl内核参数进行了namespace化(namespaced)。 也就是多个容器和主机可以各自独立设置某些内核参数。例如, 可以通过net.ipv4.ip_local_port_range,在不同容器中设置不同的端口范围。

如何判断一个参数是不是namespaced?

运行一个具有privileged权限的容器(参考下一节内容), 然后在容器中修改该参数,看一下在host上能否看到容器在中所做的修改。如果看不到, 那就是namespaced, 否则不是。

目前已经namespace化的sysctl内核参数:

  • kernel.shm*,
  • kernel.msg*,
  • kernel.sem,
  • fs.mqueue.*,
  • net.*.

注意, vm.*并没有namespace化。 比如vm.max_map_count, 在主机或者一个容器中设置它, 其他所有容器都会受影响,都会看到最新的值。

在docker容器中修改sysctl内核参数

正常运行的docker容器中,是不能修改任何sysctl内核参数的。因为/proc/sys是以只读方式挂载到容器里面的。

proc on /proc/sys type proc (ro,nosuid,nodev,noexec,relatime)

要给容器设置不一样的sysctl内核参数,有多种方式。

方法一 --privileged

docker run --privileged -it ubuntu bash

整个/proc目录都是以"rw"权限挂载的

proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)

在容器中,可以任意修改sysctl内核参赛。

注意: 如果修改的是namespaced的参数, 则不会影响host和其他容器。反之,则会影响它们。

如果想在容器中修改主机的net.ipv4.ip_default_ttl参数, 则除了--privileged, 还需要加上 --net=host。

方法二 把/proc/sys bind到容器里面

docker run -v /proc/sys:/writable-sys -it ubuntu bash

然后写bind到容器内的proc文件

echo 62 > /writable-sys/net/ipv4/ip_default_ttl

注意: 这样操作,效果类似于"--privileged", 对于namespaced的参数,不会影响host和其他容器。

方法三 --sysctl

# docker run -it --sysctl 'net.ipv4.ip_default_ttl=63' ubuntu sysctl net.ipv4.ip_default_ttl
net.ipv4.ip_default_ttl = 63

注意:

  • 只有namespaced参数才可以。否则会报错"invalid argument..."
  • 这种方式只是在容器初始化过程中完成内核参数的修改,容器运行起来以后,/proc/sys仍然是以只读方式挂载的,在容器中不能再次修改sysctl内核参数。

kubernetes 与 sysctl

方法一 通过sysctls和unsafe-sysctls annotation

k8s还进一步把syctl参数分为safe和unsafe。 safe的条件:

  • must not have any influence on any other pod on the node
  • must not allow to harm the node’s health
  • must not allow to gain CPU or memory resources outside of the resource limits of a pod.

非namespaced的参数,肯定是unsafe。

namespaced参数,也只有一部分被认为是safe的。

在pkg/kubelet/sysctl/whitelist.go中维护了safe sysctl参数的名单。在1.7.8的代码中,只有三个参数被认为是safe的:

  • kernel.shm_rmid_forced,
  • net.ipv4.ip_local_port_range,
  • net.ipv4.tcp_syncookies

如果要设置一个POD中safe参数,通过security.alpha.kubernetes.io/sysctls这个annotation来传递给kubelet。

metadata:
  name: sysctl-example
  annotations:
    security.alpha.kubernetes.io/sysctls: kernel.shm_rmid_forced=1

如果要设置一个namespaced, 但是unsafe的参数,要使用另一个annotation: security.alpha.kubernetes.io/unsafe-sysctls, 另外还要给kubelet一个特殊的启动参数。

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=123
spec:
  ...

kubelet 增加--experimental-allowed-unsafe-sysctls启动参数

kubelet --experimental-allowed-unsafe-sysctls 'kernel.msg*,net.ipv4.route.min_pmtu'

方法二 privileged POD

如果要修改的是非namespaced的参数, 如vm.*, 那就没办法使用以上方法。 可以给POD privileged权限,然后在容器的初始化脚本或代码中去修改sysctl参数。

创建POD/deployment/daemonset等对象时, 给容器的spec指定securityContext.privileged=true

    spec:
      containers:
      - image: nginx:alpine
        securityContext:
          privileged: true

这样跟"docker run --privileged"效果一样,在POD中/proc是以"rw"权限mount的,可以直接修改相关sysctl内核参数。

ulimit

每个进程都有若干操作系统资源的限制, 可以通过 /proc/$PID/limits 来查看。

$ cat /proc/1/limits 
Limit                     Soft Limit           Hard Limit           Units     
Max cpu time              unlimited            unlimited            seconds   
Max file size             unlimited            unlimited            bytes     
Max data size             unlimited            unlimited            bytes     
Max stack size            8388608              unlimited            bytes     
Max core file size        0                    unlimited            bytes     
Max resident set          unlimited            unlimited            bytes     
Max processes             62394                62394                processes 
Max open files            1024                 4096                 files     
Max locked memory         65536                65536                bytes     
Max address space         unlimited            unlimited            bytes     
Max file locks            unlimited            unlimited            locks     
Max pending signals       62394                62394                signals   
Max msgqueue size         819200               819200               bytes     
Max nice priority         0                    0                    
Max realtime priority     0                    0                    
Max realtime timeout      unlimited            unlimited            us

在bash中有个ulimit内部命令,可以查看当前bash进程的这些限制。

跟ulimit属性相关的配置文件是/etc/security/limits.conf。具体配置项和语法可以通过man limits.conf 命令查看。

systemd给docker daemon自身配置ulimit

在service文件中(一般是/usr/lib/systemd/system/dockerd.service)中可以配置:

[Service]
LimitAS=infinity
LimitRSS=infinity
LimitCORE=infinity
LimitNOFILE=65536
ExecStart=...
WorkingDirectory=...
User=...
Group=...

dockerd 给容器的 缺省ulimit设置

dockerd --default-ulimit nofile=65536:65536

冒号前面是soft limit, 后面是hard limit

给容器指定ulimit设置

docker run -d --ulimit nofile=20480:40960 nproc=1024:2048 容器名

在kubernetes中给pod设置ulimit参数

有一个issue在讨论这个问题: https://github.com/kubernetes/kubernetes/issues/3595

目前可行的办法,是在镜像中的初始化程序中调用setrlimit()系统调用来进行设置。子进程会继承父进程的ulimit参数。

参考文档:

http://tapd.oa.com/CCCM/prong/stories/view/1010166561060564549

https://kubernetes.io/docs/concepts/cluster-administration/sysctl-cluster/

 

与[转帖]给容器设置内核参数相似的内容:

[转帖]给容器设置内核参数

http://www.manongjc.com/detail/55-sgvseudnytygddj.html 本文章向大家介绍给容器设置内核参数,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。 怎么给docker容器设置内核参数? 怎么给

[转帖]Dockerfile中CMD和ENTRYPOINT命令详解

https://www.jb51.net/article/136264.htm Dockerfile中的ENTRYPOINT指令和CMD指令都可以设置容器启动时要执行的命令,但用途是有略微不同的。下面这篇文章主要给大家介绍了关于Dockerfile中CMD和ENTRYPOINT命令的相关资料,需要的

[转帖]一文解决内核是如何给容器中的进程分配CPU资源的?

https://zhuanlan.zhihu.com/p/615570804 现在很多公司的服务都是跑在容器下,我来问几个容器 CPU 相关的问题,看大家对天天在用的技术是否熟悉。 容器中的核是真的逻辑核吗? Linux 是如何对容器下的进程进行 CPU 限制的,底层是如何工作的? 容器中的 thr

[转帖]Docker 容器运行 ivorysql 之体验

当下容器运行应用已经越来越火,只要主机上能运行 Docker,就可以通过镜像来运行应用,不需要考虑环境是否满足应用的运行条件。今天就给大家分享一下使用镜像运行 ivorysql 数据库。如果你容器运行过 postgresql,那就比较容易上手了,几乎是一样的体验,稍微有点差别,后面会说明。 友情提示

[转帖]给你的SpringBoot做埋点监控--JVM应用度量框架Micrometer

https://www.cnblogs.com/yunlongn/p/11343848.html 这世上有三样东西是别人抢不走的:一是吃进胃里的食物,二是藏在心中的梦想,三是读进大脑的书 JVM应用度量框架Micrometer实战 前提 spring-actuator做度量统计收集,使用Promet

[转帖]linux awk数据列, 存入shell数组

awk 赋值给 shell 变量的方法 result='week(now(),-1) 49';var=`echo $result|awk '{print substr($result,16,3)}'`;echo $var;SYSFILE_NAME=`echo "$CONTROL_FILE" | aw

[转帖]OceanBase 在线与离线安装方式详解

各位好,今天给大家带来一篇有关 OceanBase 在线与离线安装方式的解读。首先我们来讨论一下一日常工作中的一些场景,大家经常会遇到以下几种情况: 公司网络条件很不错,在线下载速度很快,安装软件直接从互联网下载安装即可,不需要考虑其他因素;公司人数众多,在线下载速度很慢,下载一个rpm包都要等很久

【转帖】【性能提升神器】STRAIGHT_JOIN

今天给大家下另一个性能提升神器-STRAIGHT_JOIN,在数据量大的联表查询中灵活运用的话,能大大缩短查询时间。 首先来解释下STRAIGHT_JOIN到底是用做什么的: STRAIGHT_JOIN is similar to JOIN, except that the left table i

[转帖]Shell 脚本实现应用服务日志入库 Mysql

今天给大家分享一个 shell 脚本工具,通过 shell 脚本与 mysql 的结合,将某个具体服务的错误输出日志入库到指定的 mysql 表中,以便于进行错误问题的定位与分析。 日常工作中,经常需要和 linux 系统打交道,例如:服务部署、日志和服务状态查看等,而 shell 脚本是和 lin

[转帖]如何判断oracle内存是否够用

https://www.modb.pro/db/431194 给数据库分配的内存,在topas当中看,是属于计算内存,从内存栈分类上来说是共享内存。如果给数据库分配XX GB内存,那么数据库使用的内存不含超过这个限制。但至于这些内存够不够用,就要看业务系统是否能够接受当前的响应时间等性能指标,能接受