你的Docker摆设能更简单吗?GitLab集成与多进程管理又怎么做? ...

打印 上一主题 下一主题

主题 980|帖子 980|积分 2940

媒介

文章开始前,先尝试回答几个问题:

  • 在日常工作中,程序的打包和摆设方式流程是怎样的?
  • 假如使用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:

 
以 shell executor 为例:
 

 
可见,做法很简单:将Docker命令作为流水线脚本实行即可,镜像打包出来后可用来摆设。以近期热度较高的大模型服务为例,经典的集成架构如下图所示:
 

 
其他CI集成的主流程万变不离其宗,不同之处在于在此根本上做一些优化,好比缓存加速等。
常用的容器镜像构建工具:Kaniko

同样,先看官网 https://github.com/GoogleContainerTools/kaniko 界说:

 
可见,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 的使用方法描述:

 
在 Docker 容器中管理多个进程

现实中,大部分情况下容器中仅会有一个进程,也即1号进程。但总会有例外发生,以上文中的例子来说,某个容器中不仅需要主服务进程提供Web服务,还需要Nginx进程用于代理转发部分前端流量,以办理跨域问题。此时就需要同时启动并管理多个进程。有需求就有实现,现在多进程管理工具有很多了,一种常见的方案是使用Python编写的进程管理工具supervisord,它可以管理多个进程,包括启动、停止、重启等操作。针对上述例子,整体集成方式如下:

  • 制作根本镜像:基于centos体系镜像,安装supervisord 和nginx。
  1. /bin/sh -c yum install -y epel-release
  2. /bin/sh -c yum install -y supervisor
  3. /bin/sh -c yum install -y nginx-1.10.3
  4. /bin/sh -c yum clean all

  5. # 注意只列出了本文涉及到的几个命令,还有很多其他功能需要安装
  6. # 可参考仓库 https://github.com/CentOS/sig-cloud-instance-images
  7. # 该仓库包括了centos系统的各种镜像的构建命令,囊括了很多实用命令安装脚本
复制代码
  1. [/code][code]
