1. 程式人生 > >docker配置及連線私有倉庫(registry2)

docker配置及連線私有倉庫(registry2)

本教程使用作業系統 CentOS7 .

docker安裝配置

如果本機還未安裝docker,可通過以下方式快捷安裝(為了最大程度保證一致性,此處指定版本):

yum -y install docker-1.12.6-28.git1398f24.el7.centos.x86_64
#啟動 docker
systemctl start docker

# 設定為開機啟動
systemctl enable docker

檢視docker版本,確認安裝結果:

[[email protected] ~]#docker -v
Docker version 1.12.6, build 1398f24/1.12.6

一.使用不需要鑑權的倉庫

1.不使用安全連結方式

無認證倉庫且不使用安全連結非常簡單,只需要在服務端拉取一個registry映象,然後用docker run執行,客戶端再進行簡單配置即可。

倉庫配置

拉取私有倉庫映象:

docker pull registry:2.5

啟動一個registry倉庫容器:

docker run -d --restart=always –privileged=true \
--name registry -p 5000:5000 \
-v /opt/data/registry:/var/lib/registry  \
docker.io/registry:2
  • –restart=always 此模式容器會跟 docker daemon會隨著docker服務的重啟而自動恢復
  • -v /opt/data/registry:/var/lib/registry 把本地磁碟掛載到容器磁碟/var/lib/registry(預設情況下倉庫存放映象於容器內的/var/lib/registry目錄下)
  • –name myregistry 定義容器名
  • -p 5000:5000 埠對映,本地埠5000對映到容器埠5000
  • –-privileged=true :配置了-v /opt/data/registry:/var/lib/registry ,如果沒有關閉安全模組selinux,容器將沒有許可權訪問本地目錄,設定此引數可以給容器加特權。如果沒有關閉selinux以及沒有加上此引數,上傳傳映象時可能會報許可權錯誤(OSError: [Errno 13] Permission denied: ‘/var/lib/registry/repositories/library’)或者(Received unexpected HTTP status: 500 Internal Server Error)錯誤

防火牆開放5000埠:

firewall-cmd --zone=public --add-port=2375/tcp --permanent
firewall-cmd --zone=public --add-port=2375/udp --permanent
firewall-cmd --reload

客戶端配置

(ps:客戶端可以是執行倉庫的同一臺機,以下全文皆是)
docker1.3.2版本開始,預設使用https連線,因為上面啟動時並沒有進行證書配置,在需要連線該私有倉庫的每個客戶端docker宿主機上都必須更改配置項,使客戶端使用HTTP連線請求倉庫。不同的系統配置方式可能存在差異,此處列舉常見的系統配置,其餘系統請自行搜尋嘗試。

CentOS&Ubuntu

步驟:

修改配置,CentOS配置檔案路徑: /etc/sysconfig/docker
# vim  /etc/sysconfig/docker
 增加啟動選項(在後面追加),。
# OPTIONS='--insecure-registry 10.20.26.52:5000'    #CentOS 7系統
# other_args='--insecure-registry 10.20.26.52:5000' #CentOS 6系統
 新增後重啟docker

Ubuntu下配置檔案路徑:/etc/init/docker.conf

Redhat7

Redhat7系統,需在檔案/etc/systemd/system/docker.service.d/docker.conf(沒有則新增),配置如下內容:

[Service]
ExecStart=
ExecStart=/usr/bin/docker daemon -H fd:// --insecure-registry=10.20.26.52:5000

儲存修改後,重啟

[[email protected] /]# systemctl daemon-reload
[[email protected] /]# service docker restart

boot2docker(使用windows dockertools 預設安裝的系統適用)

步驟:

使用 docker ssh 登陸到 boot2docker 虛擬機器
# docker ssh <name>
使用 命令修改配置檔案,
# sudo vi /var/lib/boot2docker/profile 
   在檔案最後增加一行:
# EXTRA_ARGS="--insecure-registry 10.20.26.52:5000"
退出該虛擬機器並重啟
# docker-machine restart <name>

驗證

配置完成後,使用docker login 驗證是否可以訪問(因為沒有配置使用者,提示使用者時任意輸入都可以登入成功):

[[email protected] registry]# docker login 127.0.0.1:5000
Username: 2
Password: 
Login Succeeded

如果沒有進行以上配置,客戶端登入或者連線將會有類似以下提示:

[[email protected] registry]# docker login 10.20.26.52:5000
Username: 2
Password: 
Error response from daemon: Get https://10.20.26.52:5000/v1/users/: http: server gave HTTP response to HTTPS client

此處需要說明的是,提示中雖然提示Get https://127.0.0.1:5005/v1/users/ ,似乎訪問了registry v1倉庫的連結地址。實際上,docker login 操作會依次訪問 v2和v1的地址,最後在命令列顯示的是最後失敗的日誌資訊。

為了讓大家清楚瞭解登入過程,以下貼出相關日誌資訊,供參考。
如果沒有進行配置時的日誌資訊(日誌來自系統CentOS7):

8月 02 14:21:18 server dockerd-current[32106]: time="2018-08-02T14:21:18.811035053+08:00" level=info msg="Error logging in to v2 endpoint, trying next endpoint: Get https://10.20.23.52:5000/v2/: http: server gave HTTP response to HTTPS client"
8月 02 14:21:18 server dockerd-current[32106]: time="2018-08-02T14:21:18.811306066+08:00" level=info msg="Error logging in to v1 endpoint, trying next endpoint: Get https://10.20.23.52:5000/v1/users/: http: server gave HTTP response to HTTPS client"
8月 02 14:21:18 server dockerd-current[32106]: time="2018-08-02T14:21:18.811320903+08:00" level=error msg="Handler for POST /v1.26/auth returned error: Get https://10.20.23.52:5000/v1/users/: http: server gave HTTP response to HTTPS client"

如果正常配置日誌資訊(日誌來自系統 boot2docker):

time="2018-08-02T09:38:43.975291248Z" level=debug msg="Calling GET /_ping"
time="2018-08-02T09:38:43.975756760Z" level=debug msg="Calling GET /v1.28/info"
time="2018-08-02T09:38:45.603555104Z" level=debug msg="Calling POST /v1.28/auth"
time="2018-08-02T09:38:45.603621065Z" level=debug msg="form data: {\"password\":\"*****\",\"serveraddress\":\"10.20.26.52:5000\",\"username\":\"2\"}"
time="2018-08-02T09:38:45.603676682Z" level=debug msg="attempting v2 login to registry endpoint https://10.20.26.52:5000/v2/"
time="2018-08-02T09:38:45.640464885Z" level=info msg="Error logging in to v2 endpoint, trying next endpoint: Get https://10.20.26.52:5000/v2/: http: server gave HTTP response to HTTPS client"
time="2018-08-02T09:38:45.640546495Z" level=debug msg="attempting v2 login to registry endpoint http://10.20.26.52:5000/v2/"

2.配置安全連線方式

docker1.3.2版本開始,使用registry時,預設使用TLS保證資料安全傳輸。下面將演示如何安裝一個使用安全連結的registry。

倉庫配置

第一步:生成證書

證書可以去認證機構購買簽名證書,此處我們使用openssl生成證書。
一般情況下,證書只支援域名訪問,要使其支援IP地址訪問,需要修改配置檔案openssl配置檔案,再進行證書生成。
在CentOS7系統中,檔案儲存位置為/etc/pki/tls/openssl.cnf。在其中的[ v3_ca]部分,新增subjectAltName選項(填入操作機實際IP):

[ v3_ca ]
subjectAltName = IP:10.20.26.52

修改配置後,生成自簽名的證書:

mkdir -p /opt/docker/registry/certs
 
