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"]}