小天管理 发表于 2024年7月22日 发表于 2024年7月22日 我想用 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变成死循环吗?
已推荐帖子