【问题标题】:<CoreOS, cloud-config> How to 'Wait' until Docker Private Registry is ready?<CoreOS, cloud-config> 如何在 Docker Private Registry 准备好之前“等待”?
【发布时间】:2015-07-24 20:34:47
【问题描述】:

我正在 EC2 上的 CoreOS 上尝试 Docker。

我想做的是:

  • 运行 Docker 私有注册表容器
  • 从私有仓库拉取镜像后运行其他容器

初始配置

我的cloud-config.yml是这样的:

#cloud-config
coreos:
  units:
    - name: etcd2.service
      command: start

    - name: fleet.service
      command: start

    - name: docker.service
      command: start
      drop-ins:
        - name: 50-insecure-registry.conf
          content: |
            [Service]
            Environment=DOCKER_OPTS='--insecure-registry="localhost:5000"'

    - name: private-docker-registry.service
      command: start
      runtime: true
      content: |
       [Unit]
       Description=Docker Private Registry
       After=docker.service
       Requires=docker.service
       Requires=network-online.target
       After=network-online.target

       [Service]
       ExecStartPre=/usr/bin/docker pull registry:latest
       ExecStart=/usr/bin/docker run --name private-docker-registry --privileged -e SETTINGS_FLAVOR=s3 -e AWS_BUCKET=bucket -e AWS_KEY=awskey -e AWS_SECRET=awssecret -e SEARCH_BACKEND=sqlalchemy -p 5000:5000 registry:latest

    - name: myservice.service
      command: start
      runtime: true
      content: |
       [Unit]
       Description=My Service
       After=private-docker-registry.service
       Requires=private-docker-registry.service
       Requires=network-online.target
       After=network-online.target

       [Service]
       ExecStartPre=/usr/bin/docker pull localhost:5000/myservice:latest
       ExecStart=/usr/bin/docker run --name myservice localhost:5000/myservice:latest

myservice.service 失败

这里的问题是:

  • 虽然私有注册表容器成功运行,但 myservice.service 失败

当我登录机器时,它显示以下消息。

Failed Units: 1
  myservice.service

命令journalctl -u private-docker-registry.service 显示:

Jul 24 07:30:25 docker[830]: [2015-07-24 07:30:25 +0000] [1] [INFO] Listening at: http://0.0.0.0:5000 (1)

命令journalctl -u myservice.service 显示以下日志。

Jul 24 07:30:25 systemd[1]: Starting My Service...
Jul 24 07:30:25 docker[836]: time="2015-07-24T07:30:25Z" level=fatal msg="Error response from daemon: v1 ping attempt failed with error: Get http://localhost:5000/v1/_ping: dial tcp 127.0.0.1:5000: connection refused"
Jul 24 07:30:25 systemd[1]: myservice.service: Control process exited, code=exited status=1
Jul 24 07:30:25 systemd[1]: Failed to start My Service.
Jul 24 07:30:25 systemd[1]: myservice.service: Unit entered failed state.
Jul 24 07:30:25 systemd[1]: myservice.service: Failed with result 'exit-code'.

但是,我可以手动运行 myservice 容器(几分钟后)。

docker run --name myservice localhost:5000/myservice:latest

我的假设是:

  • 拉取myservice 映像失败,因为myservice.service 在私有注册表开始侦听后立即尝试拉取myservice 映像。

试错

基于我上面的假设,我添加了wait-for-registry.service,它在私有注册表启动后等待 2 分钟。

