Docker:Swarm 工作节点未找到本地构建的映像
Docker: Swarm worker nodes not finding locally built image
也许我遗漏了什么,但我制作了本地docker图像。我有一个 3 节点的 swarm up 和 运行ning。两名工人和一名经理。我使用标签作为约束。当我通过约束向其中一名工作人员启动服务时,如果该图像是 public,它会完美运行。
也就是说,如果我这样做:
docker service create --name redis --network my-network --constraint node.labels.myconstraint==true redis:3.0.7-alpine
然后redis 服务被发送到其中一个工作节点并且功能齐全。同样,如果我 运行 我的本地构建镜像没有限制,因为我的经理也是一名工人,它会被安排给经理并且 运行 非常好。但是,当我添加约束时,它在工作节点上失败,从 docker service ps 2l30ib72y65h
我看到:
... Shutdown Rejected 14 seconds ago "No such image: my-customized-image"
有没有办法让worker可以访问swarm的manager节点上的本地镜像?它是否使用可能未打开的特定端口?如果没有,我该怎么办 - 运行 本地存储库?
manager节点不共享自己的本地镜像。您需要启动注册服务器(或用户 hub.docker.com)。为此所需的努力不是很大:
# first create a user, updating $user for your environment:
if [ ! -d "auth" ]; then
mkdir -p auth
fi
touch auth/htpasswd
chmod 666 auth/htpasswd
docker run --rm -it \
-v `pwd`/auth:/auth \
--entrypoint htpasswd registry:2 -B /auth/htpasswd $user
chmod 444 auth/htpasswd
# then spin up the registry service listening on port 5000
docker run -d -p 5000:5000 --restart=always --name registry \
-v `pwd`/auth/htpasswd:/auth/htpasswd:ro \
-v `pwd`/registry:/var/lib/registry \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Local Registry" \
-e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" \
-e "REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY=/var/lib/registry" \
registry:2
# then push your image
docker login localhost:5000
docker tag my-customized-image localhost:5000/my-customized-image
docker push localhost:5000/my-customized-image
# then spin up the service with the new image name
# replace registryhost with ip/hostname of your registry Docker host
docker service create --name custom --network my-network \
--constraint node.labels.myconstraint==true --with-registry-auth \
registryhost:5000/my-customized-image
图像必须下载到每个节点上的本地缓存。原因是如果您将所有图像仅存储在一个节点上并且该节点出现故障,swarm 将无法在其他节点上生成新任务(容器)。
我个人只是在启动服务之前拉取每个节点上所有图像的副本。这可以在 bash 脚本或 Makefile(例如下面)
中完成
pull:
@for node in $$NODE_LIST; do
OPTS=$$(docker-machine config $$node)
set -x
docker $$OPTS pull postgres:9.5.2
docker $$OPTS pull elasticsearch:2.3.3
docker $$OPTS pull schickling/beanstalkd
docker $$OPTS pull gliderlabs/logspout
etc ...
set +x
done
对我来说,这个循序渐进的指南很管用。但是,它是不安全的:
# Start your registry
$ docker run -d -p 5000:5000 --name registry registry:2
# Tag the image so that it points to your registry
$ docker tag my_existing_image localhost:5000/myfirstimage
# Push it to local registry/repo
$ docker push localhost:5000/myfirstimage
# For verification you can use this command:
$ curl -X GET http://localhost:5000/v2/_catalog
# It will print out all images on repo.
# On private registry machine add additional parameters to enable insecure repo:
ExecStart=/usr/bin/dockerd --insecure-registry IP_OF_CURRENT_MACHINE:5000
# Flush changes and restart Docker:
$ systemctl daemon-reload
$ systemctl restart docker.service
# On client machine we should say docker that this private repo is insecure, so create or modifile the file '/etc/docker/daemon.json':
{ "insecure-registries":["hostname:5000"] }
# Restart docker:
$ systemctl restart docker.service
# On swarm mode, you need to point to that registry, so use host name instead, for example: hostname:5000/myfirstimage
也许我遗漏了什么,但我制作了本地docker图像。我有一个 3 节点的 swarm up 和 运行ning。两名工人和一名经理。我使用标签作为约束。当我通过约束向其中一名工作人员启动服务时,如果该图像是 public,它会完美运行。
也就是说,如果我这样做:
docker service create --name redis --network my-network --constraint node.labels.myconstraint==true redis:3.0.7-alpine
然后redis 服务被发送到其中一个工作节点并且功能齐全。同样,如果我 运行 我的本地构建镜像没有限制,因为我的经理也是一名工人,它会被安排给经理并且 运行 非常好。但是,当我添加约束时,它在工作节点上失败,从 docker service ps 2l30ib72y65h
我看到:
... Shutdown Rejected 14 seconds ago "No such image: my-customized-image"
有没有办法让worker可以访问swarm的manager节点上的本地镜像?它是否使用可能未打开的特定端口?如果没有,我该怎么办 - 运行 本地存储库?
manager节点不共享自己的本地镜像。您需要启动注册服务器(或用户 hub.docker.com)。为此所需的努力不是很大:
# first create a user, updating $user for your environment:
if [ ! -d "auth" ]; then
mkdir -p auth
fi
touch auth/htpasswd
chmod 666 auth/htpasswd
docker run --rm -it \
-v `pwd`/auth:/auth \
--entrypoint htpasswd registry:2 -B /auth/htpasswd $user
chmod 444 auth/htpasswd
# then spin up the registry service listening on port 5000
docker run -d -p 5000:5000 --restart=always --name registry \
-v `pwd`/auth/htpasswd:/auth/htpasswd:ro \
-v `pwd`/registry:/var/lib/registry \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Local Registry" \
-e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" \
-e "REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY=/var/lib/registry" \
registry:2
# then push your image
docker login localhost:5000
docker tag my-customized-image localhost:5000/my-customized-image
docker push localhost:5000/my-customized-image
# then spin up the service with the new image name
# replace registryhost with ip/hostname of your registry Docker host
docker service create --name custom --network my-network \
--constraint node.labels.myconstraint==true --with-registry-auth \
registryhost:5000/my-customized-image
图像必须下载到每个节点上的本地缓存。原因是如果您将所有图像仅存储在一个节点上并且该节点出现故障,swarm 将无法在其他节点上生成新任务(容器)。
我个人只是在启动服务之前拉取每个节点上所有图像的副本。这可以在 bash 脚本或 Makefile(例如下面)
中完成pull:
@for node in $$NODE_LIST; do
OPTS=$$(docker-machine config $$node)
set -x
docker $$OPTS pull postgres:9.5.2
docker $$OPTS pull elasticsearch:2.3.3
docker $$OPTS pull schickling/beanstalkd
docker $$OPTS pull gliderlabs/logspout
etc ...
set +x
done
对我来说,这个循序渐进的指南很管用。但是,它是不安全的:
# Start your registry
$ docker run -d -p 5000:5000 --name registry registry:2
# Tag the image so that it points to your registry
$ docker tag my_existing_image localhost:5000/myfirstimage
# Push it to local registry/repo
$ docker push localhost:5000/myfirstimage
# For verification you can use this command:
$ curl -X GET http://localhost:5000/v2/_catalog
# It will print out all images on repo.
# On private registry machine add additional parameters to enable insecure repo:
ExecStart=/usr/bin/dockerd --insecure-registry IP_OF_CURRENT_MACHINE:5000
# Flush changes and restart Docker:
$ systemctl daemon-reload
$ systemctl restart docker.service
# On client machine we should say docker that this private repo is insecure, so create or modifile the file '/etc/docker/daemon.json':
{ "insecure-registries":["hostname:5000"] }
# Restart docker:
$ systemctl restart docker.service
# On swarm mode, you need to point to that registry, so use host name instead, for example: hostname:5000/myfirstimage