当前位置: 首页 > news >正文

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


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
 

相关文章:

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

Centos7 docker 容器内root身份应用自启动 & /usr/sbin/init 问题 环境&#xff1a;我在一个 docker 容器内手动安装了 mysql、nginx、autotestsystem&#xff08;自己的服务&#xff09;&#xff1b; mysql 和 nginx 都做了服务脚本&#xff1a;mysqld.service、nginx.se…...

STL学习笔记之容器

首先我们要学习的是容器 第一个是容器的初始化&#xff08;构造方式&#xff09;有三种方式 分别是 第一种 int arr[]{1,2,3} vector<int> v1(arr,arr3) 即容器存放的种类和从另外一个数组去拷贝一段数据。 第二种 vector<int> v2(3,10); 第一个3是指存放…...

Java基础---第十二篇

系列文章目录 文章目录 系列文章目录一、获取一个类Class对象的方式有哪些?二、ArrayList 和 LinkedList 的区别有哪些?三、用过 ArrayList 吗?说一下它有什么特点?一、获取一个类Class对象的方式有哪些? 搞清楚类对象和实例对象,但都是对象。 第一种:通过类对象的 get…...

Acwing 841. 字符串哈希

Acwing 841. 字符串哈希 题目描述思路讲解代码展示 题目描述 思路讲解 代码展示 #include <iostream> #include <algorithm>using namespace std;typedef unsigned long long ULL;const int N 100010, P 131; // P 131 或者13331(经验值)int n, m; char str[N]…...

NEON优化:性能优化经验总结

NEON优化&#xff1a;性能优化经验总结 1. 什么是 NEONArm Adv SIMD 历史 2. 寄存器3. NEON 命名方式4. 优化技巧5. 优化 NEON 代码(Armv7-A内容&#xff0c;但区别不大)5.1 优化 NEON 汇编代码5.1.1 Cortex-A 处理器之间的 NEON 管道差异5.1.2 内存访问优化 Reference: NEON优…...

C++ 并发编程实战 第九章

目录 9.1 线程池 9.1.1 最简易可行的线程池 9.1.2 等待提交给线程池的任务完成运行 9.1.3等待其他任务完成的任务 9.1.4 避免任务队列上的争夺 9.1.5 任务窃取 9.2 中断线程 9.2.1 发起一个线程&#xff0c;以及把他中断 9.2.2 检测线程是否被中断 9.2.3 中断条件变…...

【Java】super 关键字用法

目录 this与super区别 1.访问成员变量-示例代码 继承中构造方法的访问特点 2.访问构造方法-示例代码&#xff1a; 继承中成员方法访问特点 3.访问成员方法-示例代码&#xff1a; super 关键字的用法和 this 关键字相似 this : 代表本类对象的引用super : 代表父类存储空间…...

前端笔试题总结,带答案和解析

1. 执行以下程序&#xff0c;输出结果为&#xff08;&#xff09; var x 10; var y 20; var z x < y ? x:y; console.log(xx;yy;zz);A x11;y21;z11 B x11;y20;z10 C x11;y21;z10 D x11;y20;z11 初始化x的值为10&#xff0c;y的值为20&#xff0c;x < y返回结果为tru…...

Omniverse Machinima

Omniverse Machinima App | NVIDIA Omniverse Machinima 是 NVIDIA 推出的一款实时动画创作工具&#xff0c;可用于在虚拟世界中制作和操纵角色及其环境。该工具使用 Universal Scene Description (USD) 作为其通用场景描述格式&#xff0c;可与多种 3D 建模、动画和渲染应用程…...

【测试人生】游戏业务测试落地精准测试专项的一些思路

精准测试在互联网领域有广泛的应用。以变更为出发点&#xff0c;通过对变更内容进行分析&#xff0c;可以确定单次变更具体涉及到哪些模块和功能点&#xff0c;以及是否存在夹带风险&#xff0c;从而从QA的视角&#xff0c;可以知道哪些功能模块需要做测试&#xff0c;以及哪些…...

Redis 数据类型底层原理

