輕松搭建Docker Registry運行環境


原文鏈接

我們知道Docker官方提供了一個公有的registry叫做Docker Hub。但是企業內部可能有些鏡像還是不方便放到公網上去,所以docker也提供了registry鏡像來讓需要的人自己搭建私有倉庫。本文從零開始搭建Docker Registry的運行環境,並添加用戶界面和認證功能。

准備工作

我們需要先安裝virtualBoxvagrant。通過vagrant來驅動virtualBox搭建一個虛擬測試環境。首先在本地任意路徑新建一個空文件夾比如test,運行以下命令:

virtual box host

1
2
3
4
mkdir test
cd test
vagrant init minimum/ubuntu-trusty64-docker
vi Vagrantfile

 

里面應該有一句config.vm.box = "minimum/ubuntu-trusty64-docker",在它的下面添加如下幾行代碼,相當於給它分配兩台虛擬機,一台叫做registry,它的IP是192.168.33.18;另一台叫做client,它的IP是192.168.33.19。Registry配上界面會比較耗內存,所以我們給它1G內存,默認是512M。

Vagrantfile

1
2
3
4
5
6
7
8
9
10
11
12
config.vm.define "registry" do | host |
host.vm.hostname = "registry"
host.vm.network "private_network", ip: "192.168.33.18"
host.vm.provider "virtualbox" do |v|
v.memory = 1024
end
end

config.vm.define "client" do | host |
host.vm.hostname = "client"
host.vm.network "private_network", ip: "192.168.33.19"
end

 

這個vagrant鏡像已經在ubuntu的基礎上幫我們安裝了docker,用起來很方便。然后分別在兩個終端運行以下命令啟動並連接兩台虛擬機。

virtual box host terminal 1

1
2
vagrant up
vagrant ssh registry

 

virtual box host terminal 2

1
vagrant ssh client

搭建環境

啟動一個registry是很容易的:

registry

1
2
3
4
5
6
docker run -d \
-p 5000:5000 \
--name registry \
--restart=always \
-v /var/lib/registry:/var/lib/registry \
registry:2.3.0

 

這里指定了一個/var/lib/registry的卷,是為了把真實的鏡像數據儲存在主機上,而別在容器掛掉之后丟失數據。就算這樣,也還是不保險。要是主機掛了呢?Docker官方建議可以放到cephswift這樣的存儲里,或是亞馬遜S3微軟Azure谷歌GCS阿里雲OSS之類的雲商那里。Docker registry提供了配置文件,可以從容器里復制出來查看:

registry

1
2
docker cp registry:/etc/docker/registry/config.yml config.yml
cat config.yml

 

配置文件里有一個storage,按照這里寫的配置,然后執行以下命令重新掛載這個文件來啟動registry就可以了,有條件的話可以去試一試:

registry

1
2
3
4
5
6
7
8
docker rm -fv registry
docker run -d \
-p 5000:5000 \
--name registry \
--restart=always \
-v /var/lib/registry:/var/lib/registry \
-v `pwd`/config.yml:/etc/docker/registry/config.yml \
registry:2.3.0

 

Docker Registry配置完了,我們在client上傳一個鏡像試試:

client

1
2
3
docker pull busybox:1.24.1
docker tag busybox:1.24.1 192.168.33.18:5000/busybox:1.24.1
docker push 192.168.33.18:5000/busybox:1.24.1

 

結果push的時候就掛了。原來是我們沒有配置認證信息,所以這是一個“不安全”的registry。Docker要求在docker daemon的啟動參數里增加--insecure-registry,才能允許我們上傳鏡像:

client

1
2
3
sudo sh -c 'echo DOCKER_OPTS=\"--insecure-registry 192.168.33.18:5000\" >> /etc/default/docker'
sudo service docker restart
docker push 192.168.33.18:5000/busybox:1.24.1

 

這回就沒問題啦。同樣地在registry端也配置一下,然后把registry:2.3.0這個鏡像上傳:

registry

1
2
3
4
sudo sh -c 'echo DOCKER_OPTS=\"--insecure-registry 192.168.33.18:5000\" >> /etc/default/docker'
sudo service docker restart
docker tag registry:2.3.0 192.168.33.18:5000/library/registry:2.3.0
docker push 192.168.33.18:5000/library/registry:2.3.0

 