#cloud-config
coreos:
  units:
    - name: etcd2.service
      command: start

    - name: fleet.service
      command: start

    - name: docker.service
      command: start
      drop-ins:
        - name: 50-insecure-registry.conf
          content: |
            [Service]
            Environment=DOCKER_OPTS='--insecure-registry="localhost:5000"'

    - name: private-docker-registry.service
      command: start
      runtime: true
      content: |
       [Unit]
       Description=Docker Private Registry
       After=docker.service
       Requires=docker.service
       Requires=network-online.target
       After=network-online.target

       [Service]
       ExecStartPre=/usr/bin/docker pull registry:latest
       ExecStart=/usr/bin/docker run --name private-docker-registry --privileged -e SETTINGS_FLAVOR=s3 -e AWS_BUCKET=bucket -e AWS_KEY=awskey -e AWS_SECRET=awssecret -e SEARCH_BACKEND=sqlalchemy -p 5000:5000 registry:latest

    - name: wait-for-registry.service
      command: start
      runtime: true
      content: |
       [Unit]
       Description=Wait Until Private Registry is Ready
       After=private-docker-registry.service
       Requires=private-docker-registry.service

       [Service]
       ExecStart=/usr/bin/sleep 120

    - name: myservice.service
      command: start
      runtime: true
      content: |
       [Unit]
       Description=My Service
       After=wait-for-registry.service
       After=private-docker-registry.service
       Requires=private-docker-registry.service
       Requires=network-online.target
       After=network-online.target

       [Service]
       ExecStartPre=/usr/bin/docker pull localhost:5000/myservice:latest
       ExecStart=/usr/bin/docker run --name myservice localhost:5000/myservice:latest

但这会导致同样的问题。

命令journalctl -u private-docker-registry.service 显示:

Jul 24 08:23:38 docker[838]: [2015-07-24 08:23:38 +0000] [1] [INFO] Listening at: http://0.0.0.0:5000 (1)

命令journalctl -u wait-for-registry.service 显示:

Jul 24 08:23:37 systemd[1]: Started Wait Until Private Registry is Ready.
Jul 24 08:23:37 systemd[1]: Starting Wait Until Private Registry is Ready...

命令journalctl -u myservice.service 显示:

Jul 24 08:23:37 systemd[1]: Starting My Service...
Jul 24 08:23:37 docker[847]: time="2015-07-24T08:23:37Z" level=fatal msg="Error response from daemon: v1 ping attempt failed with error: Get http://localhost:5000/v1/_ping: dial tcp 127.0.0.1
Jul 24 08:23:37 systemd[1]: myservice.service: Control process exited, code=exited status=1
Jul 24 08:23:37 systemd[1]: Failed to start My Service.
Jul 24 08:23:37 systemd[1]: myservice.service: Unit entered failed state.
Jul 24 08:23:37 systemd[1]: myservice.service: Failed with result 'exit-code'.

sleep好像没有效果。

问题

我怎样才能让它等到私有注册表可用?

欢迎任何提示或建议!

谢谢:)

【问题讨论】:

    标签: amazon-ec2 docker coreos


    【解决方案1】:

    systemd 单元文件很棘手 :-)

    我想你已经拥有它了。我不是专家,但我会尝试解释我认为正在发生的事情。

    首先,我想你可能想添加一个:

    - name: wait-for-registry.service
      command: start
      runtime: true
      content: |
       [Unit]
       Description=Wait Until Private Registry is Ready
       After=private-docker-registry.service
       Requires=private-docker-registry.service
    
       [Service]
       ExecStart=/usr/bin/sleep 120
       RemainAfterExit=true
       Type=oneshot
    

    解释是 /usr/bin/sleep 120 启动。既然启动了,链中的下一个 Unit 就会启动(你的 myservice.service)。通过将其更改为 oneshot,您必须等到它完成。不过,我在这里猜测,因为大部分单元内容对我来说都是反复试验。

    我的单元文件中确实有类似的结构。我不认为你真的想要“睡觉”,那是一种黑客行为。我认为您真的想等到端口 5000 响应,对吗?如果是这种情况,您可以将 sleep 替换为:

    ExecStart=/usr/bin/bash /opt/bin/waiter.sh
    

    然后,朝向云配置的顶部:

    write_files:
      - path: /opt/bin/waiter.sh
        permissions: 0755
        owner: root
        content: |
          #! /usr/bin/bash
          until curl -s http://127.0.0.1:5000/; do echo waiting waiter.sh; sleep 2; done
    

    或类似的东西。等到那个端口有东西再继续。

    -g

    【讨论】:

    • 这真的很有帮助!我很感激你,@Greg:-)
    猜你喜欢
    • 2019-02-18
    • 2019-03-15
    • 1970-01-01
    • 2018-08-13
    • 2018-10-21
    • 1970-01-01
    • 1970-01-01
    • 2020-06-21
    • 1970-01-01
    相关资源
    最近更新 更多