V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yezheyu
V2EX  ›  Docker

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

  •  
  •   yezheyu · 152 天前 · 1159 次点击
    这是一个创建于 152 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我想用 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  
       152 天前 via Android
    为什么不愿意死循环,有什么说法吗?
    povsister
        2
    povsister  
       152 天前
    你 CMD 直接替换了 entrypoint ,1 号进程是 sh 不是 tini 了

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

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

    按我的理解,tini 作为 init 进程,只要其还在,容器的生命周期就不会结束,registry_with_gc 挂了也就挂了,不会导致容器结束
    julyclyde
        5
    julyclyde  
       152 天前
    @yezheyu 你可以给各个进程挂上 strace 看一下

    按说 tini 作为 init 只要还在,整个容器不会结束
    但是你咋知道 tini 确实还在呢?这个先入为主的思维不对啊
    你应该去研究为什么它退出了,而不是问为什么它没退出却容器停了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2682 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 07:45 · PVG 15:45 · LAX 23:45 · JFK 02:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.