一.什麼是Docker 倉庫?
倉庫是集中存放鏡像檔案的場所。有時候會把倉庫和倉庫注冊伺服器(Registry)混為一談,并不嚴格區分。實際上,倉庫注冊伺服器上往往存放着多個倉庫,每個倉庫中又包含了多個鏡像,每個鏡像有不同的标簽(tag)。(之間的關系是:倉庫注冊伺服器 —> 各種各樣的倉庫 —> 每個倉庫中有大量的鏡像)
倉庫分為公開倉庫(Public)和私有倉庫(Private)兩種形式。最大的公開倉庫是 Docker Hub,存放了數量龐大的鏡像供使用者下載下傳。 國内的公開倉庫包括 Docker Pool 等,可以提供大陸使用者更穩定快速的通路。私有倉庫和共有倉庫類似,不同之處在于前者不會在搜尋結果中顯示,也沒有通路它的權限。隻有使用者設定為合作者才能通路私有倉庫。
使用者也可以在本地網絡内建立一個私有倉庫。當使用者建立了自己的鏡像之後就可以使用 push 指令将它上傳到公有或者私有倉庫,這樣下次在另外一台機器上使用這個鏡像時候,隻需要從倉庫上 pull 下來就可以了。
二、 私有倉庫registry的優勢
有時候使用Docker Hub這樣的公共倉庫可能不友善,這種情況下使用者可以使用registry建立一個本地倉庫供私人使用。
使用私有倉庫有許多優點:
1)節省網絡帶寬,針對于每個鏡像不用每個人都去中央倉庫上面去下載下傳,隻需要從私有倉庫中下載下傳即可;
2)提供鏡像資源利用,針對于公司内部使用的鏡像,推送到本地的私有倉庫中,以供公司内部相關人員使用。
目前Docker Registry已經更新到了v2,最新版的Docker已不再支援v1。Registry v2使用Go語言編寫,在性能和安全性上做了很多優化,重新設計了鏡像的存儲格式。如果需要安裝registry v2,隻需下載下傳registry:2.2即可。
Docker官方提供的工具docker-registry可以用于建構私有的鏡像倉庫。
三.建立私有倉庫
1.Docker 官方已經把倉庫封裝為鏡像,直接通過啟動容器就可以部署完成倉庫
cd /opt/registry/
ls
docker
docker load -i registry.tar ##官方将建立私有倉庫封裝成了鏡像
docker images registry (注意标簽TAG)
REPOSITORY TAG IMAGE ID CREATED SIZE
registry 2.3.1 83139345d017 3 years ago 166MB
docker run -d --name registry -p 5000:5000 -v /opt/registry:/var/lib/registry registry:2.3.1 ##就相當于安裝了一個空的倉庫,運作上述指令後,會從DockerHub上拉取registry鏡像并在本地啟動Registry服務,并監聽5000端口。上面的操作已經将鏡像導入了,會直接使用上面的鏡像。基于容器的運作方式
docker load -i registry ###加載一個已經存在的鏡像
docker tag registry localhost:5000/registry ##修改加載的鏡像的标簽,将原有的鏡像标記為本地的一個版本
docker push localhost:5000/registry ##将修改好的鏡像上傳到私有的倉庫裡
docker rmi localhost:5000/registry ###在這之前先執行如下指令移除本地未使用的鏡像,保證拉取的鏡像是從本地倉庫的,而不是從緩存中擷取的。
docker pull localhost:5000/registry ##拉取鏡像
docker images registry ##檢視拉取的自己的私有的倉庫中的鏡像資訊
REPOSITORY TAG IMAGE ID CREATED SIZE
registry latest 0a3eb3fde7fd 4 years ago 140MB
然後就可以利用這個自己私有倉庫拉取的鏡像,建立需要的容器。
=====================================================================================
(1)使用标簽的目的是:
docker将檔案等資訊的變動抽象為一次次的commit,每一次commit以後可能走向不同的分支,當我們完成dockerfile的建構後,會生成一串無規則的字元串代表此次生成的ID。此時,tag的作用就是為他建立一個友好的NAME,友善我們對鏡像庫的管理。
docker tag image image:v1
,系統又幫我們加上了latest,也就是說,當我們不指定tag的時候,系統會自動幫我們補上latest的tag,然後去比對,如果命中,就用對應的容器ID去建立新的tag。
(2)latest
這個latest其實在使用中不是最新的意思,而是預設值(defalut)的意思。也就是說,如果在tag為可選的指令中,我們沒有寫上tag,如
docker pull image:v1;docker pull image
,前者有确定的tag,而後者沒有,這時系統會自動給後者添加一個:latest的标簽,然後去比對。這時如果latest對應的鏡像不存在就會報錯!
(3)docker的tag(标簽)的文法:
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
docker run image ##預設使用的是标簽為latest的鏡像
docker run image:v1 ##使用的是指定的鏡像
(4)docker鏡像的版本控制
如果需要更新某個docker鏡像,我們可以這樣做。
- 1.給每個新生成的鏡像都打上相應版本的tag。此時可能存在image:latest、image:v1、image:v2等。
- 2.我們要從v1更新到v2,首先我們将導入的v2鏡像強制重命名為image:latest,指令為 docker tag -f image:v2 image:latest
- 3.docker stop之前正在運作的容器
- 4.啟用docker run image,此時image的等價鏡像image:latest就是最新的V2鏡像。
=====================================================================================
2.給私有庫添加證書 原來的庫任何人都可以通路,這樣不安全,接下來我們要增加庫的安全性
(1)建立服務端key以及證書
cd /opt/docker/
mkdir -p certs
openssl req \ ##生成證書請求
> -newkey rsa:4096 -nodes -sha256 -keyout certs/westos.org.key \
##“-new”表示新生成一個新的證書請求檔案,"-key"指定私鑰檔案。"-keyout"選項可以指定私鑰儲存位置,"-nodes"選項禁止加密私鑰檔案,"-newkey"選項可以直接指定私鑰的算法和長度,是以它主要用在openssl req自動建立私鑰時。它的使用格式為"-newkey arg",其中arg的格式為"rsa:numbits",rsa表示建立rsa私鑰,numbits表示私鑰的長度,如果不給定長度(即"-newkey rsa")則預設從配置檔案中讀取長度值。其實不止支援rsa私鑰,隻不過現在基本都是用rsa私鑰,是以預設就使用rsa。
> -x509 -days 365 -out certs/westos.org.crt
##"-out"指定輸出檔案,此處輸出檔案即為證書請求檔案。使用openssl req自簽署證書時,需要使用"-x509"選項,由于是簽署證書請求檔案,是以可以指定"-days"指定所頒發的證書有效期