openssl req -x509 -days 3650 -nodes -newkey rsa:2048 \
-keyout /opt/docker/registry/certs/domain.key \
-out /opt/docker/registry/certs/domain.crt
...
Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:10.20.26.52:5000
Email Address []:

生成時,可以所有操作直接回車,不填寫任何資訊生成。或在Common Name 裡填入倉庫將使用IP和埠”10.20.26.52:5000”。

第二步:啟動容器

此時的啟動引數和上面有所不同,需要指定容器使用證書相關路徑資訊:

mkdir /opt/docker/registry/certs/data
docker run -d \
--name repo  --restart=always \
-v /opt/docker/registry/data:/var/lib/registry \
-u root \
-p 5000:5000 \
-v /opt/docker/registry/certs:/certs \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
registry:2.5

客戶端配置

此時客戶端可以採取兩種方式連線客戶端,其一是跟上節中一樣,配置使用不安全的HTTP連線;其二則是需要將上面第一步中生成的證書,拷貝到dokcer客戶端宿主機上。

在沒有進行任何配置之前,使用docker login ,將返回類似錯誤:

[[email protected] registry]# docker login 10.20.26.52:5000
Username: 33
Password: 
Error response from daemon: Get https://10.20.26.52:5000/v1/users/: http: server gave HTTP response to HTTPS client

現在我們在客戶端中使用證書,將上面第一步中生成的證書domain.crt拷貝到docker客戶端宿主機對應資料夾內。(docker使用的證書預設儲存在 /etc/docker/cert.d目錄中,按照域名儲存匹配)
如果是本機測試,可以使用cp命令 ,如果是不同機器,可以使用scp命令。

cp /opt/docker/registry/certs/domain.crt /etc/docker/certs.d/10.20.26.52:5000/domain.crt

如果是不同機器,可以使用scp命令

sudo scp -r [email protected]:/opt/registry/certs/registry.crt /etc/docker/certs.d/xxx.com:5000/domain.crt

此時,我們就可以使用HTTPS的方式(預設方式)來使用倉庫了,使用docker login驗證 (再次提示,由於此時沒有配置使用者,正確反饋為輸入任何字元都可以登入成功,如果返回錯誤資訊應該是配置過程出錯,請確保目錄及配置字元都完全正確)

[[email protected] registry]docker login 10.20.26.230:5000
Username: 233
Password:
Login Succeeded

這裡需要注意,此時用上節不使用安全連結的方式,客戶端進行同樣配置(–insecure-registry)後是客戶端仍然可以對倉庫進行任何操作的。此節只是在倉庫端加了證書支援客戶端使用安全連結,但並不強制客戶端一定要使用安全連結(至少在目前版本是這樣的)。所以這裡這個只是新增證書的倉庫,並不能作為許可權控制,防止他人非法使用倉庫。如果需要保證安全,必須在這個基礎上加上其他安全手段。

二、需要許可權認證的倉庫

上面我們安裝的都是一個沒有許可權校驗的私庫,但很多時候基於安全考慮,都需要給倉庫配置許可權,下面將講解如何配置帶有許可權控制的倉庫。
Registry支援三種認證方式(只能同時使用一種):silly、token和htpasswd。
此處我們選擇配置使用 htpasswd + TLS 方式

1. htpasswd + TLS

倉庫配置

第一步 生成證書

  • 參考上節中“配置安全連線方式”小節中操作。

第二步 生成密碼憑證

mkdir /opt/docker/registry/certs/data
docker run --entrypoint htpasswd registry:2.5 -Bbn admin admin123 >> /opt/docker/registry/auth/htpasswd

第三步 啟動容器
此時對比之前,需要指定鑑權方式的配置並在啟動的時候掛載密碼目錄到容器內auth目錄:

docker run -d --privileged=true \
-u root -p 5000:5000 \
--name repo --restart=always \
-v /opt/docker/registry/data:/var/lib/registry \
-v /opt/docker/registry/auth/:/auth/ \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm"  \
-e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" \
-v /opt/docker/registry/certs:/certs \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
registry:2.5
  • 引數解析
