你的Docker摆设能更简单吗?GitLab集成与多进程管理又怎么做?
媒介文章开始前,先尝试回答几个问题:
[*]在日常工作中,程序的打包和摆设方式流程是怎样的?
[*]假如使用Docker容器摆设方式,是用原生Docker命令,照旧Kaniko这类工具?
[*]除了业务服务外,假如还需要同时运行其他进程,应该怎么办?举个例子:除了主服务进程(好比Web服务器),还需要同时启动Nginx进程(用于代理转发部分前端流量,办理跨域问题)。
以上几个问题,拆解:
[*]属于 CI 集成的概念:GitLab和Docker的集成是一种主流方式,其他工具也大同小异。
[*]与内核态和用户态有关。Kaniko是一种常用的容器镜像构建工具。
[*]需要用到进程管理工具,在Docker容器中同时管理多个进程。
一个个来说。
GitLab 和 Docker 的集成
两者的集成主要有三种方式,手段大同小异,但核心目的都是把Docker打包镜像的流程放到GitLab的流水线中实行。可参见官 https://docs.gitlab.com/ee/ci/docker/using_docker_build.html:
https://img2024.cnblogs.com/blog/609124/202412/609124-20241209112650398-1368764747.png
以 shell executor 为例:
https://img2024.cnblogs.com/blog/609124/202412/609124-20241209112848093-270635422.png
可见,做法很简单:将Docker命令作为流水线脚本实行即可,镜像打包出来后可用来摆设。以近期热度较高的大模型服务为例,经典的集成架构如下图所示:
https://img2024.cnblogs.com/blog/609124/202412/609124-20241209112900306-1220238463.png
其他CI集成的主流程万变不离其宗,不同之处在于在此根本上做一些优化,好比缓存加速等。
常用的容器镜像构建工具:Kaniko
同样,先看官网 https://github.com/GoogleContainerTools/kaniko 界说:
https://img2024.cnblogs.com/blog/609124/202412/609124-20241209112913952-1201626312.png
可见,Kaniko 是一个用于构建容器镜像的工具,它答应我们从Dockerfile构建镜像,且不需要Docker保卫进程。Kaniko executor 构建镜像的具体步调如下:
[*]Kaniko Executor Image:Kaniko实行器镜像是一个特别的容器镜像,它包含了全部必要的工具和依赖,以便在容器内部构建新的Docker镜像。
[*]Building an Image from a Dockerfile:用户提供一个Dockerfile,Kaniko实行器镜像将根据这个Dockerfile来构建一个新的镜像。Dockerfile包含了一系列的指令,这些指令界说了如何构建一个新Docker镜像,比方FROM, RUN, COPY, ADD等。
[*]Extracting the Filesystem of the Base Image:在Dockerfile中,FROM 指令指定了根本镜像,Kaniko 首先需要提取这个根本镜像的文件体系。这个文件体系被复制到 Kaniko 实行器镜像的临时目录中,以便后续的构建过程可以在用户空间中对其举行操作。
[*]Executing Commands in the Dockerfile:Kaniko逐个实行Dockerfile中的指令。对于每个指令,Kaniko都会在用户空间中模仿该指令的效果。比方,假如指令是RUN apt-get update,Kaniko会在容器内部实行这个命令,就像在普通的Docker构建过程中一样。
[*]Snapshotting the Filesystem in Userspace:在每个指令实行之后,Kaniko 会在用户空间中对文件体系举行快照。这个快照捕获了自上一个快照以来文件体系的全部变化,这些变化包括新创建的文件、修改过的文件和删除的文件。
[*]Appending a Layer of Changed Files:假如在实行某个指令后文件体系发生了变化,Kaniko 会将这些变化作为一个新层添加到根本镜像上。这个过程是逐层举行的,每个指令可能对应一个或多个层,这取决于文件体系的变化。
[*]Updating Image Metadata:除了添加文件体系的变化之外,Kaniko还会更新镜像的元数据,包括标签、情况变量、工作目录等。这些元数据信息也是 Dockerfile 中指令的一部分,Kaniko会确保这些信息被准确地应用到新构建的镜像上。
[*]Pushing the Image to a Registry:一旦全部的指令都被实行完毕,并且全部的变化都被添加到镜像中,Kaniko 会将这个新构建的镜像推送到指定的容器镜像仓库(registry)。这个步调需要提供仓库的认证信息,以便Kaniko能够乐成地将镜像推送到仓库。
总的来说,Kaniko与原生Docker最大的不同之处在于:Kaniko在用户空间中模仿 Dockerfile中的指令,并逐层捕获文件体系的变化,最终构建出一个新的Docker镜像,而不需要Docker保卫进程的参与。这种方法提高了安全性,并且可以在多种情况中灵活地构建容器镜像(也即:可以在没有root权限的情况中运行)。另外,在GitLab官网 https://docs.gitlab.com/ee/ci/docker/using_kaniko.html 也有 Kaniko 的使用方法描述:https://img2024.cnblogs.com/blog/609124/202412/609124-20241209112929683-120704562.png
在 Docker 容器中管理多个进程
现实中,大部分情况下容器中仅会有一个进程,也即1号进程。但总会有例外发生,以上文中的例子来说,某个容器中不仅需要主服务进程提供Web服务,还需要Nginx进程用于代理转发部分前端流量,以办理跨域问题。此时就需要同时启动并管理多个进程。有需求就有实现,现在多进程管理工具有很多了,一种常见的方案是使用Python编写的进程管理工具supervisord,它可以管理多个进程,包括启动、停止、重启等操作。针对上述例子,整体集成方式如下:
[*]制作根本镜像:基于centos体系镜像,安装supervisord 和nginx。
/bin/sh -c yum install -y epel-release
/bin/sh -c yum install -y supervisor
/bin/sh -c yum install -y nginx-1.10.3
/bin/sh -c yum clean all
# 注意只列出了本文涉及到的几个命令,还有很多其他功能需要安装
# 可参考仓库 https://github.com/CentOS/sig-cloud-instance-images
# 该仓库包括了centos系统的各种镜像的构建命令,囊括了很多实用命令安装脚本2. 编写 /etc/supervisord.conf,它是supervisord的主配置文件,界说了supervisord 进程管理器的全局设置和行为,确保全部被管理的进程都能按照预期的方式启动和运行。通过这个配置文件,可以集中管理多个服务,使得服务的摆设和维护更加方便。
file=/var/run/supervisor.sock
chmod=0700
logfile=/var/log/supervisor/supervisord.log
logfile_maxbytes=50MB
logfile_backups=10
loglevel=info
pidfile=/var/run/supervisord.pid
nodaemon=false
minfds=1024
minprocs=200
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
serverurl=unix:///var/run/supervisor.sock
files = /etc/supervisor/conf.d/*.ini:界说了 supervisord 的 Unix 套接字 HTTP 服务器的配置,用于 supervisorctl 命令行工具或其他客户端与 supervisord 举行通信。
:包含了 supervisord 保卫进程的全局配置,如日志文件位置、日志大小限制、日志备份数量、进程文件位置、最小文件描述符和进程数量等。
:界说了 RPC 接口的配置,答应远程管理 supervisord。这通常用于 supervisorctl 命令行工具。
:界说了 supervisorctl 命令行工具的配置,如连接到 supervisord 的 URL。
:答应 supervisord 包含其他配置文件。这使得你可以将不同的程序配置在不同的文件中,然后由主配置文件统一管理。通常,这个节会包含 /etc/supervisor/conf.d/*.ini,如许 supervisord 就会主动加载 /etc/supervisor/conf.d/ 目录下的全部 .ini 文件。
[*]为各工程使用方便,将 /etc/supervisor/conf.d/nginx.ini 提前打包到镜像中,后续只需配置 nginx.conf 即可。
command=/etc/nginx/sbin/nginx
user=xiaoxi666
priority=999
numprocs=1
autostart=true
autorestart=true
startsecs=1
startretries=3
stopsignal=KILL
stopwaitsecs=10
stdout_logfile=/var/log/supervisor/nginx.log
stderr_logfile=/var/log/supervisor/nginx.err
stdout_logfile_maxbytes=100MB
stdout_logfile_backups=5
stopasgroup=true:界说了一个名为 nginx 的程序。supervisord 会根据这个名称来辨认和控制这个进程。各个字段含义:
command:指定启动进程的命令。
user:指定以哪个用户身份运行 Nginx 进程。通常建议使用非 root 用户来运行服务以提高安全性。
priority:设置程序的启动优先级。较小的数字表示更高的优先级,即 supervisord 会先启动优先级数值较小的程序。
numprocs:指定应该启动多少个进程。这里设置为1,意味着只启动一个 Nginx 进程。
autostart:设置为 true 时,supervisord 会在启动时主动启动这个程序。
autorestart:设置为 true 时,假如 nginx 进程意外退出,supervisord 会主动重启它。
startsecs:指定 Nginx 进程启动后多少秒内被以为是稳固的。假如在这个时间内进程退出,supervisord 会以为启动失败。
startretries:假如 Nginx 进程在 startsecs 时间内退出,supervisord 会尝试重启它。这个值指定了最大重启次数。
stopsignal:指定停止 Nginx 进程时发送的信号。KILL 信号是一个逼迫终止进程的信号。
stopwaitsecs:指定 supervisord 期待 Nginx 进程停止的时间(以秒为单位)。假如超时,supervisord 会发送 KILL 信号。
stdout_logfile:指定 Nginx 进程的标准输出日志文件的位置。
stderr_logfile:指定 Nginx 进程的标准错误日志文件的位置。
stdout_logfile_maxbytes:设置标准输出日志文件的最大大小。当文件到达这个大小后,会滚动切分输出。
stdout_logfile_backups:设置标准输出日志文件的备份数量。当日志文件滚动切分时,旧的日志文件会被保留的备份数量。
stopasgroup:设置为 true 时,supervisord 会向整个进程组发送停止信号,这可以确保全部子进程都被准确终止。
做完这一步,该镜像就可以提供给“同时需要Web服务和Nginx服务”的工程使用了。
[*]各工程编写自己的Dockerfile文件,将自界说的服务ini文件(假设名字为supervisor-app.ini)和 nginx.conf 文件复制到指定目录,然后启动supervisord。
# 定义环境变量
ENV SUPERVISOR_CONF_DIR=/etc/supervisor/conf.d
ENV NGINX_CONF_DIR=/etc/nginx/conf.d
ENV APP_DIR=/app
ENV PROJECT_NAME=xiaoxi666_demo_project
# 复制supervisord的配置文件到supervisord的配置目录
COPY supervisor-app.ini ${SUPERVISOR_CONF_DIR}/supervisor-app.ini
# 复制nginx配置文件到指定的nginx配置目录
COPY nginx.conf ${NGINX_CONF_DIR}/nginx.conf
# 复制当前目录下的所有文件到APP_DIR
COPY . ${APP_DIR}
# 创建项目目录并移动target目录下的内容到项目目录
RUN mkdir -p ${APP_DIR}/${PROJECT_NAME} \
&& mv ${APP_DIR}/target/* ${APP_DIR}/${PROJECT_NAME} \
&& chown -R xiaoxi666:xiaoxi666 ${APP_DIR}
# 暴露端口
EXPOSE 8080 其他要暴露的端口
# 启动supervisord
CMD ["/usr/bin/supervisord", "-n"]其中,supervisor-app.ini文件内容为主进程的启动命令,一个示例:
command=java -jar 其他虚拟机参数 xiaoxi666-demo-project.jar
user=root
priority=999
numprocs=1
autostart=true
autorestart=true
startsecs=1
startretries=3
stopsignal=KILL
stopwaitsecs=20
stdout_logfile=%(ENV_LOG_DIR)/supervisor/xiaoxi666-demo-project.log
stderr_logfile=%(ENV_LOG_DIR)/supervisor/xiaoxi666-demo-project.err
stdout_logfile_maxbytes=100MB
stdout_logfile_backups=5
stopasgroup=true而 nginx.conf 根据实际代理需求配置即可。
整体来看,文件引用层级是如许的:
https://img2024.cnblogs.com/blog/609124/202412/609124-20241209113004474-999669325.png
跋文本文以实际工程中的例子为切入点,围绕“Docker容器镜像构建”、“GitLab集成摆设”,以及“容器多进程管理”这几个侧重点做了一些探讨和梳理,同时给出了对应的官方参考资料链接,有爱好的读者可进一步深入学习。也欢迎大家留言,谈谈你所履历的容器集成摆设方式是怎样的。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]