Docker Registry

1. 理解Registrynode

一個registry是一個存儲和內容交付系統,其中維護着若干命名的Docker鏡像,這些鏡像有不一樣的標記版本。(例如:有一個鏡像名字叫 hello/world,它有兩個tags分別是2.0和2.1)docker

用戶經過使用 docker pushdocker pull 命令與 registry 進行交互。(例如:docker pull registry-1.docker.io/hello/world:2.1)ubuntu

A registry is a storage and content delivery system, holding named Docker images, available in different tagged versions.
Users interact with a registry by using docker push and pull commands.

前面說了,registry是一個存儲系統,它存儲的是Docker鏡像。那麼,鏡像到底存到哪裏呢?存儲自己委託給驅動程序。默認的存儲驅動程序是本地posix文件系統,還支持其它基於雲的存儲驅動程序,例如 Aliyun OSS網絡

因爲保護對託管映像的訪問相當重要,所以Registry自己支持TLS和基自己份驗證。dom

1.1. 理解鏡像命名spa

docker pull ubuntu 指示docker從官方Docker Hub中拉取一個名字叫ubuntu的鏡像。這條命令實際上是docker pull docker.io/library/ubuntu的簡寫版本控制

docker pull myregistrydomain:port/foo/bar 指示docker拉取位於myregistrydomain:port的鏡像foo/bar rest

1.2. 用例orm

運行你本身的Registry是與CI/CD系統集成並對其進行補充的絕佳解決方案。在典型的工做流程中,對源版本控制系統的提交將觸發在CI系統上的構建,若是構建成功,則將新鏡像推送到你的Registry。而後,來自Registry的通知將觸發在暫存環境上的部署,或者通知其它系統有一個新鏡像可用。server

若是要在大型計算機集羣上快速部署新鏡像,它也是必不可少的組件。

這也是在隔離的網絡中分發鏡像的最佳方法。 

2. 部署一個registry server

# Run a local registry
docker run -d -p --restart=always --name registry registry:2

2.1. Copy an image from Docker Hub to your registry

你能夠從Docker Hub上拉取一個鏡像,並把它推送到你本身的Registry上。下面的例子中,從Docker Hub上拉取鏡像ubuntu:16.04,並將其從新打標記爲my-ubuntu,而後將其推送到本地registry,最後,再將ubuntu:16.04和my-ubuntu刪除。

# 1. Pull the ubuntu:16.04 image from Docker Hub
docker pull ubuntu:16.04

# 2. Tag the image as localhost:5000/my-ubuntu
# (注意,當tag的第一部分是主機名和端口時,push時Docker會將其解釋爲registry的位置)
docker tag ubuntu:16.04 localhost:5000/my-ubuntu

# 3. Push the image to the local registry running at localhost:5000
docker push localhost:5000/my-ubuntu

# 4. Remove the locally-cached ubuntu:16.04 and localhost:5000/my-ubuntu images, so that you can test pulling the image from your registry. This does not remove the localhost:5000/my-ubuntu image from your registry.
docker image remove ubuntu:16.04
docker image remove localhost:5000/my-ubuntu

# 5. Pull the localhost:5000/my-ubuntu image from your local registry
docker pull localhost:5000/my-ubuntu 

中止本地registry

# stop the registry
docker container stop registry
# remove the container
docker container stop registry && docker container rm -v registry

3. 基本配置

爲了配置container,能夠給docker run命令指定額外的選項參數 

# 自動重啓registry
# -p選項的值,第一個是主機端口,第二個是容器端口。在容器中,registry默認監聽端口是5000
docker run -d -p 5000:5000 --restart=always --name registry registry:2
# 自定義存儲位置
docker run -d -p 5000:5000 --restart=always --name registry -v /mnt/registry:/var/lib/registry registry:2

3.1. 運行一個外部可訪問的registry

運行一個僅在本地主機上可訪問的registry沒有什麼用處,爲了使你的registry可供外部主機訪問,必須首先使用TLS保護registry。

下面是一個將registry做爲服務來運行的例子:

首先,得到一個證書

假設你的registry的URL是https://myregistry.domain.com/,同時假設的DNS,路由和防火牆設置容許經過端口443訪問registry的主機,再假設你已經從CA那裏得到一個證書。

那麼,接下來

建立一個certs目錄

從CA那裏複製.crt和.key文件到certs目錄,假設分別重命名爲domain.crt和domain.key

重啓registry,將其指向使用TLS證書

docker run -d \
     --restart=always \
     --name registry \
     -v "$(pwd)"/certs:/certs \
     -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
     -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
     -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
     -p 443:443 \
     registry:2 

如今Docker客戶端就能夠經過registry的外網地址進行pull和push了

docker pull ubuntu:16.04
docker tag ubuntu:16.04 myregistry.domain.com/my-ubuntu
docker push myregistry.domain.com/my-ubuntu
docker pull myregistry.domain.com/my-ubuntu

將registry做爲一個服務運行

與獨立容器相比,swarm services具備多個優勢。它們使用聲明式模型,這意味着你定義了所需的狀態,而Docker則將服務保持在該狀態。服務提供了自動負載平衡擴展,並具備控制服務分配的能力以及其餘優點。服務還容許你祕密存儲敏感數據,例如TLS證書。 

下面這個例子將registry做爲單副本服務啓動,能夠在端口80上的任何羣集節點上訪問該registry,並假定使用的是與前面示例相同的TLS證書。

# 首先,保存TLS證書和key做爲secret
docker secret create domain.crt certs/domain.crt
docker secret create domain.key certs/domain.key

# 接下來,將你想要在上面容許registry的node添加一個標籤
docker node update --label-add registry=true node1

# 再接着,建立一個服務,並受權它能夠訪問兩個secret,並將其限制爲僅在標籤爲registry=true的節點上運行
docker service create \
     --name registry \
     --secret domain.crt \
     --secret domain.key \
     --constraint 'node.labels.registry==true' \
     --mount type=bind,src=/mnt/registry,dst=/var/lib/registry \
     -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
     -e REGISTRY_HTTP_TLS_CERTIFICATE=/run/secrets/domain.crt \
     -e REGISTRY_HTTP_TLS_KEY=/run/secrets/domain.key \
     --publish published=443,target=443 \
     --replicas 1 \
     registry:2

如今你能夠在任何swarm節點的443端口上訪問服務。Docker會將請求發送到運行該服務的節點。 

4. 文檔

# 啓動registry
docker run -d -p 5000:5000 --name registry registry:2
# 從Docker Hub上拉取鏡像
docker pull ubuntu
# 給鏡像打tag
docker image tag ubuntu localhost:5000/myfirstimage
# 推送至你本身的registry
docker push localhost:5000/myfirstimage
# 再次從你本身的registry拉取鏡像
docker pull localhost:5000/myfirstimage
# 中止registry並刪除全部數據
docker container stop registry && docker container rm -v registry

https://docs.docker.com/registry/introduction/

https://docs.docker.com/registry/deploying/

相關文章
相關標籤/搜索