String 内部编码有三种&#xff1a;int、embstr、raw int&#xff1a;如果一个字符串对象保存的是整数值&#xff0c;并且这个整数值可以用 long类型来表示(不超过 long 的表示范围&#xff0c;如果超过了 long 的表示范围&#xff0c;那么按照存储字符串的编码来存储&#xf…...

EasyEdge 智能边缘控制台通过sdk发布应用

离线部署SDK生成 模型部署完成后会出现下载SDK的按钮&#xff0c;点击按钮下载SDK并保存好SDK。 进入EasyDL官网的技术文档 安装智能边缘控制台 跟着教程&#xff0c;完成安装&#xff1a;点此链接 树莓派4b是Linux arm64的架构&#xff0c;点击对应的链接进行下载。 下载完成…...

centos软件设置开机启动的方式

以下以redis作为案例&#xff1a; 开机启动方式一 [Unit] Descriptionredis-server Afternetwork.target [Service] Typeforking # 这里需要修改自己的配置文件 ExecStart/usr/local/bin/redis-server /etc/redis/redis.conf PrivateTmptrue [Install] WantedBymulti-user.tar…...

二叉树和堆

二叉树不存在度大于2的结点&#xff08;每个根最多只有两个子结点&#xff09;二叉树的子树有左右之分&#xff0c;次序不能颠倒&#xff0c;因此二叉树是有序树 两个特殊的二叉树——&#xff08;满二叉树&#xff0c;完全二叉树&#xff09; 满二叉树——每个根结点都有左右…...

洛谷P5732 【深基5.习7】杨辉三角题解

目录 题目【深基5.习7】杨辉三角题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1传送门 代码解释亲测 题目 【深基5.习7】杨辉三角 题目描述 给出 n ( n ≤ 20 ) n(n\le20) n(n≤20)&#xff0c;输出杨辉三角的前 n n n 行。 如果你不知道什么是杨辉三角&#xf…...

Docker 精简安装 Nacos 2.2.1 单机版本

准备工作&#xff1a; 1&#xff09;已安装docker 2&#xff09;数据库准备&#xff0c;演示使用MySql5.7版本 1、拉取 [rootTseng-HW ~]# docker pull nacos/nacos-server:v2.2.1 v2.2.1: Pulling from nacos/nacos-server 2d473b07cdd5: Already exists 77c5a601c050: Pul…...

IntelliJ IDEA配置Cplex12.6.3详细步骤

Cplex12.6.3版IntelliJ IDEA配置详细步骤 一、Cplex12.6.3版下载地址二、Cplex安装步骤三、IDEA配置CPLEX3.1 添加CPLEX安装目录的cplex.jar包到项目文件中3.2 将CPLEX的x64_win64文件夹添加到IDEA的VM options中 四、检查IDEA中Cplex是否安装成功卸载Cplex 一、Cplex12.6.3版下…...

2023 年最佳多 GPU 深度学习系统指南

动动发财的小手&#xff0c;点个赞吧&#xff01; 本文[1]提供了有关如何构建用于深度学习的多 GPU 系统的指南&#xff0c;并希望为您节省一些研究时间和实验时间。 1. GPU 让我们从有趣&#xff08;且昂贵&#xff09;的部分开始&#xff01; 购买 GPU 时的主要考虑因素是&am…...

Kotlin异常处理runCatching,getOrNull,onFailure,onSuccess(1)

Kotlin异常处理runCatching&#xff0c;getOrNull&#xff0c;onFailure&#xff0c;onSuccess&#xff08;1&#xff09; fun main(args: Array<String>) {var s1 runCatching {1 / 1}.getOrNull()println(s1) //s11&#xff0c;打印1println("-")var s2 ru…...

【深入探究人工智能】:历史、应用、技术与未来

深入探究人工智能 前言人工智能的历史人工智能的应用人工智能的技术人工智能的未来当代的人工智能产物结语&#x1f340;小结&#x1f340; &#x1f389;博客主页&#xff1a;小智_x0___0x_ &#x1f389;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &am…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...