--restart=always 此模式容器會跟 docker daemon會隨著docker服務的重啟而自動恢復
-v /opt/registry/data:/var/lib/registry 
把本地磁碟掛載到容器磁碟/var/lib/registry
(預設情況下倉庫存放映象於容器內的/var/lib/registry目錄下)
-v /opt/registry/auth/:/auth/ 
將密碼資料夾掛載到容器/auth資料夾
--name registry 2
定義容器名,方便啟動
-p 5000:5000
 埠對映,<本地埠>:<容器埠>,本地埠5000對映到容器埠5000
–-privileged=true 
此引數容器新增特權,前面將本地目錄掛載到容器,
如果本地沒有關閉安全模組selinux,容器將沒有許可權訪問本地目錄,
如果沒有關閉selinux以及沒有加上此引數,上傳傳映象時可能會報許可權錯誤
OSError: [Errno 13] Permission denied: ‘/var/lib/registry/repositories/library’
或者
Received unexpected HTTP status: 500 Internal Server Error
-e "REGISTRY_AUTH=htpasswd" 
配置認證方式為 htpasswd
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" 
鑑權範圍
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd 
配置htpasswd認證使用的密碼檔案路徑
-v /opt/registry/certs:/certs
掛載目錄
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry.crt
指定證書crt地址
-e REGISTRY_HTTP_TLS_KEY=/certs/registry.key
指定證書key地址

到這裡,倉庫服務配置完成。

客戶端配置

第一步 獲取安全證書

將上面第一步中生成的證書domain.crt拷貝到docker客戶端宿主機對應資料夾內。(docker使用的證書預設儲存在 /etc/docker/cert.d目錄中,按照域名儲存匹配)
如果是本機測試,可以使用cp命令 ,如果是不同機器,可以使用scp命令。

cp /opt/docker/registry/certs/domain.crt /etc/docker/certs.d/10.20.26.52:5000/domain.crt

如果是不同機器,可以使用scp命令

sudo scp -r [email protected]:/opt/registry/certs/registry.crt /etc/docker/certs.d/xxx.com:5000/domain.crt

第二步 使用指定賬號登入

此時,我們就可以使用HTTPS的方式(預設方式)來使用倉庫。現在我們進行 docker login驗證配置,因為在倉庫配置的時候,指定了鑑權方式並生成了賬戶密碼。這時候進行 docker login 時,使用非配置的使用者將無法登入(返回 401 Unauthorized),只能通過上述配置中 的admin使用者和正確的密碼進行登入。

[[email protected] registry]# docker login 10.20.26.52:5000
Username (admin): 3
Password:
Error response from daemon: login attempt to https://10.20.26.230:5000/v2/ failed with status: 401 Unauthorized
[[email protected] registry]# docker login 10.20.26.52:5000
Username (admin): admin
Password:
Login Succeeded

需要注意的是:

此時仍然可以通過配置(–insecure-registry)不使用安全連結進行登入(當然這時需要使用配置的使用者名稱和密碼),不使用安全連結時,使用者名稱和密碼將使用明文傳輸,存在嚴重安全風險。日常使用應該使用安全連結方式。

異常情況及排查

異常一:如果客戶端沒有配置證書,將出現以下錯誤:

[[email protected] registry]# docker login 10.20.26.52:5000
Username (admin): admin
Password: 
Error response from daemon: Get https://10.20.26.52:5000/v1/users/: x509: certificate signed by unknown authority


異常二:如果證書不匹配或者使用ip證書沒有按上述操作配置openssl.cnf,將出現以下錯誤資訊:

[[email protected] registry]#docker login 10.20.26.52:5000
Username (admin): admin
Password:
Error response from daemon: Get https://10.20.26.52:5000/v1/users/: x509: certificate signed by unknown authority

