请教个关于 docker 中 init 进程的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yezheyu
V2EX    Docker

请教个关于 docker 中 init 进程的问题

  •  
  •   yezheyu 2024-07-22 20:47:58 +08:00 1546 次点击
    这是一个创建于 447 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我想用 docker 的官方镜像仓库 registry 搭建一个本地镜像仓库。registry 在删除镜像后默认只会删除镜像的 manifest ,需要手动 gc(garbage-collect)来释放 layer 。

    而调用 gc 又要求需要把 registry 设置为 readonly 模式来保证不会误删用户正在上传的镜像。

    我想设计一个镜像,tini 作为 init 进程,执行 registry 进程来接收用户的 CRUD 镜像请求,再使用 cron 执行一个定时任务:一段时间后停止 registry ,然后以 readonly 方式重启动 registry ,再执行 gc ,执行完 gc ,再去掉 readonly ,重启 registry

    下面是涉及到的所有文件:

    $ ls readonly_config.yml normal_config.yml Dockerfile gc.sh registry_with_gc.sh $ cat Dockerfile FROM registry WORKDIR / RUN apk add dcron RUN apk add tini COPY *.sh / COPY *.yml /etc/docker/registry ENTRYPOINT ["tini", "--"] CMD ["./registry_with_gc.sh"] # 添加一个 gc.sh 的定时任务,启动 registry 服务 $ cat registry_with_gc.sh #!/bin/sh crond { crontab -l 2>/dev/null; echo "* * * * * sh /gc.sh >> /tmp/gc.log 2>&1"; } | crontab - registry serve /etc/docker/registry/normal_config.yml # registry 切换到 readonly 模式,在进行 gc ,最后再切换回来 $ cat gc.sh #!/bin/sh # stop registry serve killall registry # wait for registry stop sleep 1 # start registry serve with readonly_config.yml registry serve /etc/docker/registry/readonly_config.yml & # gc registry garbage-collect /etc/docker/registry/normal_config.yml # stop registry serve killall registry # wait for registry stop sleep 1 # start registry serve with normal_config.yml registry serve /etc/docker/registry/normal_config.yml $ cat normal_config.yml version: 0.1 log: fields: service: registry storage: cache: blobdescriptor: inmemory filesystem: rootdirectory: /var/lib/registry delete: enabled: true http: addr: :5000 headers: X-Content-Type-Options: [nosniff] health: storagedriver: enabled: true interval: 10s threshold: 3 # 多一个 readonly.enabled: true 字段 $ cat readonly_config.yml version: 0.1 log: fields: service: registry storage: cache: blobdescriptor: inmemory filesystem: rootdirectory: /var/lib/registry maintenance: readonly: enabled: true http: addr: :5000 headers: X-Content-Type-Options: [nosniff] health: storagedriver: enabled: true interval: 10s threshold: 3 

    问题:

    镜像 build 后,容器启动一会,当定时任务 gc.sh 执行时,执行到第一行停止 registry ,就会杀掉registry_with_gc.sh中的 registry ,导致registry_with_gc.sh结束,接着容器就结束,没法执行后续的 gc 任务。

    这种该怎么解决呢?registry_with_gc.sh命令结束了,但是 tini 作为 init 进程不是没有结束吗?为啥容器的生命周期就结束呢?

    难道要把registry_with_gc.sh变成死循环吗?

    5 条回复    2024-07-23 14:51:59 +08:00
    loveqianool
        1
    loveqianool  
       2024-07-22 21:33:55 +08:00 via Android
    为什么不愿意死循环,有什么说法吗?
    povsister
        2
    povsister  
       2024-07-22 22:39:39 +08:00
    你 CMD 直接替换了 entrypoint ,1 号进程是 sh 不是 tini 了

    问个题外话,你这么直接杀,正在上传镜像的用户就不管了?直接上传失败?
    yezheyu
        3
    yezheyu  
    OP
       2024-07-23 09:39:29 +08:00
    @povsister
    嗯,如果你是指 Dockerfile 中这两行会发生替换,我认为你可能理解有偏差,可以自己翻下文档
    ENTRYPOINT ["tini", "--"]
    CMD ["./registry_with_gc.sh"]

    至于第二点,我这是随便设计的,上传失败大不了重新上传,也没太大代价。如果真要较真,引入 Redis 作为上传请求数的计数器?
    yezheyu
        4
    yezheyu  
    OP
       2024-07-23 09:58:29 +08:00
    @loveqianool
    没啥说法吧,我只是不明白,既然我使用了 tini 作为 PID 的进程,registry_with_gc 作为其子进程就应该可以使用完就释放掉,要不然 tini 的作用在哪?只是作为信号转发器?

    按我的理解,tini 作为 init 进程,只要其还在,容器的生命周期就不会结束,registry_with_gc 挂了也就挂了,不会导致容器结束
    julyclyde
        5
    julyclyde  
       2024-07-23 14:51:59 +08:00
    @yezheyu 你可以给各个进程挂上 strace 看一下

    按说 tini 作为 init 只要还在,整个容器不会结束
    但是你咋知道 tini 确实还在呢?这个先入为主的思维不对啊
    你应该去研究为什么它退出了,而不是问为什么它没退出却容器停了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3174 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 158ms UTC 12:13 PVG 20:13 LAX 05:13 JFK 08:13
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86