楔子
我們一般測試開發(fā)的時(shí)候,都習(xí)慣于直接從公共鏡像倉庫hub.docker.com拉取所需鏡像,但是實(shí)際生產(chǎn)環(huán)境中可能涉及自建鏡像和網(wǎng)絡(luò)等各方面的原因,這個(gè)時(shí)候或許預(yù)先搭建自己的鏡像倉庫可能會(huì)更方便些,如下就來講講基于證書訪問的docker registry的搭建流程。
創(chuàng)建自簽名證書
首先,不管是Registry客戶端還是服務(wù)器端都默認(rèn)已經(jīng)安裝docker、openssl等工具。另外這兒Registry Server和客戶端是一臺(tái)主機(jī)且IP是10.0.2.15,域名vienfu.dockerhub.com,因此要做域名的解析配置:
echo "10.0.2.15 vienfu.dockerhub.com" >> /etc/hosts
然后開始創(chuàng)建自簽名證書:
mkdir -p /root/certs.d
cd /root/certs.d
openssl req -newkey rsa:2048 -nodes -sha256 -keyout ./domain.key -x509 -days 365 -out ./domain.crt # 根據(jù)提示依次填入所需信心,注意Common Name處要填入之前被解析的域名vienfu.dockerhub.com
# 客戶端證書拷貝
mkdir -p /etc/docker/certd.d/vienfu.dockerhub.com:5000
cp /root/certs.d/domain.crt /etc/docker/certd.d/vienfu.dockerhub.com:5000/ca.crt
# 如果后續(xù)欲通過curl證書訪問registry接口,還需要做如下操作:
cat /root/certs.d/domain.crt >> /etc/ssl/certs/ca-certificates.crt
以上所有操作完成后,重啟docker:systemctl restart docker
創(chuàng)建Registry容器
首先,可以預(yù)先拉取registry鏡像:
docker pull registry:2
如果考慮到持久化和鏡像的刪除問題,可以預(yù)先做如下操作:
mkdir -p /root/docker_image_mgr/registry
cat << EOF >> /root/docker_image_mgr/config.yml
version: 0.1
log:
fields:
service: registry
storage:
delete:
enabled: true # 其中delete.enabled是為鏡像刪除設(shè)置的字段
cache:
blobdescriptor: inmemory
filesystem:
rootdirectory: /var/lib/registry
http:
addr: :5000
headers:
X-Content-Type-Options: [nosniff]
health:
storagedriver:
enabled: true
interval: 10s
threshold: 3
EOF
啟動(dòng)registry容器:
docker run -d -p 5000:5000 --name my-registry -v /root/docker_image_mgr/registry:/var/lib/registry -v /root/docker_image_mgr/config.yml:/etc/docker/config.yml -v /root/certs.d:/root -e REGISTRY_HTTP_TLS_CERTIFICATE=/root/domain.crt -e REGISTRY_HTTP_TLS_KEY=/root/domain.key registry:2
# 啟動(dòng)之后,docker ps看一下啟動(dòng)狀態(tài)
root@kolla:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ed96182fa77d registry:2 "/entrypoint.sh /etc/" 15 hours ago Up 15 hours 0.0.0.0:5000->5000/tcp my-registry
如此Registry Server啟動(dòng)完成,下面不妨測試一下可否向該Registry Server上傳鏡像。
docker tag hello-world vienfu.dockerhub.com:5000/hello-world:test
docker push vienfu.dockerhub.com:5000/hello-world:test
簡單通過curl命令來查看鏡像是否上傳:
root@kolla:~#curl -X GET https://vienfu.dockerhub.com:5000/v2/_catalog
{"repositories":["hello-world"]}
如此我們看到鏡像也的確上傳成功了。
倉庫加鑒權(quán)
出于安全考慮,一般在認(rèn)證之后還需要做一個(gè)鑒權(quán)來控制用戶的訪問權(quán)限,這兒僅介紹最基本的鑒權(quán)方式:用戶名和密碼訪問模式。
首先創(chuàng)建一個(gè)用戶及訪問的密碼,這兒假設(shè)用戶名和密碼分別是vienfu、Fch19880810:
mkdir -p /root/auth
docker run --entrypoint htpasswd registry:2 -Bbn vienfu Fch19880810 > /root/auth/htpasswd
然后把之前起的容器停掉并且刪除:
docker stop my-registry
docker rm my-registry
最后啟動(dòng)一個(gè)帶鑒權(quán)的registry容器:
docker run -d -p 5000:5000 --name my-registry \
-v /root/auth:/auth \
-v /root/docker_image_mgr/registry:/var/lib/registry \
-v /root/docker_image_mgr/config.yml:/etc/docker/registry/config.yml \
-v /root/certs.d:/root \
-e "REGISTRY_AUTH=htpasswd" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/root/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/root/domain.key \
registry:2
那也不妨測試一下,實(shí)際上我們不難發(fā)現(xiàn),這個(gè)時(shí)候如果我們直接docker push來上傳鏡像會(huì)失敗,這是因?yàn)樵O(shè)置了鑒權(quán)訪問的參數(shù)需要先做如下操作:
docker login vienfu.dockerhub.com:5000 # 根據(jù)提示輸入之前設(shè)置的用戶名和密碼
如此我們?cè)偻ㄟ^docker push上傳鏡像就ok啦,最后也通過curl命令來查看一下吧:
root@kolla:~# curl -u vienfu:Fch19880810 -X GET https://vienfu.dockerhub.com:5000/v2/_catalog
{"repositories":["hello-world"]}
好啦,自此私有鏡像倉庫的搭建工作算是完成了。
結(jié)語
以上完整講述了私有鏡像倉庫的搭建流程,但實(shí)際生產(chǎn)環(huán)境中可能會(huì)涉及高可用、異地?cái)?shù)據(jù)同步及一致性等問題,這些問題都需要我們?nèi)ヒ灰唤鉀Q(這兒暫不做這方面的展開);另外,企業(yè)級(jí)應(yīng)用還可以考慮使用Harbor,它會(huì)提供一整套的解決方案包括用戶管理、操作界面、鏡像簽名、漏掃、高可用等一系列功能,剛興趣的同學(xué)可參照我的另兩篇博客:基于NFS后端存儲(chǔ)搭建Harbor和基于CEPH后端存儲(chǔ)搭建Harbor。