Centos7 docker 容器内root身份应用自启动 /usr/sbin/init 问题

news/2025/3/31 22:37:07/


Centos7 docker 容器内root身份应用自启动 & /usr/sbin/init 问题

环境:我在一个 docker 容器内手动安装了 mysql、nginx、autotestsystem(自己的服务);
mysql 和 nginx 都做了服务脚本:mysqld.service、nginx.service,并设置了开机自启动:
systemctl enable mysqld.service
systemctl enable nginx.service

vi mysqld.service


vi nginx.service

自己的应用位置:
/opt/AutoTestSystem/ui/              #前端,前端用的nginx
/opt/AutoTestSystem/server/          #后端,后端用的python flask
/opt/AutoTestSystem/server/start.sh  #后端服务启动脚本
/opt/AutoTestSystem/server/stop.sh   #后端服务停止脚本
ln -s /opt/AutoTestSystem/server/start.sh /usr/bin/autotestsystem-start
ln -s /opt/AutoTestSystem/server/stop.sh /usr/bin/autotestsystem-stop

# cat /opt/AutoTestSystem/server/start.sh 
#!/bin/sh

pid=$(ps aux |grep  "python3 main.py" |grep -v "grep" | awk '{print $2}')
echo $pid
if [ -n "$pid" ]; then
  echo "WARNNING: main.py already is running, need not run again!"
  exit
fi

# start server
pushd /opt/AutoTestSystem/server  2>&1 >/dev/null
$(nohup python3 main.py >> log &)
sleep 2

pid=$(ps aux |grep  "python3 main.py" |grep -v "grep" | awk '{print $2}')
if [ -z "$pid" ]; then
 echo "ERROR: start failed!"
else
 echo "SUCCESS: start success!"
fi
popd 2>&1 >/dev/null

# cat /opt/AutoTestSystem/server/stop.sh  
#!/bin/sh

#pid=$(ps aux |grep  "python3 main.py" |grep -v "grep" | awk '{print $2}')
pid=$(ps aux |grep  "/opt/AutoTestSystem/server/main.py" |grep -v "grep" | awk '{print $2}')

if [ -z "$pid" ]; then
 echo "INFO: main.py is not running"
 exit
fi 

echo "INFO: to stop main.py, pid is: $pid"
$(kill -9 $pid)
sleep 3

pid2=$(ps aux |grep  "python3 main.py" |grep -v "grep" | awk '{print $2}')
if [ -n "$pid2" ]; then
 echo "ERROR: stop $pid2 failed!"
else
 echo "SUCCESS: stop $pid2 success!"
fi

执行docker commit保存持久化:

docker commit -a "hrf" -m "autotestsystem 1.0" 478394f89173 autotestsystem:1.0

注意:docker commit 时如果指定的 REPOSITORY:TAG 变化则会生成新的image,如果不变则不会生成新的image、只会合并,docker image查看会多出 REPOSITORY和TAG未空 <none> 的 IMAGE ID,这种是可以删除的(docker rmi IMAGE_ID)。

创建build目录 & Dockerfile & init_ats启动脚本,执行 docker build 把自启动脚本打包到容器里面去并设置自启动:

cd build

vi Dockerfile
FROM autotestsystem:1.0
WORKDIR /opt/AutoTestSystem
COPY init_ats /usr/bin/
RUN chmod +x /usr/bin/init_ats
ENTRYPOINT init_ats
LABEL user="hrf"
USER root

vi init_ats
#!/bin/bash
/usr/sbin/init
sleep 2
/usr/bin/autotestsystem-start


docker build -t autotestsystem:1.0 .
docker images
docker run -idt --name autotest2 -p 29090:8080 -p 23306:3306 -p 29000:80 --privileged --cap-add SYS_ADMIN --restart=always autotestsystem:1.0 

也尝试过docker run是传参替换: 
docker run -idt --name autotest2 -p 29090:8080 -p 23306:3306 -p 29000:80 --privileged --cap-add SYS_ADMIN --restart=always autotestsystem:1.0 /usr/sbin/init

docker run -idt --name autotest2 -p 29090:8080 -p 23306:3306 -p 29000:80 --privileged --cap-add SYS_ADMIN --restart=always autotestsystem:1.0 init_ats