(2)添加本地解析
vim /etc/hosts
172.25.254.1 westos.org
(3)建立倉庫
docker rm -f registry ##之前基于容器安裝的倉庫,不支援證書,是以需要重新的配置。
netstat -antlp | grep :443
docker run -d \
> --restart=always \
> --name registry \
> -v "$(pwd)"/certs:/certs \
> -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \ ## -e 設定相應的環境變量
> -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/westos.org.crt \ ## -e 設定相應的環境變量 添加了相應的證書的環境變量的設定
> -e REGISTRY_HTTP_TLS_KEY=/certs/westos.org.key \ ## -e 設定相應的環境變量 添加了相應的私鑰的環境變量的設定
> -p 443:443 \
> -v /opt/registry:/var/lib/registry registry:2.3.1
e97292700fe680c6124c6b3491fc8101b2658adfce7867050f488b519e71375d
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d91ba651fb74 registry:2.3.1 "/bin/registry /etc/…" 10 seconds ago Up 8 seconds 0.0.0.0:443->443/tcp, 5000/tcp registry
(4)建立證書存放目錄,并複制證書
cd /etc/docker/
mkdir certs.d
cd certs.d/
mkdir westos.org
cd westos.org/
ls
ca.crt
cp /opt/docker/certs/westos.org.crt ca.crt
(5)導入一個鏡像并上傳到私有倉庫
docker load -i game2048.tar
docker tag game2048:latest westos.org/game2048
docker push westos.org/game2048
3.建立虛拟機然後試着将剛才push的虛拟機再拉取下來
(1)建立一個虛拟機 在 server1 上安裝docker
systemctl start docker
vim /etc/hosts
172.25.254.1 westos.org
(2)建立同樣的證書目錄,并将服務端證書傳到此位置
cd /etc/docker
mkdir certs.d
cd certs.d/
mkdir westos.org
cd westos.org/
pwd
/etc/docker/certs.d/westos.org
ls
ca.crt ##将伺服器上的證書傳到server1上
(4)下拉上傳的鏡像
docker pull westos.org/game2048
四.配置使用者權限,給證書加密
如果想要控制registry的使用權限,使其隻有在登入使用者名和密碼之後才能使用的話,還需要做額外的設定。registry的使用者名密碼檔案可以通過htpasswd來生成
1.設定使用者密碼并檢視
cd /opt/docker/
mkdir auth
docker run --entrypoint htpasswd registry:2.3.1 -Bbn wang westos > auth/htpasswd
docker run --rm --entrypoint htpasswd registry:2.3.1 -Bbn admin westos >> auth/htpasswd
cat auth/htpasswd
wang:$2y$05$lyM5fqXxNOqWQLIlMUplxet.dPLMZMlZutV6oJk7AxyZCcDUkTyZ.
admin:$2y$05$eFez8FCfUBM7BQG.uoxY9OtioSZNaaGJudyjDDm3gb4U0XBJg8q8q
2.建立倉庫
docker stop registry
docker rm registry
docker run -d --restart=always --name registry -v "$(pwd)"/certs:/certs -e REGISTRY_HTTP_ADDR=0.0.0.0:443 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/westos.org.crt -e REGISTRY_HTTP_TLS_KEY=/certs/westos.org.key -p 443:443 -v /opt/registry:/var/lib/registry -v "$(pwd)"/auth:/auth -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd registry:2.3.1 ##這個新安裝的倉庫設定安裝,包含了:證書和使用者權限
docker tag rhel7:latest westos/rhel7
netstat -antlp | grep :443 ##過濾443端口
tcp6 0 0 :::443 :::* LISTEN 27631/docker-proxy
docker push westos/rhel7
no basic auth credentials ##此時上傳顯示沒有基礎認證,在沒有登入相應的docker倉庫的情況下,無法上傳\拉取相應的容器。
3.登入庫,輸入使用者名和設定的密碼
docker login westos.org
Username: wang
Password: westos
Login Succeeded ##顯示成功即可
4.在檔案config.json 中可以看到記錄的認證(認證一次,永久儲存)
cd /root/.docker/
ls
config.json
vim config.json
{
"auths": {
"westos.org": {
"auth": "aHVpOndlc3Rvcw=="
}
},
"HttpHeaders": {
"User-Agent": "Docker-Client/18.06.1-ce (linux)"
}
}
5.再次上傳剛才沒有上傳的那個鏡像
docker push westos/rhel7 ##上傳成功
The push refers to repository [westos/rhel7]
18af9eb19b5f: Pushed
latest: digest: sha256:58cd9120a4194edb0de4377b71bd564953255a1422baa1bbd9cb23d521c6873b size: 528
五.給建立的私有倉庫添加web的UI界面
1.導入相應的鏡像
docker load -i docker-registry-web.tar
docker load -i docker-registry-frontend.tar
2.重新建立倉庫(增加了一個删除參數)
docker rm -f registry
docker rm -f registry-web
docker run -d --restart=always --name registry -v "$(pwd)"/certs:/certs -e REGISTRY_HTTP_ADDR=0.0.0.0:443 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/westos.org.crt -e REGISTRY_HTTP_TLS_KEY=/certs/westos.org.key -p 443:443 -v /opt/registry:/var/lib/registry -v "$(pwd)"/auth:/auth -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd -e REGISTRY_STORAGE_DELETE_ENABLED=true registry:2.3.1 ##允許執行删除操作
docker run -it -p 8080:8080 --name registry-web --lnk registry:westos.org -e REGISTRY_URL=https://westos.org/v2 -e REGISTRY_TRUST_ANY_SSL=true -e REGISTRY_BASIC_AUTH="aHVpOndlc3Rvcw==" -e REGISTRY_NAME=westos.org -e REGISTRY_READONLY=false docker-registry-web ##運作web界面
3.測試
在網頁的頁面上輸入:localhost:8080