我們知道Docker官方提供了一個公有的registry叫做Docker Hub。但是企業內部可能有些鏡像還是不方便放到公網上去,所以docker也提供了registry鏡像來讓需要的人自己搭建私有倉庫。本文從零開始搭建Docker Registry的運行環境,並添加用戶界面和認證功能。
准備工作
我們需要先安裝virtualBox和vagrant。通過vagrant來驅動virtualBox搭建一個虛擬測試環境。首先在本地任意路徑新建一個空文件夾比如test
,運行以下命令:
virtual box host
1 |
mkdir test |
里面應該有一句config.vm.box = "minimum/ubuntu-trusty64-docker"
,在它的下面添加如下幾行代碼,相當於給它分配兩台虛擬機,一台叫做registry,它的IP是192.168.33.18;另一台叫做client,它的IP是192.168.33.19。Registry配上界面會比較耗內存,所以我們給它1G內存,默認是512M。
Vagrantfile
1 |
config.vm.define "registry" do | host | |
這個vagrant鏡像已經在ubuntu的基礎上幫我們安裝了docker,用起來很方便。然后分別在兩個終端運行以下命令啟動並連接兩台虛擬機。
virtual box host terminal 1
1 |
vagrant up |
virtual box host terminal 2
1 |
vagrant ssh client |
搭建環境
啟動一個registry是很容易的:
registry
1 |
docker run -d \ |
這里指定了一個/var/lib/registry
的卷,是為了把真實的鏡像數據儲存在主機上,而別在容器掛掉之后丟失數據。就算這樣,也還是不保險。要是主機掛了呢?Docker官方建議可以放到ceph、swift這樣的存儲里,或是亞馬遜S3、微軟Azure、谷歌GCS、阿里雲OSS之類的雲商那里。Docker registry提供了配置文件,可以從容器里復制出來查看:
registry
1 |
docker cp registry:/etc/docker/registry/config.yml config.yml |
配置文件里有一個storage
,按照這里寫的配置,然后執行以下命令重新掛載這個文件來啟動registry就可以了,有條件的話可以去試一試:
registry
1 |
docker rm -fv registry |
Docker Registry配置完了,我們在client上傳一個鏡像試試:
client
1 |
docker pull busybox:1.24.1 |
結果push的時候就掛了。原來是我們沒有配置認證信息,所以這是一個“不安全”的registry。Docker要求在docker daemon的啟動參數里增加--insecure-registry
,才能允許我們上傳鏡像:
client
1 |
sudo sh -c 'echo DOCKER_OPTS=\"--insecure-registry 192.168.33.18:5000\" >> /etc/default/docker' |
這回就沒問題啦。同樣地在registry端也配置一下,然后把registry:2.3.0這個鏡像上傳:
registry
1 |
sudo sh -c 'echo DOCKER_OPTS=\"--insecure-registry 192.168.33.18:5000\" >> /etc/default/docker' |
如果是沒有用戶的鏡像(通常是官方鏡像),打標簽和上傳都需要加一個library/
。客戶端必須再配置一個參數--registry-mirror
才能在我們自己的私有registry里下載鏡像:
client
1 |
sudo sed -i '$d' /etc/default/docker |
應該有飛一般的感覺了吧。如果鏡像不在registry里,客戶端會自動去docker hub下載。但是每次打標簽再上傳豈不是很麻煩?所幸docker提供了一個proxy的功能。只要在config.yml
里增加如下配置,重啟registry容器即可。這樣,客戶端pull的鏡像,也會自動同步到registry里去。
1 |
proxy:
remoteurl: https://registry-1.docker.io |
界面
Docker官方只提供了REST API,並沒有給我們一個界面。好在有熱心人士出馬,所以我們只需執行以下命令就可以給我們的私有庫提供一個UI了:
registry
1 |
docker run -d \ |
然后打開http://192.168.33.18:8080
,應該就能看到如下界面:
上面是個簡易版,如果有更深入的需求,可以嘗試SUSE的Portus。除了界面以外,它還提供了更細粒度的權限控制、用戶認證等功能。
認證
我們剛剛配好的insecure registry是不支持認證的,如果要上產品環境,找CA申請一個證書吧。我們自己測試的話,可以用自簽名證書。我們准備使用IP代替域名,所以需要在證書里面包含我們的IP:
registry
1 |
sudo mkdir /certs |
隨便填點值完成這繁瑣的流程,就能看見certs里面多了兩個文件。現在可以用以下命令來啟動registry:
registry
1 |
docker rm -f registry |
客戶端現在就不需要--insecure-registry
了,但是由於這是自簽名證書,客戶端還需要把證書文件復制過去:
client
1 |
sudo sed -i '$d' /etc/default/docker |
注意vagrant的默認密碼也是vagrant。現在push就沒有問題了:
client
1 |
docker push 192.168.33.18:5000/busybox:1.24.1 |
提示鏡像已經存在,並沒有阻止我們提交。接下來我們加上認證。首先在registry生成用戶名hello和密碼world:
registry
1 |
sudo mkdir /auth |
還得指定認證方式和認證文件等參數,重新啟動registry容器:
registry
1 |
docker rm -f registry |
這回客戶端用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 |