docker run -idt --name autotest2 -p 29090:8080 -p 23306:3306 -p 29000:80 --privileged --cap-add SYS_ADMIN --restart=always autotestsystem:1.0 autotestsystem-start
都不行。

执行脚本,还尝试了多种,都不行:
ENTRYPOINT init_ats
ENTRYPOINT ["init_ats"]
ENTRYPOINT ["sh","init_ats"]
ENTRYPOINT ["sh","-c","init_ats"]
ENTRYPOINT autotestsystem-start
CMD init_ats
CMD autotestsystem-start

网上找了很多资料,原因是 root 身份运行docker容器,需要特权,需要加 /usr/sbin/init 运行容器。可是编写 Dockerfile 执行 docker build 的方式,无法支持启动时执行多个脚本或命令,只能执行一个或一条命令,即使写在一个shell脚本中也不行。


最后,换了一个思路,既然mysqld和nginx做成了service服务自启动可以(systemctl enable xxx),那我也尝创建自己应用的.service脚本,做成系统服务自启动。

查看当前容器:
[root@localhost build]# docker ps -a
CONTAINER ID   IMAGE      COMMAND            CREATED        STATUS        PORTS                                                                                                                           NAMES
478394f89173   centos:7   "/usr/sbin/init"   33 hours ago   Up 33 hours   0.0.0.0:9000->80/tcp, :::9000->80/tcp, 0.0.0.0:13306->3306/tcp, :::13306->3306/tcp, 0.0.0.0:9090->8080/tcp, :::9090->8080/tcp   autotest

查看镜像:
[root@localhost build]# docker images
REPOSITORY       TAG       IMAGE ID       CREATED          SIZE
autotestsystem   1.0       a781ff5a15b8   46 minutes ago   1.72GB
centos           7         eeb6ee3f44bd   2 years ago      204MB

容器 478394f89173 是以root运行的,里面的mysqld服务和nginx服务自启正常,但自己服务编写的自启动脚本 init_ats 自启不生效。


接下来,我尝试把我的 autotestsystem 做成系统服务:

进入docker容器:
docker exec -it 478394f89173 /bin/bash

创建.service文件:
[root@478394f89173 system]# vi /lib/systemd/system/autotestsystem.service

[Unit]
Description=autotestsystem
After=network.target
 
[Service]
Type=forking
ExecStart=/opt/AutoTestSystem/server/start.sh
ExecReload=/opt/AutoTestSystem/server/start.sh
ExecStop=/opt/AutoTestSystem/server/stop.sh
PrivateTmp=true
User=root
#Group=root
WorkingDirectory=/opt/AutoTestSystem/server/
RestartSec=2s
 
[Install]
WantedBy=multi-user.target


[root@478394f89173 system]# chmod 754 /lib/systemd/system/autotestsystem.service

[root@478394f89173 system]# systemctl daemon-reload    # 每次修改service后需要刷新生效

[root@478394f89173 system]# systemctl  start autotestsystem.service 
[root@478394f89173 system]# systemctl  enable autotestsystem.service 
Created symlink from /etc/systemd/system/multi-user.target.wants/autotestsystem.service to /usr/lib/systemd/system/autotestsystem.service.
[root@478394f89173 system]# ps aux |grep main.py       #启动服务成功

退出容器、停止容器、启动容器,进入容器,再查看 autotestsystem 能正常自启动:
exit
docker stop 478394f89173
docker start 478394f89173
docker exec -it 478394f89173 /bin/bash
ps aux |grep main.py
 

退出容器,在宿主机下重新 docker build 构建/保存镜像(image),即持久化:
做成.service系统服务了,用不到docker启动脚本,可以直接docker commit持久化、并删除none镜像:
 docker commit -a "hrf" -m "autotestsystem 1.0" 478394f89173 autotestsystem:1.0
 docker rmi `docker images | grep  '<none>' | awk '{print $3}'`

当然如果要使用docker build方式持久化镜像也是可以的。

如果是在宿主机上build目录下直接vi创建和编写的autotestsystem.service服务器脚本(而不是在容器内创建服务脚本和设置自启动),则可以使用docker build方式构建镜像、打脚本包到容器里面去:

cd build

vi autotestsystem.service

[Unit]
Description=autotestsystem
After=network.target
 
[Service]
Type=forking
ExecStart=/opt/AutoTestSystem/server/start.sh
ExecReload=/opt/AutoTestSystem/server/start.sh
ExecStop=/opt/AutoTestSystem/server/stop.sh
PrivateTmp=true
User=root
#Group=root
WorkingDirectory=/opt/AutoTestSystem/server/
RestartSec=2s
 
[Install]
WantedBy=multi-user.target

vi Dockerfile

FROM autotestsystem:1.0
WORKDIR /opt/AutoTestSystem
#COPY  init_ats  /usr/bin/
#RUN  chmod +x /usr/bin/init_ats
#ENTRYPOINT ["init_ats"]
COPY autotestsystem.service /lib/systemd/system/
COPY autotestsystem.service /etc/systemd/system/multi-user.target.wants/
RUN chmod 754 /lib/systemd/system/autotestsystem.service
RUN chmod 754 /etc/systemd/system/multi-user.target.wants/autotestsystem.service
ENTRYPOINT ["/usr/sbin/init"]
LABEL user="hrf"
USER root

说明:
build目录下创建和编写下面2个文件:autotestsystem.service、Dockerfile。
docker build构建时会执行Dockerfile中的COPY命名,COPY是构件阶段执行的。RUN、CMD、ENTRYPOINT命令则是在容器启动阶段执行的。
COPY autotestsystem.service /lib/systemd/system/  这条命令会在docker build构件阶段把build目录下的utotestsystem.service文件拷贝到容器内的/lib/systemd/system/这个目录下。


重新构建:
docker build -t autotestsystem:1.0 . 

[root@localhost build]#  docker build -t autotestsystem:1.0 .
[+] Building 22.0s (11/11) FINISHED                                                                                                  docker:default
 => [internal] load .dockerignore                                                                                                              0.7s
 => => transferring context: 2B                                                                                                                0.0s
 => [internal] load build definition from Dockerfile                                                                                           1.8s
 => => transferring dockerfile: 550B                                                                                                           0.0s
 => [internal] load metadata for docker.io/library/autotestsystem:1.0                                                                          0.0s
 => [1/6] FROM docker.io/library/autotestsystem:1.0                                                                                            6.6s
 => [internal] load build context                                                                                                              0.8s
 => => transferring context: 461B                                                                                                              0.0s
 => [2/6] WORKDIR /opt/AutoTestSystem                                                                                                          0.7s
 => [3/6] COPY autotestsystem.service /lib/systemd/system/                                                                                     1.4s
 => [4/6] COPY autotestsystem.service /etc/systemd/system/multi-user.target.wants/                                                             1.3s
 => [5/6] RUN chmod 754 /lib/systemd/system/autotestsystem.service                                                                             2.3s
 => [6/6] RUN chmod 754 /etc/systemd/system/multi-user.target.wants/autotestsystem.service                                                     2.3s
 => exporting to image                                                                                                                         2.9s
 => => exporting layers                                                                                                                        2.9s
 => => writing image sha256:a1750b9abb21ba65b122edfdf21c37b81896ec68ffbe2f510bfff7ce97e4a95b                                                   0.0s
 => => naming to docker.io/library/autotestsystem:1.0                                                                                          0.1s
[root@localhost build]# 
[root@localhost build]# 
[root@localhost build]# 
[root@localhost build]# docker run -idt --name autotest2 -p 29090:8080 -p 23306:3306 -p 29000:80 --privileged --cap-add SYS_ADMIN --restart=always autotestsystem:1.0 
06ce37919cf068e20fdd676fa51ce1988e3a1d40ba7424d645fd5f561b758a27

