docker 拉入单元文件仅在第一次启动时有效,稍后会被忽略
docker pull in unit files only works at first start, gets ignored later on
我有一个单元,运行 docker 图片的 "latest" 标签。最新的图像是在第一次启动时通过 "docker pull" 命令从单元文件中获取的。
但是在任何后续(重新)启动时,"docker pull" 命令似乎都不会被执行,因为任何带有 "latest" 标记的新图像修订都不会被拉出。
运行 命令行上的 "docker pull ..." 按预期工作。
我的服务文件:
[Unit]
Description=Foo
Requires=docker.service
After=docker.service
[Service]
TimeoutStartSec=0
KillMode=none
EnvironmentFile=/etc/environment
ExecStartPre=-/usr/bin/docker kill foo
ExecStartPre=-/usr/bin/docker rm foo
ExecStartPre=/usr/bin/docker login -e foo@example.com -u bla -p xxxxx https://myregistry.example.com && /usr/bin/docker pull myregistry.example.com/foo
ExecStart=/usr/bin/docker run --name foo myregistry.example.com/foo
ExecStop=/usr/bin/docker stop foo
[X-Fleet]
Global=true
这种行为是故意的吗?是否有解决方法?
提前致谢!
编辑:运行 CoreOS 557.2.0、docker 1.4.1 和 fleetd 0.9.0
选项 1 - 使用多个 ExecStartPre
我不确定您是否可以在 ExecStartPre
部分中使用 shell 风格的 &&
。
所以一种简单的方法就是将其分解
ExecStartPre=/usr/bin/docker login -e foo@example.com -u bla -p xxxxx https://myregistry.example.com
ExecStartPre=/usr/bin/docker pull myregistry.example.com/foo
选项 2 - 通过云配置安装 .dockercfg 凭据
如果您不想在单元文件中嵌入凭据,您可以让您的 CoreOS 云配置使用这样的部分编写凭据
write_files:
- path: /home/core/.dockercfg
owner: core:core
permissions: 0644
content: |
{"https://myregistry.example.com:5000":{"auth":"Y2FudGJlbGlldmU6eW91ZGVjb2RlZHRoaXM=","email":"user@example.com"}}
auth 值是一个 base64 username:password 组合,您可以创建它或只获取一个有效的 .dockercfg 文件。
因此,现在您的 CoreOS 机器将使用它们需要的凭据启动,您还需要做一件事 - 确保需要以核心用户身份登录注册表的单元 运行:
[Service]
User=core
ExecStartPre=/usr/bin/docker pull myregistry.example.com/foo
选项 3 - 使用实际 shell
如果你想做类似 shell 的事情,你总是可以启动一个 shell 并让它执行你需要的
ExecStartPre=/bin/sh -c '/usr/bin/docker login -e foo@example.com -u bla -p xxxxx https://myregistry.example.com && /usr/bin/docker pull myregistry.example.com/foo'
我有一个单元,运行 docker 图片的 "latest" 标签。最新的图像是在第一次启动时通过 "docker pull" 命令从单元文件中获取的。
但是在任何后续(重新)启动时,"docker pull" 命令似乎都不会被执行,因为任何带有 "latest" 标记的新图像修订都不会被拉出。
运行 命令行上的 "docker pull ..." 按预期工作。
我的服务文件:
[Unit]
Description=Foo
Requires=docker.service
After=docker.service
[Service]
TimeoutStartSec=0
KillMode=none
EnvironmentFile=/etc/environment
ExecStartPre=-/usr/bin/docker kill foo
ExecStartPre=-/usr/bin/docker rm foo
ExecStartPre=/usr/bin/docker login -e foo@example.com -u bla -p xxxxx https://myregistry.example.com && /usr/bin/docker pull myregistry.example.com/foo
ExecStart=/usr/bin/docker run --name foo myregistry.example.com/foo
ExecStop=/usr/bin/docker stop foo
[X-Fleet]
Global=true
这种行为是故意的吗?是否有解决方法?
提前致谢!
编辑:运行 CoreOS 557.2.0、docker 1.4.1 和 fleetd 0.9.0
选项 1 - 使用多个 ExecStartPre
我不确定您是否可以在 ExecStartPre
部分中使用 shell 风格的 &&
。
所以一种简单的方法就是将其分解
ExecStartPre=/usr/bin/docker login -e foo@example.com -u bla -p xxxxx https://myregistry.example.com
ExecStartPre=/usr/bin/docker pull myregistry.example.com/foo
选项 2 - 通过云配置安装 .dockercfg 凭据
如果您不想在单元文件中嵌入凭据,您可以让您的 CoreOS 云配置使用这样的部分编写凭据
write_files:
- path: /home/core/.dockercfg
owner: core:core
permissions: 0644
content: |
{"https://myregistry.example.com:5000":{"auth":"Y2FudGJlbGlldmU6eW91ZGVjb2RlZHRoaXM=","email":"user@example.com"}}
auth 值是一个 base64 username:password 组合,您可以创建它或只获取一个有效的 .dockercfg 文件。
因此,现在您的 CoreOS 机器将使用它们需要的凭据启动,您还需要做一件事 - 确保需要以核心用户身份登录注册表的单元 运行:
[Service]
User=core
ExecStartPre=/usr/bin/docker pull myregistry.example.com/foo
选项 3 - 使用实际 shell
如果你想做类似 shell 的事情,你总是可以启动一个 shell 并让它执行你需要的
ExecStartPre=/bin/sh -c '/usr/bin/docker login -e foo@example.com -u bla -p xxxxx https://myregistry.example.com && /usr/bin/docker pull myregistry.example.com/foo'