2016-09-07 334 views
6

也许我错过了一些东西,但是我做了一个本地Docker镜像。我有一个3节点的群集,并正在运行。两名工人和一名经理。我使用标签作为约束。当我通过约束向其中一名工作人员启动一项服务时,如果该图像是公开的,它就可以很好地工作。Docker:Swarm Worker节点没有找到本地构建的镜像

也就是说,如果我做的:

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" 

有没有一种方法,使工作人员可以访问本地图像群的管理节点上?它是否使用可能未打开的特定端口?如果不是,我该怎么做 - 运行一个本地存储库?

回答

7

管理器节点不会从本身共享本地图像。您需要创建一个注册表服务器(或用户hub.docker.com)。需要这种努力并不十分显著:

# first create a user, updating $user for your environment: 
if [ ! -d "auth" ]; then 
    mkdir -p auth 
fi 
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 
+0

甜 - 谢谢!在我接受作为答案之前,(我不喜欢不一致!),管理器节点是否看到本地映像(不是来自docker run,而是来自docker service create)并且Worker节点不? – JoeG

+0

从用户的角度来看,也许。但从代码角度来看,每个Docker主机都是独立的环境。在构建时,您将在主机上创建该映像,而不是在群集上。 “服务创建”的逻辑是首先使用主机上缓存的内容,然后回退到从注册表中提取该映像。这恰好与'docker run'具有相同的行为。 – BMitch

+0

我可能会丢失一些东西,但群中的工作节点如何引用此注册表/映像?我试着在我的yml文件中放入localhost:5000/my/image,但我的工作节点仍然找不到图像。有没有办法让这个工作无需登录到工作节点? –

-1

图像必须被下载到本地缓存每个节点上。原因是,如果只将所有图像存储在一个节点上,并且该节点停止运行,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 
+2

我相信OP正在寻找覆盖本地构建映像的解决方案,而不是来自hub.docker.com的映像。 – BMitch

+1

@BMitch你说得对。我没有正确地阅读这个问题。时间到了这里的床上。 – Alkaline

0

对于我一步buide,这是不安全的工作这一步:

# 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 
+0

我可能会丢失一些东西,但群中的工作节点如何引用此注册表/映像?我试着把'localhost:5000/my/image'放到我的yml文件中,但我的工作节点仍然找不到图像。有没有办法让这项工作无需登录到工作节点? –

+0

尝试使用主机名而不是'localhost' – elkoo

+0

您应该如何知道注册表的主机名? – Philippe