[root@localhost build]# 
[root@localhost build]# 
[root@localhost build]# 
[root@localhost build]# 
[root@localhost build]# docker ps -a
CONTAINER ID   IMAGE                COMMAND            CREATED         STATUS         PORTS                                                                                                                               NAMES
06ce37919cf0   autotestsystem:1.0   "/usr/sbin/init"   7 seconds ago   Up 4 seconds   0.0.0.0:29000->80/tcp, :::29000->80/tcp, 0.0.0.0:23306->3306/tcp, :::23306->3306/tcp, 0.0.0.0:29090->8080/tcp, :::29090->8080/tcp   autotest2
478394f89173   centos:7             "/usr/sbin/init"   33 hours ago    Up 33 hours    0.0.0.0:9000->80/tcp, :::9000->80/tcp, 0.0.0.0:13306->3306/tcp, :::13306->3306/tcp, 0.0.0.0:9090->8080/tcp, :::9090->8080/tcp       autotest
[root@localhost build]# 

最后导出、备份镜像文件:

cd release
docker save -o autotestsystem-1.0.tar autotestsystem:1.0
 


http://www.ppmy.cn/news/1137397.html

相关文章

YOLOv8轻量化模型:BiLevelRoutingAttention 结合C2f | CVPR2023

💡💡💡本文解决什么问题:BiLevelRoutingAttention ,通过双层路由(bi-level routing)提出了一种新颖的动态稀疏注意力(dynamic sparse attention ) BiLevelRoutingAttention 和C2f结合 | 轻量化的同时在数据集并有小幅涨点; YOLO轻量化模型专栏:http://t.csdnimg…

Python--控制台获取输入与正则表达式

前言一、控制台获取输入1.1 字符串输入1.2 整数输入1.3 浮点数输入1.4 布尔值输入1.5 列表输入1.6 汇总 二、正则表达式2.1 匹配数字2.2 模式检查2.3 替换字符2.4 切分字符串2.5 搜索并提取匹配的部分2.6 使用捕获组提取匹配的部分2.7 非贪婪匹配2.8 忽略大小写匹配2.9 使用预定…

多线程 - 单例模式

单例模式 ~~ 单例模式是常见的设计模式之一 什么是设计模式 你知道象棋,五子棋,围棋吗?如果,你想下好围棋,你就不得不了解一个东西,”棋谱”,设计模式好比围棋中的 “棋谱”. 在棋谱里面,大佬们,把一些常见的对局场景,都给推演出来了,照着棋谱来下棋,基本上棋力就不会差到哪…

【LeetCode热题100】--74.搜索二维矩阵

74.搜索二维矩阵 按行搜索&#xff0c;使用二分查找 class Solution {public boolean searchMatrix(int[][] matrix, int target) {for(int[] row : matrix){int index search(row,target);if(index > 0){return true;}}return false;}public int search(int[] nums,int t…

QGIS文章四——对遥感影像进行土地类型分类

关于土地类型分类&#xff0c;按照性质、用途、利用现状有不同的分类标准。 一、按照国家土地性质分类标准&#xff0c;一般分五类:商业用地、综合用地、住宅用地、工业用地和其他用地。 二、按照用途进行土地分类&#xff1a;可以分为农用地、建设用地和未利用土地&#xff0c…

MySQL:数据库的物理备份和恢复-冷备份(3)

介绍 物理备份&#xff1a; 直接复制数据文件进行的备份 优点&#xff1a;不需要其他的工具&#xff0c;直接复制就好&#xff0c;恢复直接复制备份文件即可 缺点&#xff1a;与存储引擎有关&#xff0c;跨平台能力较弱 逻辑备份&#xff1a; 从数据库中导出数据另存而进行的备…

美联储世纪大裁员

“最近的指标表明&#xff0c;经济活动一直在稳步扩张。近几个月就业增长放缓&#xff0c;但仍保持强劲&#xff0c;失业率仍保持在较低水平。”——美联储9月20号议息会议声明开篇如是说。两天之后的周五&#xff0c;美联储发言人向媒体确认了美联储计划年内裁撤约300个岗位的…

零基础入门初学 Python 需要安装哪些软件?

Python是近年来备受热门的编程语言&#xff0c;其简明易读、开源免费、跨平台等特点&#xff0c;使得Python倍受喜爱&#xff0c;成为初学者及开发者心中的首选。 如果你是第一次接触Python&#xff0c;又不想繁琐地安装各种软件&#xff0c;可以尝试在线运行Python代码&#…