配置私有倉庫(使用registry鏡像搭建一個私有倉庫)


在使用Docker一段時間后,往往會發現手頭積累了大量的自定義鏡像文件,這些文件通過公有倉庫進行管理並不方便;另外有時候只是希望在內部用戶之間進行分享,不希望暴露出去。這種情況下,就有必要搭建一個本地私有鏡像倉庫。

使用Docker Registry的兩種主要方式:通過容器方式運行通過本地安裝運行並注冊為系統服務,以及添加Nginx反向代理添加用戶認證功能。Docker Registry配置文件中各個選項的含義和使用。如何通過腳本來實現對鏡像的批量管理,以及使用Registry的通知系統來支持更多應用場景。

安裝Docker Registry

Docker Registry工具目前最新為2.0系列版本,這一版本與一些類庫、工具一起被打包為負責容器內容分發的工具集:Docker Distribution。目前其核心的功能組件仍為負責鏡像倉庫的管理。新版本的Registry基於Golang進行了重構,提供更好的性能和擴展性,並且支持Docker 1.6+的API,非常適合用來構建私有的鏡像注冊服務器。官方倉庫中也提供了Registry的鏡像,因此用戶可以通過容器運行源碼安裝兩種方式來使用Registry。

1.基於容器安裝運行

基於容器的運行方式十分簡單,只需要一條命令:

$ docker run -d -p 5000:5000 --restart=always --name registry registry:2.1

啟動后比較關鍵的參數是指定配置文件和倉庫存儲路徑

Registry默認的配置文件為/etc/docker/registry/config.yml,因此,通過如下命令,可以指定使用本地主機上的配置文件(如/home/user/registry-conf)。

$ docker run -d -p 5000:5000 \

--restart=always \

--name registry \

-v /home/user/registry-conf/config.yml:/etc/docker/registry/config.yml \

registry:2

此外,Registry默認的存儲位置為/var/lib/registry,可以通過-v參數來映射本地的路徑到容器內。

例如下面的例子將鏡像存儲到本地/opt/data/registry目錄。

$ docker run -d -p 5000:5000 --restart=always --name registry \

-v /opt/data/registry:/var/lib/registry \

registry:2

2.本地安裝運行

有時候需要本地運行倉庫服務,可以通過源碼方式進行安裝。

首先安裝Golang環境支持,以Ubuntu為例,可以執行如下命令:

$ sudo add-apt-repository ppa:ubuntu-lxc/lxd-stable
$ sudo apt-get update
$ sudo apt-get install golang

確認Golang環境安裝成功,並配置$GOPATH環境變量,例如/go。

創建$GOPATH/src/github.com/docker/目錄,並獲取源碼,如下所示:

$ mkdir -p $GOPATH/src/github.com/docker/
$ cd $GOPATH/src/github.com/docker/
$ git clone https://github.com/docker/distribution.git
$ cd distribution

將自帶的模板配置文件復制到/etc/docker/registry/路徑下,創建存儲目錄/var/lib/registry:

$ cp cmd/registry/config-dev.yml /etc/docker/registry/config.yml
$ mkdir -p /var/lib/registry

然后執行安裝操作:

$ make PREFIX=/go clean binaries

編譯成功后,可以通過下面的命令來啟動:

$ registry server /etc/docker/registry/config.yml

此時使用訪問本地的5000端口,看到返回成功(200 OK),則說明運行成功:

$ curl -i 127.0.0.1:5000/v2/

HTTP/1.1 200 OK

配置TLS證書

當本地主機運行Registry服務后,所有能訪問到該主機的Docker Host都可以把它作為私有倉庫使用。只需要在鏡像名稱前面添加上具體的服務器地址

例如將本地的ubuntu:latest鏡像上傳到私有倉庫myrepo.com:

$ docker tag ubuntu myrepo.com:5000/ubuntu

$ docker push myrepo.com:5000/ubuntu

或者從私有倉庫myrepo.com下載鏡像到本地:

$ docker pull myrepo.com:5000/ubuntu

$ docker tag myrepo.com:5000/ubuntu ubuntu