复制代码
2. 编写 /etc/supervisord.conf,它是supervisord的主配置文件,界说了supervisord 进程管理器的全局设置和行为,确保全部被管理的进程都能按照预期的方式启动和运行。通过这个配置文件,可以集中管理多个服务,使得服务的摆设和维护更加方便。
  1. [unix_http_server]
  2. file=/var/run/supervisor.sock
  3. chmod=0700

  4. [supervisord]
  5. logfile=/var/log/supervisor/supervisord.log
  6. logfile_maxbytes=50MB
  7. logfile_backups=10
  8. loglevel=info
  9. pidfile=/var/run/supervisord.pid
  10. nodaemon=false
  11. minfds=1024
  12. minprocs=200

  13. [rpcinterface:supervisor]
  14. supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

  15. [supervisorctl]
  16. serverurl=unix:///var/run/supervisor.sock

  17. [include]
  18. files = /etc/supervisor/conf.d/*.ini
复制代码
  1. [/code][indent][b][unix_http_server][/b]:界说了 supervisord 的 Unix 套接字 HTTP 服务器的配置,用于 supervisorctl 命令行工具或其他客户端与 supervisord 举行通信。
  2. [b][supervisord][/b]:包含了 supervisord 保卫进程的全局配置,如日志文件位置、日志大小限制、日志备份数量、进程文件位置、最小文件描述符和进程数量等。
  3. [b][rpcinterface:x][/b]:界说了 RPC 接口的配置,答应远程管理 supervisord。这通常用于 supervisorctl 命令行工具。
  4. [b][supervisorctl][/b]:界说了 supervisorctl 命令行工具的配置,如连接到 supervisord 的 URL。
  5. [b][include] [/b]:答应 supervisord 包含其他配置文件。这使得你可以将不同的程序配置在不同的文件中,然后由主配置文件统一管理。通常,这个节会包含 /etc/supervisor/conf.d/*.ini,如许 supervisord 就会主动加载 /etc/supervisor/conf.d/ 目录下的全部 .ini 文件。
  6. [/indent][list=1]
  7. [*]为各工程使用方便,将 /etc/supervisor/conf.d/nginx.ini 提前打包到镜像中,后续只需配置 nginx.conf 即可。
  8. [/list][code] 
复制代码
  1. [program:nginx]
  2. command=/etc/nginx/sbin/nginx
  3. user=xiaoxi666
  4. priority=999
  5. numprocs=1
  6. autostart=true
  7. autorestart=true
  8. startsecs=1
  9. startretries=3
  10. stopsignal=KILL
  11. stopwaitsecs=10
  12. stdout_logfile=/var/log/supervisor/nginx.log
  13. stderr_logfile=/var/log/supervisor/nginx.err
  14. stdout_logfile_maxbytes=100MB
  15. stdout_logfile_backups=5
  16. stopasgroup=true
复制代码
  1. [/code][indent][b][program:nginx][/b]:界说了一个名为 nginx 的程序。supervisord 会根据这个名称来辨认和控制这个进程。各个字段含义:
  2. [b]command[/b]:指定启动进程的命令。
  3. [b]user[/b]:指定以哪个用户身份运行 Nginx 进程。通常建议使用非 root 用户来运行服务以提高安全性。
  4. [b]priority[/b]:设置程序的启动优先级。较小的数字表示更高的优先级,即 supervisord 会先启动优先级数值较小的程序。
  5. [b]numprocs[/b]:指定应该启动多少个进程。这里设置为1,意味着只启动一个 Nginx 进程。
  6. [b]autostart[/b]:设置为 true 时,supervisord 会在启动时主动启动这个程序。
  7. [b]autorestart[/b]:设置为 true 时,假如 nginx 进程意外退出,supervisord 会主动重启它。
  8. [b]startsecs[/b]:指定 Nginx 进程启动后多少秒内被以为是稳固的。假如在这个时间内进程退出,supervisord 会以为启动失败。
  9. [b]startretries[/b]:假如 Nginx 进程在 startsecs 时间内退出,supervisord 会尝试重启它。这个值指定了最大重启次数。
  10. [b]stopsignal[/b]:指定停止 Nginx 进程时发送的信号。KILL 信号是一个逼迫终止进程的信号。
  11. [b]stopwaitsecs[/b]:指定 supervisord 期待 Nginx 进程停止的时间(以秒为单位)。假如超时,supervisord 会发送 KILL 信号。
  12. [b]stdout_logfile[/b]:指定 Nginx 进程的标准输出日志文件的位置。
  13. [b]stderr_logfile[/b]:指定 Nginx 进程的标准错误日志文件的位置。
  14. [b]stdout_logfile_maxbytes[/b]:设置标准输出日志文件的最大大小。当文件到达这个大小后,会滚动切分输出。
  15. [b]stdout_logfile_backups[/b]:设置标准输出日志文件的备份数量。当日志文件滚动切分时,旧的日志文件会被保留的备份数量。
  16. [b]stopasgroup[/b]:设置为 true 时,supervisord 会向整个进程组发送停止信号,这可以确保全部子进程都被准确终止。
  17. [/indent]做完这一步,该镜像就可以提供给“同时需要Web服务和Nginx服务”的工程使用了。
  18. [list=1]
  19. [*]各工程编写自己的Dockerfile文件,将自界说的服务ini文件(假设名字为supervisor-app.ini)和 nginx.conf 文件复制到指定目录,然后启动supervisord。
  20. [/list][code]# 定义环境变量
  21. ENV SUPERVISOR_CONF_DIR=/etc/supervisor/conf.d
  22. ENV NGINX_CONF_DIR=/etc/nginx/conf.d
  23. ENV APP_DIR=/app
  24. ENV PROJECT_NAME=xiaoxi666_demo_project

  25. # 复制supervisord的配置文件到supervisord的配置目录
  26. COPY supervisor-app.ini ${SUPERVISOR_CONF_DIR}/supervisor-app.ini

  27. # 复制nginx配置文件到指定的nginx配置目录
  28. COPY nginx.conf ${NGINX_CONF_DIR}/nginx.conf

  29. # 复制当前目录下的所有文件到APP_DIR
  30. COPY . ${APP_DIR}

  31. # 创建项目目录并移动target目录下的内容到项目目录
  32. RUN mkdir -p ${APP_DIR}/${PROJECT_NAME} \
  33.     && mv ${APP_DIR}/target/* ${APP_DIR}/${PROJECT_NAME} \
  34.     && chown -R xiaoxi666:xiaoxi666 ${APP_DIR}

  35. # 暴露端口
  36. EXPOSE 8080 其他要暴露的端口

  37. # 启动supervisord
  38. CMD ["/usr/bin/supervisord", "-n"]
复制代码
其中,supervisor-app.ini文件内容为主进程的启动命令,一个示例:
  1. [program:xiaoxi666-demo-project]
  2. command=java -jar 其他虚拟机参数 xiaoxi666-demo-project.jar
  3. user=root
  4. priority=999
  5. numprocs=1
  6. autostart=true
  7. autorestart=true
  8. startsecs=1
  9. startretries=3
  10. stopsignal=KILL
  11. stopwaitsecs=20
  12. stdout_logfile=%(ENV_LOG_DIR)/supervisor/xiaoxi666-demo-project.log
  13. stderr_logfile=%(ENV_LOG_DIR)/supervisor/xiaoxi666-demo-project.err
  14. stdout_logfile_maxbytes=100MB
  15. stdout_logfile_backups=5
  16. stopasgroup=true
复制代码
而 nginx.conf 根据实际代理需求配置即可。
整体来看,文件引用层级是如许的:

 
跋文本文以实际工程中的例子为切入点,围绕“Docker容器镜像构建”、“GitLab集成摆设”,以及“容器多进程管理”这几个侧重点做了一些探讨和梳理,同时给出了对应的官方参考资料链接,有爱好的读者可进一步深入学习。也欢迎大家留言,谈谈你所履历的容器集成摆设方式是怎样的。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

怀念夏天

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表