docker与gosu,你的技术真的到天花板了吗

本文探讨了在Docker容器中使用gosu代替sudo的原因和优势。通过分析redis服务的启动过程,展示了gosu如何确保进程以非root身份以PID 1运行,实现优雅停机。gosu的功能、在Docker的最佳实践以及如何在Dockerfile中安装gosu进行了详细解释。
摘要由CSDN通过智能技术生成
  1. 执行命令ps -ef查看redis服务,结果如下:

root@122c2df16bbb:/data# ps -ef

UID PID PPID C STIME TTY TIME CMD

redis 1 0 0 09:22 ? 00:00:01 redis-server *:6379

root 287 0 0 09:36 ? 0

《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》

【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享

0:00:00 /bin/bash

root 293 287 0 09:39 ? 00:00:00 ps -ef

上面的结果展示了两个关键信息:

第一,redis服务是redis账号启动的,并非root;

第二,redis服务的PID等于1,这很重要,宿主机执行docker stop命令时,该进程可以收到SIGTERM信号量,于是redis应用可以做一些退出前的准备工作,例如保存变量、退出循环等,也就是优雅停机(Gracefully Stopping);

现在我们已经证实了redis服务并非root账号启动,而且该服务进程在容器内还是一号进程,但是我们在Dockerfile和docker-entrypoint.sh脚本中都没有发现切换到redis账号的命令,也没有sudo和su,这是怎么回事呢?

答案是gosu

再看一次redis的docker-entrypoint.sh文件,如下图,地址是:https://github.com/docker-library/redis/blob/6845f6d4940f94c50a9f1bf16e07058d0fe4bc4f/5.0/docker-entrypoint.sh

在这里插入图片描述

注意上图中的代码,我们来分析一下:

  1. 假设启动容器的命令是docker run --name myredis -idt redis redis-server /usr/local/etc/redis/redis.conf;

  2. 容器启动后会执行docker-entrypoint.sh脚本,此时的账号是root;

  3. 当前账号是root,因此会执行上图红框中的逻辑;

  4. 红框中的$0表示当前脚本的名称,即docker-entrypoint.sh;

  5. 红框中的$@表示外部传入的所有参数,即redis-server /usr/local/etc/redis/redis.conf;

  6. gosu redis “$0” “@”,表示以redis账号的身份执行以下命令:

docker-entrypoint.sh redis-server /usr/local/etc/redis/redis.conf

  1. gosu redis “$0” "@"前面加上个exec,表示以gosu redis “$0” "@"这个命令启动的进程替换正在执行的docker-entrypoint.sh进程,这样就保证了gosu redis “$0” "@"对应的进程ID为1;

  2. gosu redis “ 0 ” " @ " 导 致 d o c k e r − e n t r y p o i n t . s h 再 执 行 一 次 , 但 是 当 前 的 账 号 已 经 不 是 r o o t 了 , 于 是 会 执 行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值