2016-09-07 21 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