私有倉庫需要啟用TLS認證,否則會報錯。可以通過添加DOCKER_OPTS="--insecure-registry myrepo.com:5000來躲過這個問題。

在這里將介紹如何獲取和生成TLS證書。

1.自行生成證書

使用openssl工具可以很容易地生成私人證書文件:

mkdir -p certs

$ openssl req -newkey rsa:4096 -nodes -sha256 -keyout certs/myrepo.key -x509 -days 365 -out certs/myrepo.crt

生成過程中會提示填入各種信息,注意CN一欄的信息要填入跟訪問的地址相同的域名,例如這里應該為myrepo.com。

生成結果為秘鑰文件myrepo.key,以及證書文件myrepo.crt。

其中證書文件需要發送給用戶,並且配置到用戶Docker Host上,注意路徑需要跟域名一致,例如:/etc/docker/certs.d/myrepo.com:5000/ca.crt

2.從代理商申請證書

如果Registry服務需要對外公開,需要申請大家都認可的證書。

知名的代理商包括SSLs.com、GoDaddy.com、LetsEncrypt.org、GlobalSign.com等,用戶可以自行選擇權威的證書提供商。

3.啟用證書

當擁有秘鑰文件和證書文件后,可以配置Registry啟用證書支持,主要通過REGISTRY_HTTP_TLS_CERTIFICATE和REGISTRY_HTTP_TLS_KEY參數來設置:

docker run -d -p 5000:5000 --restart=always --name registry \

-v `pwd`/certs:/certs \

-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/myrepo.crt \

-e REGISTRY_HTTP_TLS_KEY=/certs/myrepo.key \

registry:2

管理訪問權限

通常在生產場景中,對私有倉庫還需要進行訪問代理,以及提供認證和用戶管理。

1.Docker Registry v2的認證模式

Docker Registry v2的認證模式和v1有了較大的變化,降低了系統的復雜度、減少了服務之間的交互次數,其基本工作模式:

具體交互過程包括如下步驟:

1)Docker Daemon或者其他客戶端嘗試訪問Registry服務器,比如pull、push或者訪問manifiest文件;

2)在Registry服務器開啟了認證服務模式時,就會直接返回401 Unauthorized錯誤,並通知調用方如何獲得授權;

3)調用方按照要求,向Authorization Service發送請求,並攜帶Authorization Service需要的信息,比如用戶名、密碼;

4)如果授權成功,則可以拿到合法的Bearer token,來標識該請求方可以獲得的權限;

5)請求方將拿到Bearer token加到請求的Authorization header中,再次嘗試步驟1中的請求;

6)Registry服務通過驗證Bearer token以及JWT格式的授權數據,來決定用戶是否有權限進行請求的操作。

當啟用認證服務時,需要注意以下兩個地方:

  1. 對於Authentication Service,Docker官方目前並沒有放出對應的實現方案,需要自行實現對應的服務接口;
  2. Registry服務和Authentication服務之間通過證書進行Bearer token的生成和認證,所以要保證兩個服務之間證書的匹配。

除了使用第三方實現的認證服務(如docker_auth、SUSE Portus等)外,還可以通過Nginx代理方式來配置基於用戶名密碼的認證。

2.配置Nginx代理

使用Nginx來代理Registry服務的原理十分簡單,我們讓Registry服務監聽在127.0.0.1:5000,這意味着只允許本機才能通過5000端口訪問到,其他主機是無法訪問到的。為了讓其他主機訪問到,可以通過Nginx監聽在對外地址的15000端口,當外部訪問請求到達15000端口時,內部再將請求轉發到本地的5000端口。

首先,安裝Nginx:

$ sudo apt-get -y install nginx

在/etc/nginx/sites-available/目錄下,創建新的站點配置文件/etc/nginx/sites-available/docker-registry.conf,代理本地的15000端口轉發到5000端口。

配置文件內容如下:

#本地的registry服務監聽在15000端口
upstream docker-registry {
  server localhost:5000;
}
#代理服務器監聽在15000端口
server {
  listen 15000;
  server_name private-registry-server.com;
  add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always;
  # If you have SSL certification files, then can enable this section.
  ssl on;
  ssl_certificate /etc/ssl/certs/myrepo.crt;
  ssl_certificate_key /etc/ssl/private/myrepo.key;
  proxy_pass                          http://docker-registry;
  proxy_set_header  Host              \$http_host;   # required for docker
  client's sake
  proxy_set_header  X-Real-IP         \$remote_addr; # pass on real client's IP
  proxy_set_header  X-Forwarded-For   \$proxy_add_x_forwarded_for;
  proxy_set_header  X-Forwarded-Proto \$scheme;
  proxy_read_timeout                  600;
  client_max_body_size 0; # disable any limits to avoid HTTP 413 for large
  image uploads
  # required to avoid HTTP 411: see Issue #1486 (https://github.com/dotcloud/docker/issues/1486)
  chunked_transfer_encoding on;
  location /v2/ {#禁止舊版本Docker訪問
    if (\$http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*\$" ) {
      return 404;
    }
    #配置轉發訪問請求到registry服務
    proxy_pass http://docker-registry;
  }
}

建立配置文件軟連接,放到/etc/nginx/sites-enabled/下面,讓Nginx啟用它,最后重啟Nginx服務:

$ sudo ln -s /etc/nginx/sites-available/docker-registry.conf /etc/nginx/sites-enabled/docker-registry.conf

$ service nginx restart

之后,可以通過上傳鏡像來測試服務是否正常。測試上傳本地的ubuntu:latest鏡像:

$ docker tag ubuntu:14.04 127.0.0.1:15000/ubuntu:latest

$ docker push 127.0.0.1:15000/ubuntu:latest

3.添加用戶認證

公共倉庫Docker Hub是通過注冊索引(index)服務來實現的。由於Index服務並沒有完善的開源實現,在這里介紹基於Nginx代理的用戶訪問管理方案。

Nginx支持基於用戶名和密碼的訪問管理。

首先,在配置文件的location/字段中添加兩行:

...
location / {
  # let Nginx know about our auth file
  auth_basic "Please Input username/password";
  auth_basic_user_file    docker-registry-htpasswd;
  proxy_pass http://docker-registry;
}
...

其中,auth_basic行說明啟用認證服務,不通過的請求將無法轉發。auth_basic_user_file行則指定了驗證的用戶名密碼存儲文件為本地(/etc/nginx/下)的docker-registry-htpasswd文件。

docker-registry-htpasswd文件中存儲用戶名密碼的格式為每行放一個用戶名、密碼對。

例如:
...
user1:password1
user2:password2
...

需要注意的是,密碼字段存儲的並不是明文,而是使用crypt函數加密過的字符串。

要生成加密后的字符串,可以使用htpasswd工具,首先安裝apache2-utils:

$ sudo aptitude install apache2-utils -y

創建用戶user1,並添加密碼。

例如,如下的操作會創建/etc/nginx/docker-registry-htpasswd文件來保存用戶名和加密后的密碼信息,並創建user1和對應的密碼:

$ sudo htpasswd -c /etc/nginx/docker-registry-htpasswd user1

$ New password:

$ Re-type new password:

$ Adding password for user user1

添加更多用戶,可以重復上面的命令(密碼文件存在后,不需要再使用-c選項來新創建)。

最后,重新啟動Nginx服務:

$ sudo service nginx restart

此時,通過瀏覽器訪問本地的服務http://127.0.0.1:15000/v2/,會彈出對話框,提示需要輸入用戶名和密碼。

通過命令行訪問,需要在地址前面帶上用戶名和密碼才能正常返回:

$ curl USERNAME:PASSWORD@127.0.0.1:15000/v2/

除了使用Nginx作為反向代理外,Registry自身也支持簡單的基於用戶名和密碼的認證和基於token的認證,可以通過如下環境變量來指定:

REGISTRY_AUTH: htpasswd

REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd

REGISTRY_AUTH_HTPASSWD_REALM: basic

4.用Compose啟動Registry

一般情況下,用戶使用Registry需要的配置包括存儲路徑、TLS證書和用戶認證。