如果是沒有用戶的鏡像(通常是官方鏡像),打標簽和上傳都需要加一個library/。客戶端必須再配置一個參數--registry-mirror才能在我們自己的私有registry里下載鏡像:

client

1
2
3
4
sudo sed -i '$d' /etc/default/docker
sudo sh -c 'echo DOCKER_OPTS=\"--insecure-registry 192.168.33.18:5000 --registry-mirror http://192.168.33.18:5000\" >> /etc/default/docker'
sudo service docker restart
docker pull registry:2.3.0

 

應該有飛一般的感覺了吧。如果鏡像不在registry里,客戶端會自動去docker hub下載。但是每次打標簽再上傳豈不是很麻煩?所幸docker提供了一個proxy的功能。只要在config.yml里增加如下配置,重啟registry容器即可。這樣,客戶端pull的鏡像,也會自動同步到registry里去。

1
proxy:
  remoteurl: https://registry-1.docker.io

 

界面

Docker官方只提供了REST API,並沒有給我們一個界面。好在有熱心人士出馬,所以我們只需執行以下命令就可以給我們的私有庫提供一個UI了:

registry

1
2
3
4
5
6
docker run -d \
-p 8080:8080 \
--name web \
-e REGISTRY_HOST=172.17.0.1 \
-e REGISTRY_PORT=5000\
hyper/docker-registry-web

 

然后打開http://192.168.33.18:8080,應該就能看到如下界面:

上面是個簡易版,如果有更深入的需求,可以嘗試SUSE的Portus。除了界面以外,它還提供了更細粒度的權限控制、用戶認證等功能。

認證

我們剛剛配好的insecure registry是不支持認證的,如果要上產品環境,找CA申請一個證書吧。我們自己測試的話,可以用自簽名證書。我們准備使用IP代替域名,所以需要在證書里面包含我們的IP:

registry

1
2
3
4
5
sudo mkdir /certs
sudo sed -i '/^\[ v3_ca \]$/a subjectAltName = IP:192.168.33.18' /etc/ssl/openssl.cnf
sudo sh -c "openssl req \
-newkey rsa:4096 -nodes -sha256 -keyout /certs/domain.key \
-x509 -days 365 -out /certs/domain.crt"

 

隨便填點值完成這繁瑣的流程,就能看見certs里面多了兩個文件。現在可以用以下命令來啟動registry:

registry

1
2
3
4
5
6
7
8
9
10
docker rm -f registry
docker run -d \
-p 5000:5000 \
--name registry \
--restart=always \
-v /var/lib/registry:/var/lib/registry \
-v /certs:/certs \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
registry:2.3.0

 

客戶端現在就不需要--insecure-registry了,但是由於這是自簽名證書,客戶端還需要把證書文件復制過去:

client

1
2
3
4
sudo sed -i '$d' /etc/default/docker
sudo mkdir -p /etc/docker/certs.d/192.168.33.18:5000/
sudo scp vagrant@192.168.33.18:/certs/domain.crt /etc/docker/certs.d/192.168.33.18:5000/ca.crt
sudo service docker restart

 

注意vagrant的默認密碼也是vagrant。現在push就沒有問題了:

client

1
docker push 192.168.33.18:5000/busybox:1.24.1

 

提示鏡像已經存在,並沒有阻止我們提交。接下來我們加上認證。首先在registry生成用戶名hello和密碼world:

registry

1
2
sudo mkdir /auth
sudo sh -c "docker run --entrypoint htpasswd registry:2.3.0 -Bbn hello world > /auth/htpasswd"

 

還得指定認證方式和認證文件等參數,重新啟動registry容器:

registry

1
2
3
4
5
6
7
8
9
10
11
12
13
14
docker rm -f registry
docker run -d \
-p 5000:5000 \
--name registry \
--restart=always \
-v /var/lib/registry:/var/lib/registry \
-v /auth:/auth \
-v /certs:/certs \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
-e REGISTRY_AUTH=htpasswd \
-e REGISTRY_AUTH_HTPASSWD_REALM="Registry Realm" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
registry:2.3.0

 

這回客戶端用docker push 192.168.33.18:5000/busybox:1.24.1來嘗試push就會失敗啦。但是我們可以用用戶名hello和密碼world登錄啦:

client

1
docker login -u hello -p world -e email_whatever 192.168.33.18:5000

 

再次push,就沒有問題了:

client

1
docker push 192.168.33.18:5000/busybox:1.24.1


免責聲明!

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



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