[[email protected] registry]#docker login 10.20.26.230:5000
Username (admin): admin
Password:
Error response from daemon: Get https://10.20.26.230:5000/v1/users/: x509: cannot validate certificate for 10.20.26.230 because it doesn't contain any IP SANs

異常三:
容器啟動失敗會導致無法登陸,表現為 connection refused等。

[[email protected] registry]# docker login 10.20.26.52:5006
Username: admin
Password: 
Error response from daemon: Get https://10.20.26.52:5006/v1/users/: dial tcp 10.20.26.52:5006: getsockopt: connection refused

如果出現異常情況,首先排除容器是否正常啟動,使用docker ps,檢視容器的情況:

[[email protected] registry]# docker ps
CONTAINER ID        IMAGE                    COMMAND                  CREATED             STATUS                                  PORTS                    NAMES
40a6b1603c1d        docker.io/registry:2.5   "/entrypoint.sh /e..."   7 seconds ago       Restarting (2) Less than a second ago                            registry2
3b29b82a169a        registry:2.5             "/entrypoint.sh /e..."   22 minutes ago      Up 22 minutes                           0.0.0.0:5000->5000/tcp   repo

如果發現status 為 非正常情況(Restarting … ),則容器啟動異常。
導致容器異常的原因有很多,比如 容器配置項錯誤(檢查輸入),掛載檔案不存在(檢查檔案)等,請先逐項排查每個配置項及關聯配置檔案是否正確(存在且格式正確)。也可以通過 檢視日誌的方式確定問題範圍

docker logs <容器名>

私有庫的使用

私有庫搭建好了,我們可以進行一些操作體驗一下。

從預設庫獲取hello-world映象

docker pull hello-world

在客戶機上tag需要上傳的映象

[[email protected] ~]# docker tag hello-world 10.20.26.52:5000/hello-world

提交(push)映象

[[email protected] ~]# docker push 10.20.26.52:5000/hello-world

docker push 10.20.26.52:5000/hello-world
The push refers to a repository [10.20.26.64:5000/hello-world]
45761469c965: Pushed 
latest: digest: sha256:f3b3b28a45160805bb16542c9531888519430e9e6d6ffc09d72261b0d26ff74f size: 524

刪除本地映象

[[email protected] ~]# docker rmi 10.20.26.52:5000/hello-world

Untagged: 10.20.26.52:5000/hello-world:latest
Untagged: 10.20.26.52:5000/[email protected]:f3b3b28a45160805bb16542c9531888519430e9e6d6ffc09d72261b0d26ff74f
Deleted: sha256:1815c82652c03bfd8644afda26fb184f2ed891d921b20a0703b46768f9755c57
Deleted: sha256:45761469c965421a92a69cc50e92c01e0cfa94fe026cdd1233445ea00e96289a

從私有倉庫獲取映象

[[email protected] ~]# docker pull 10.20.26.52:5000/hello-world
Using default tag: latest
Trying to pull repository 10.20.26.64:5000/hello-world ... 
sha256:f3b3b28a45160805bb16542c9531888519430e9e6d6ffc09d72261b0d26ff74f: Pulling from 10.20.26.64:5000/hello-world
b04784fba78d: Pull complete 
Digest: sha256:f3b3b28a45160805bb16542c9531888519430e9e6d6ffc09d72261b0d26ff74f
Status: Downloaded newer image for 10.20.26.64:5000/hello-world:latest

查詢倉庫映象

  • 在服務端使用命令檢視映象物理檔案
tree /opt/docker/registry/data

訪問http介面:

  • 查詢映象列表: http://registry_ip:port/v2/_catalog
  • 查詢映象詳情: http://registry_ip:port/v2/image_name/tags/list

如:

curl http://10.20.26.52:5000/v2/_catalog 
{"repositories":["hello-world"]}

curl http://10.20.26.52:5000/v2/image_name/tags/list
{"name":"hello-world","tags":["latest"]}

參考文件