這里提供一個基於Docker Compose的快速啟動Registry的模板:

registry:
restart: always
image: registry:2.1
ports:
  - 5000:5000
environment:
REGISTRY_HTTP_TLS_CERTIFICATE: /certs/myrepo.crt
REGISTRY_HTTP_TLS_KEY: /certs/myrepo.key
REGISTRY_AUTH: htpasswd
REGISTRY_AUTH_HTPASSWD_PATH: /auth/docker-registry-htpasswd
REGISTRY_AUTH_HTPASSWD_REALM: basic
volumes:
  - /path/to/data:/var/lib/registry
  - /path/to/certs:/certs
  - /path/to/auth:/auth

配置Registry

Docker Registry提供了一些樣例配置,用戶可以直接使用它們來進行開發或生產部署。

使用配置文件來管理私有倉庫。

示例配置

代碼如下:

version: 0.1
log:
level: debug
fields:
service: registry
environment: development
hooks:
  - type: mail
disabled: true
levels:
  - panic
options:
smtp:
addr: mail.example.com:25
username: mailuser
password: password
insecure: true
from: sender@example.com
to:
  - errors@example.com
storage:
delete:
enabled: true
cache:
blobdescriptor: redis
filesystem:
rootdirectory: /var/lib/registry
maintenance:
uploadpurging:
enabled: false
http:
addr: :5000
debug:
addr: localhost:5001
headers:
X-Content-Type-Options: [nosniff]
redis:
addr: localhost:6379
pool:
maxidle: 16
maxactive: 64
idletimeout: 300s
dialtimeout: 10ms
readtimeout: 10ms
writetimeout: 10ms
notifications:
endpoints:
  - name: local-5003
url: http://localhost:5003/callback
headers:
Authorization: [Bearer ]
timeout: 1s
threshold: 10
backoff: 1s
disabled: true
  - name: local-8083
url: http://localhost:8083/callback
timeout: 1s
threshold: 10
backoff: 1s
disabled: true
health:
storagedriver:
enabled: true
interval: 10s
threshold: 3

選項

這些選項以yaml文件格式提供,用戶可以直接進行修改,也可以添加自定義的模板段。

默認情況下,變量可以從環境變量中讀取,例如log.level:debug可以配置為:

export LOG_LEVEL=debug

比較重要的選項包括版本信息、log選項、hooks選項、存儲選項、認證選項、HTTP選項、通知選項、redis選項、健康監控選項、代理選項和驗證選項等。

下面分別介紹這些選項。

1.版本信息

version0.1

2.log選項

日志相關:

log:
level: debug
formatter: text
fields:
service: registry
environment: staging

參數說明:

  • level:字符串類型,標注輸出調試信息的級別,包括debug、info、warn、error。
  • fomatter:字符串類型,日志輸出的格式,包括text、json、logstash等。
  • fields:增加到日志輸出消息中的鍵值對,可以用於過濾日志。

3.hooks選項

配置當倉庫發生異常時,通過郵件發送日志時的參數:

hooks:
  - type: mail
levels:
  - panic
options:
smtp:
addr: smtp.sendhost.com:25
username: sendername
password: password
insecure: true
from: name@sendhost.com
to:
  - name@receivehost.com

4.存儲選項

storage選項將配置存儲的引擎,默認支持包括本地文件系統、Google雲存儲、AWS S3雲存儲和OpenStack Swift分布式存儲等,如下所示:

storage:
filesystem:
rootdirectory: /var/lib/registry
azure:
accountname: accountname
accountkey: base64encodedaccountkey
container: containername
gcs:
bucket: bucketname
keyfile: /path/to/keyfile
rootdirectory: /gcs/object/name/prefix
s3:
accesskey: awsaccesskey
secretkey: awssecretkey
region: us-west-1
regionendpoint: http://myobjects.local
bucket: bucketname
encrypt: true
keyid: mykeyid
secure: true
v4auth: true
chunksize: 5242880
multipartcopychunksize: 33554432
multipartcopymaxconcurrency: 100
multipartcopythresholdsize: 33554432
rootdirectory: /s3/object/name/prefix
swift:
username: username
password: password
authurl: https://storage.myprovider.com/auth/v1.0 or https://storage.
myprovider.com/v2.0 or https://storage.myprovider.com/v3/auth
tenant: tenantname
tenantid: tenantid
domain: domain name for Openstack Identity v3 API
domainid: domain id for Openstack Identity v3 API
insecureskipverify: true
region: fr
container: containername
rootdirectory: /swift/object/name/prefix
oss:
accesskeyid: accesskeyid
accesskeysecret: accesskeysecret
region: OSS region name
endpoint: optional endpoints
internal: optional internal endpoint
bucket: OSS bucket
encrypt: optional data encryption setting
secure: optional ssl setting
chunksize: optional size valye
rootdirectory: optional root directory
inmemory:
delete:
enabled: false
cache:
blobdescriptor: inmemory
maintenance:
uploadpurging:
enabled: true
age: 168h
interval: 24h
dryrun: false
redirect:
disable: false

比較重要的選項如下:

  • maintenance:配置維護相關的功能,包括對孤立舊文件的清理、開啟只讀模式等;
  • delete:是否允許刪除鏡像功能,默認關閉;
  • cache:開啟對鏡像層元數據的緩存功能,默認開啟;

5.認證選項

對認證類型的配置,如下所示:

auth:
silly:
realm: silly-realm
service: silly-service
token:
realm: token-realm
service: token-service
issuer: registry-token-issuer
rootcertbundle: /root/certs/bundle
htpasswd:
realm: basic-realm
path: /path/to/htpasswd

比較重要的選項如下:

  • silly:僅供測試使用,只要請求頭帶有認證域即可,不做內容檢查;
  • token:基於token的用戶認證,適用於生產環境,需要額外的token服務來支持;
  • htpasswd:基於Apache htpasswd密碼文件的權限檢查。

6.HTTP選項

跟HTTP服務相關的配置,如下所示:

http:
addr: localhost:5000
net: tcp
prefix: /my/nested/registry/
host: https://myregistryaddress.org:5000
secret: asecretforlocaldevelopment
relativeurls: false
tls:
certificate: /path/to/x509/public
key: /path/to/x509/private
clientcas:
  - /path/to/ca.pem
  - /path/to/another/ca.pem
letsencrypt:
cachefile: /path/to/cache-file
email: emailused@letsencrypt.com
debug:
addr: localhost:5001
headers:
X-Content-Type-Options: [nosniff]
http2:
disabled: false

其中的參數如下:

  • addr:必選,服務監聽地址;
  • secret:必選,跟安全相關的隨機字符串,用戶可以自己定義;
  • tls:證書相關的文件路徑信息;
  • http2:是否開啟http2支持,默認關閉。

7.通知選項

有事件發生時候的通知系統。

notifications:
endpoints:
  - name: alistener
disabled: false
url: https://my.listener.com/event
headers:
timeout: 500
threshold: 5
backoff: 1000

8.redis選項

Registry可以用Redis來緩存文件塊,這里可以配置相關選項:

redis:
addr: localhost:6379
password: asecret
db: 0
dialtimeout: 10ms
readtimeout: 10ms
writetimeout: 10ms
pool:
maxidle: 16
maxactive: 64
idletimeout: 300s

9.健康監控選項

跟健康監控相關,主要是對配置服務進行檢測判斷系統狀態,如下所示:

health:
storagedriver:
enabled: true
interval: 10s
threshold: 3
file:
  - file: /path/to/checked/file
interval: 10s
http:
  - uri: http://server.to.check/must/return/200
headers:
Authorization: [Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==]
statuscode: 200
timeout: 3s
interval: 10s
threshold: 3
tcp:
  - addr: redis-server.domain.com:6379
timeout: 3s
interval: 10s
threshold: 3

默認並未啟用。

10.代理選項

配置Registry作為一個pull代理,從遠端(目前僅支持官方倉庫)下拉Docker鏡像,如下所示:

proxy:
remoteurl: https://registry-1.docker.io
username: [username]
password: [password]

之后,用戶可以通過如下命令來配置Docker使用代理:

$ docker --registry-mirror=https://myrepo.com:5000 daemon

11.驗證選項

限定來自指定地址的客戶端才可以執行push操作:

validation:
enabled: true
manifests:
urls:
allow:
  - ^https?://([^/]+\.)*example\.com/
deny:
  - ^https?://www\.example\.com/

批量管理鏡像

有時候,本地鏡像很多,逐個打標記進行操作將十分浪費時間。這里將以批量上傳鏡像為例,如何利用腳本實現對鏡像的批量化處理。

1.批量上傳指定鏡像

可以使用下面的push_images.sh腳本,批量上傳本地的鏡像到注冊服務器中,默認是本地注冊服務器127.0.0.1:5000,用戶可以通過修改registry=127.0.0.1:5000這行來指定目標注冊服務器:

#!/bin/sh
# This script will upload the given local images to a registry server ($registry is the default value).
# See: https://github.com/yeasy/docker_practice/blob/master/_local/push_images.sh
# Usage:  push_images image1 [image2...]
# Author: yeasy@github
# Create: 2014-09-23
#The registry server address where you want push the images into registry=127.0.0.1:5000
### DO NOT MODIFY THE FOLLOWING PART, UNLESS YOU KNOW WHAT IT MEANS ###
echo_r () {
[ $# -ne 1 ] && return 0
echo -e "\033[31m$1\033[0m"
}
echo_g () {
[ $# -ne 1 ] && return 0
echo -e "\033[32m$1\033[0m"
}
echo_y () {
[ $# -ne 1 ] && return 0
echo -e "\033[33m$1\033[0m"
}
echo_b () {
[ $# -ne 1 ] && return 0
echo -e "\033[34m$1\033[0m"
}
usage() {
docker images
echo "Usage: $0 registry1:tag1 [registry2:tag2...]"
}
[ $# -lt 1 ] && usage && exit
echo_b "The registry server is $registry"
for image in "$@"
do
echo_b "Uploading $image..."
docker tag $image $registry/$image
docker push $registry/$image
docker rmi $registry/$image
echo_g "Done"
done

建議把腳本存放到本地的可執行路徑下,例如/usr/local/bin/下面。然后添加可執行權限,就可以使用該腳本了:

$ sudo chmod a+x /usr/local/bin/push_images.sh

例如,推送本地的ubuntu:latest和centos:centos7兩個鏡像到本地倉庫:

$ ./push_images.sh ubuntu:latest centos:centos7

上傳后,查看本地鏡像,會發現上傳中創建的臨時標簽也同時被清理了。

2.上傳本地所有鏡像

在push_images工具的基礎上,還可以進一步的創建push_all工具,來上傳本地所有鏡像:

#!/bin/sh
# This script will upload all local images to a registry server ($registry is the default value).
# This script requires the push_images, which can be found at https://github.com/yeasy/docker_practice/blob/master/_local/push_images.sh
# Usage:  push_all
# Author: yeasy@github
# Create: 2014-09-23
for image in `docker images|grep -v "REPOSITORY"|grep -v ""|awk '{print $1":"$2}'`
do
push_images.sh $image
done

另外,把它放在/usr/local/bin/下面,並添加可執行權限。這樣就可以通過push_all命令來同步本地所有鏡像到本地私有倉庫了。

可以試着修改腳本,實現批量化下載鏡像、刪除鏡像、更新鏡像標簽等更多的操作。

使用通知系統

Docker Registry v2還內置提供了Notification功能,提供了非常方便、快捷的集成接口,避免了v1中需要用戶自己實現的麻煩。

Notification功能其實就是Registry在有事件發生的時候,向用戶自己定義的地址發送webhook通知。目前的事件包括鏡像manifest的push、pull鏡像層的push、pull。這些動作會被序列化成webhook事件的payload,為集成服務提供事件詳情,並通過Registry v2的內置廣播系統發送到用戶定義的服務接口,Registry v2稱這些用戶服務接口為Endpoints。

Registry服務器的事件會通過HTTP協議發送到用戶定義的所有Endpoints上,而且每個Registry實例的每個Endpoint都有自己獨立的隊列,重試選項以及HTTP的目的地址。當一個動作發生時,會被轉換成對應的事件並放置到一個內存隊列中。鏡像服務器會依次處理隊列中的事件,並向用戶定義的Endpoint發送請求。事件發送處理是串行的,但是Registry服務器並不會保證其到達順序。

相關配置

Notification在Docker Registry中的相關配置如下:

notifications:
endpoints:
  -  name: cd-handler
disabled: false
url: http://cd-service-host/api/v1/cd-service
headers:
Authorization: [token ******************]
timeout: 1s
threshold: 5
backoff: 10s

上面的配置會在pull或者push發生時向http://cd-service-host/api/v1/cd-service發送事件,並在HTTP請求的header中傳入認證信息,可以是Basic、token、Bearer等模式,主要用於接收事件方進行身份認證。更新配置后,需要重啟Registry服務器,如果配置正確,會在日志中看到對應的提示信息,比如:

configuring endpoint listener (http://cd-service-host/api/v1/cd-service), timeout=1s,

headers=map[Authorization: [token ******]]

此時,用戶再通過docker客戶端去push或pull,或者查詢一些manifiest信息時,就會有相應的事件發送到定義的Endpoint上。

接下來看一下事件的格式和其中的主要屬性:

{
    "events": [
        {
            "id": "70f44894-c4b4-4be8-9691-d37db77074cd",
            "timestamp": "2016-06-05T01:57:04.654256149Z",
            "action": "push",
            "target": {
                "mediaType": "application/vnd.docker.distribution.manifest.v1+json",
                "size": 45765,
                "digest": "sha256:fd0af29ba2ae034449bffb18dd6db2ed90d798464cc43aa81e63770713edaea8",
                "length": 45765,
                "repository": "test-user/hello-world",
                "url": "http://registry-server/v2/test-user/hello-world/manifests/sha256:fd0af29ba2ae034449bffb18dd6db2ed90d798464cc43aa81e63770713edaea8"
            },
            "request": {
                "id": "9d3d837f-d7ed-4fa9-afb4-dda58687a6ce",
                "addr": "client-host:46504",
                "host": "registry-server",
                "method": "PUT",
                "useragent": "docker/1.9.1 go/go1.4.2 git-commit/a34a1d5 kernel/4.2.0-35-generic os/linux arch/amd64"
            },
            "actor": {
                "name": "test-user"
            },
            "source": {
                "addr": "8e14c2a190f2:5000",
                "instanceID": "c564003e-dd9b-4a9b-8a30-fe8564e97ba9"
            }
        }
    ]
}

每個事件的payload,都是一個定義好的JSON格式的數據。

通知系統的主要屬性主要包括action、target.mediaType、target.repository、target.url、request.method、request.useragent、actor.name等,參見表。

Notification的使用場景

理解了如何配置Docker Registry v2的Notification、Endpoint,以及接收到的Event的數據格式,我們就可以很方便地實現一些個性化的需求。

這里簡單列舉兩個場景,一個是如何統計鏡像的上傳、下載次數,方便了解鏡像的使用情況,另一個場景是對服務的持續部署,方便管理鏡像,參見圖。

1.鏡像上傳、下載計數

很常見的一個場景是根據鏡像下載次數,向用戶推薦使用最多的鏡像,或者統計鏡像更新的頻率,以便了解用戶對鏡像的維護程度。

用戶可以利用Notification的功能,定義自己的計數服務,並在Docker Registry上配置對應的Endpoint。在有pull、push動作發生時,對相應鏡像的下載或者上傳次數進行累加,達到計數效果。然后添加一個查詢接口,供用戶查看用戶鏡像的上傳、下載次數,或者提供排行榜等擴展服務。

2.實現應用的自動部署

在這個場景下,可以在新的鏡像push到Docker Registry服務器時候,自動創建或者更新對應的服務,這樣可以快速查看新鏡像的運行效果或者進行集成測試。用戶還可以根據事件中的相應屬性,比如用戶信息、鏡像名稱等,調用對應的服務部署接口進行自動化部署操作。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM