项目组宿主机发生如下情形导致无法操作:

docker在容器中执行宿主机cmd docker 执行宿主机脚本_内核

原因:

这是个从 2014 年就出现了的老 BUG,不管是 CentOS、Ubuntu 还是 Debian 都会碰到。这实际上是 Linux 内核的一个 BUG,在 Docker 中执行 systemctl 命令时触发这个错误,Docker的设计理念是在容器里面不运行后台服务,容器本身就是宿主机上的一个独立的主进程,也可以间接的理解为就是容器里运行服务的应用进程。一个容器的生命周期是围绕这个主进程存在的,所以正确的使用容器方法是将里面的服务运行在前台。再说到systemd,这个套件已经成为主流Linux发行版(比如CentOS7、Ubuntu14+)默认的服务管理,取代了传统的SystemV风格服务管理。systemd维护系统服务程序,它需要特权去会访问Linux内核。而容器并不是一个完整的操作系统,只有一个文件系统,而且默认启动只是普通用户这样的权限访问Linux内核,也就是没有特权,所以自然就用不了!因此,请遵守容器设计原则,一个容器里运行一个前台服务!

解决方法:

1.临时重启宿主机可解决,但治标不治本。以后还会发生类似问题。

2.关闭syslog日志的中向所有人群发消息的功能,只是屏蔽掉发送,并没有根本解决。

systemctl stop rsyslog
vi /etc/rsyslog.conf
# Everybody gets emergency messages
#*.emerg                                                 :omusrmsg:*

注释掉 *.emerg

systemctl start rsyslog

3.升级最新的 Linux 内核,可以从根本解决,但是环境变动太大,需要重新维护,非常麻烦,其他的东西还要改,风险大。

4.避免使用systemctl命令,比如直接通过 /user/sbin/sshd & (&表示后台运行程序)来执行命令。但是学习成本太大,次次百度非常不爽,有的也查不到,看官方文档英语又很麻烦。

5.开启特权模式:

容器时添加 --privileged=true 参数 并使用 /usr/sbin/init 的运行环境

docker run -d -name centos7 --privileged=true centos:7 /usr/sbin/init
docker exec -it centos7 /bin/bash

这样可以使用systemctl启动服务了。

k8s集群环境

针对k8s 集群环境怎么创建特权级容器,网上并未找到特别详细的说明文档,参考docker 环境中的操作,通过上面docker 环境可以看出,是需要添加 --privileged=true 和  /usr/sbin/init 运行环境。k8s 创建容器资源的时候同样是需要在yaml 文件中指定这两个参数。

 

docker在容器中执行宿主机cmd docker 执行宿主机脚本_内核_02

docker在容器中执行宿主机cmd docker 执行宿主机脚本_内核_03

真诚建议:

经过本人思考与sa的交流,在开发阶段还是以重启解决为妙,升级带来的环境变动太大,特权模式根据不同的集群模式学习成本太高,镜像也需要改,所以通过重启解决目前看收益比较高,等到后期可以直接升级内核,从根本解决。