Docker 系列(六):公有倉庫與私有倉庫
Docker Hub
目前 Docker 官方維護了一個公共倉庫Docker Hub,其中已經包括了數量超過2,650,000的映象。大部分需求都可以通過在 Docker Hub 中直接下載映象來實現。
註冊
你可以在https://hub.docker.com免費註冊一個 Docker 賬號。
登入
可以通過執行docker login
命令互動式的輸入使用者名稱及密碼來完成在命令列介面登入 Docker Hub。
你可以通過docker logout
退出登入。
拉取映象
你可以通過docker search
命令來查詢官方倉庫中的映象,並利用docker pull
命令來將它下載到本地。
例如以centos
$ docker search centos NAME DESCRIPTION STARS OFFICIAL AUTOMATED centos The official build of CentOS. 465 [OK] tianon/centos CentOS 5 and 6, created using rinse instea... 28 blalor/centos Bare-bones base CentOS 6.5 image 6 [OK] saltstack/centos-6-minimal 6 [OK] tutum/centos-6.4 DEPRECATED. Use tutum/centos:6.4 instead. ... 5 [OK]
可以看到返回了很多包含關鍵字的映象,其中包括映象名字、描述、收藏數(表示該映象的受關注程度)、是否官方建立(OFFICIAL)、是否自動構建 (AUTOMATED)。
根據是否是官方提供,可將映象分為兩類。
一種是類似centos
這樣的映象,被稱為基礎映象或根映象。這些基礎映象由 Docker 公司建立、驗證、支援、提供。這樣的映象往往使用單個單詞作為名字。
還有一種型別,比如tianon/centos
映象,它是由 Docker Hub 的註冊使用者建立並維護的,往往帶有使用者名稱稱字首。可以通過字首username/
來指定使用某個使用者提供的映象,比如 tianon 使用者。
另外,在查詢的時候通過--filter=stars=N
N
以上的映象。
下載官方centos
映象到本地。
$ docker pull centos
Pulling repository centos
0b443ba03958: Download complete
539c0211cd76: Download complete
511136ea3c5a: Download complete
7064731afe90: Download complete
推送映象
使用者也可以在登入後通過docker push
命令來將自己的映象推送到 Docker Hub。
以下命令中的username
請替換為你的 Docker 賬號使用者名稱。
$ docker tag ubuntu:18.04 username/ubuntu:18.04 $ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu 18.04 275d79972a86 6 days ago 94.6MB username/ubuntu 18.04 275d79972a86 6 days ago 94.6MB $ docker push username/ubuntu:18.04
私有倉庫
有時候使用 Docker Hub 這樣的公共倉庫可能不方便,使用者可以建立一個本地倉庫供私人使用。
本節介紹如何使用本地倉庫。
docker-registry
是官方提供的工具,可以用於構建私有的映象倉庫。本文內容基於docker-registry
v2.x 版本。
安裝執行 docker-registry
容器執行
你可以通過獲取官方registry
映象來執行。
$ docker run -d -p 5000:5000 --restart=always --name registry registry
這將使用官方的registry
映象來啟動私有倉庫。預設情況下,倉庫會被建立在容器的/var/lib/registry
目錄下。你可以通過-v
引數來將映象檔案存放在本地的指定路徑。例如下面的例子將上傳的映象放到本地的/opt/data/registry
目錄。
$ docker run -d \
-p 5000:5000 \
-v /opt/data/registry:/var/lib/registry \
registry
在私有倉庫上傳、搜尋、下載映象
建立好私有倉庫之後,就可以使用docker tag
來標記一個映象,然後推送它到倉庫。例如私有倉庫地址為127.0.0.1:5000
。
先在本機檢視已有的映象。
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
ubuntu latest ba5877dc9bec 6 weeks ago 192.7 MB
使用docker tag
將ubuntu:latest
這個映象標記為127.0.0.1:5000/ubuntu:latest
。
格式為docker tag IMAGE[:TAG] [REGISTRY_HOST[:REGISTRY_PORT]/]REPOSITORY[:TAG]
。
$ docker tag ubuntu:latest 127.0.0.1:5000/ubuntu:latest
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
ubuntu latest ba5877dc9bec 6 weeks ago 192.7 MB
127.0.0.1:5000/ubuntu:latest latest ba5877dc9bec 6 weeks ago 192.7 MB
使用docker push
上傳標記的映象。
$ docker push 127.0.0.1:5000/ubuntu:latest
The push refers to repository [127.0.0.1:5000/ubuntu]
373a30c24545: Pushed
a9148f5200b0: Pushed
cdd3de0940ab: Pushed
fc56279bbb33: Pushed
b38367233d37: Pushed
2aebd096e0e2: Pushed
latest: digest: sha256:fe4277621f10b5026266932ddf760f5a756d2facd505a94d2da12f4f52f71f5a size: 1568
用curl
檢視倉庫中的映象。
$ curl 127.0.0.1:5000/v2/_catalog
{"repositories":["ubuntu"]}
這裡可以看到{"repositories":["ubuntu"]}
,表明映象已經被成功上傳了。
先刪除已有映象,再嘗試從私有倉庫中下載這個映象。
$ docker image rm 127.0.0.1:5000/ubuntu:latest
$ docker pull 127.0.0.1:5000/ubuntu:latest
Pulling repository 127.0.0.1:5000/ubuntu:latest
ba5877dc9bec: Download complete
511136ea3c5a: Download complete
9bad880da3d2: Download complete
25f11f5fb0cb: Download complete
ebc34468f71d: Download complete
2318d26665ef: Download complete
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
127.0.0.1:5000/ubuntu:latest latest ba5877dc9bec 6 weeks ago 192.7 MB
注意事項
如果你不想使用127.0.0.1:5000
作為倉庫地址,比如想讓本網段的其他主機也能把映象推送到私有倉庫。你就得把例如192.168.199.100:5000
這樣的內網地址作為私有倉庫地址,這時你會發現無法成功推送映象。
這是因為 Docker 預設不允許非HTTPS
方式推送映象。我們可以通過 Docker 的配置選項來取消這個限制,或者檢視下一節配置能夠通過HTTPS
訪問的私有倉庫。
Ubuntu 16.04+, Debian 8+, centos 7
對於使用systemd
的系統,請在/etc/docker/daemon.json
中寫入如下內容(如果檔案不存在請新建該檔案)
{
"registry-mirror": [
"https://dockerhub.azk8s.cn"
],
"insecure-registries": [
"192.168.199.100:5000"
]
}
注意:該檔案必須符合
json
規範,否則 Docker 將不能啟動。
其他
對於 Docker Desktop for Windows 、 Docker Desktop for Mac 在設定中的Docker Engine
中進行編輯 ,增加和上邊一樣的字串即可。
私有倉庫高階配置
上一節我們搭建了一個具有基礎功能的私有倉庫,本小節我們來使用Docker Compose
搭建一個擁有許可權認證、TLS 的私有倉庫。
新建一個資料夾,以下步驟均在該資料夾中進行。
準備站點證書
如果你擁有一個域名,國內各大雲服務商均提供免費的站點證書。你也可以使用openssl
自行簽發證書。
這裡假設我們將要搭建的私有倉庫地址為docker.domain.com
,下面我們介紹使用openssl
自行簽發docker.domain.com
的站點 SSL 證書。
第一步建立CA
私鑰。
$ openssl genrsa -out "root-ca.key" 4096
第二步利用私鑰建立CA
根證書請求檔案。
$ openssl req \
-new -key "root-ca.key" \
-out "root-ca.csr" -sha256 \
-subj '/C=CN/ST=Shanxi/L=Datong/O=Your Company Name/CN=Your Company Name Docker Registry CA'
以上命令中
-subj
引數裡的/C
表示國家,如CN
;/ST
表示省;/L
表示城市或者地區;/O
表示組織名;/CN
通用名稱。
第三步配置CA
根證書,新建root-ca.cnf
。
[root_ca]
basicConstraints = critical,CA:TRUE,pathlen:1
keyUsage = critical, nonRepudiation, cRLSign, keyCertSign
subjectKeyIdentifier=hash
第四步簽發根證書。
$ openssl x509 -req -days 3650 -in "root-ca.csr" \
-signkey "root-ca.key" -sha256 -out "root-ca.crt" \
-extfile "root-ca.cnf" -extensions \
root_ca
第五步生成站點SSL
私鑰。
$ openssl genrsa -out "docker.domain.com.key" 4096
第六步使用私鑰生成證書請求檔案。
$ openssl req -new -key "docker.domain.com.key" -out "site.csr" -sha256 \
-subj '/C=CN/ST=Shanxi/L=Datong/O=Your Company Name/CN=docker.domain.com'
第七步配置證書,新建site.cnf
檔案。
[server]
authorityKeyIdentifier=keyid,issuer
basicConstraints = critical,CA:FALSE
extendedKeyUsage=serverAuth
keyUsage = critical, digitalSignature, keyEncipherment
subjectAltName = DNS:docker.domain.com, IP:127.0.0.1
subjectKeyIdentifier=hash
第八步簽署站點SSL
證書。
$ openssl x509 -req -days 750 -in "site.csr" -sha256 \
-CA "root-ca.crt" -CAkey "root-ca.key" -CAcreateserial \
-out "docker.domain.com.crt" -extfile "site.cnf" -extensions server
這樣已經擁有了docker.domain.com
的網站 SSL 私鑰docker.domain.com.key
和 SSL 證書docker.domain.com.crt
及 CA 根證書root-ca.crt
。
新建ssl
資料夾並將docker.domain.com.key
docker.domain.com.crt
root-ca.crt
這三個檔案移入,刪除其他檔案。
配置私有倉庫
私有倉庫預設的配置檔案位於/etc/docker/registry/config.yml
,我們先在本地編輯config.yml
,之後掛載到容器中。
version: 0.1
log:
accesslog:
disabled: true
level: debug
formatter: text
fields:
service: registry
environment: staging
storage:
delete:
enabled: true
cache:
blobdescriptor: inmemory
filesystem:
rootdirectory: /var/lib/registry
auth:
htpasswd:
realm: basic-realm
path: /etc/docker/registry/auth/nginx.htpasswd
http:
addr: :443
host: https://docker.domain.com
headers:
X-Content-Type-Options: [nosniff]
http2:
disabled: false
tls:
certificate: /etc/docker/registry/ssl/docker.domain.com.crt
key: /etc/docker/registry/ssl/docker.domain.com.key
health:
storagedriver:
enabled: true
interval: 10s
threshold: 3
生成 http 認證檔案
$ mkdir auth
$ docker run --rm \
--entrypoint htpasswd \
registry \
-Bbn username password > auth/nginx.htpasswd
將上面的
username
password
替換為你自己的使用者名稱和密碼。
編輯docker-compose.yml
version: '3'
services:
registry:
image: registry
ports:
- "443:443"
volumes:
- ./:/etc/docker/registry
- registry-data:/var/lib/registry
volumes:
registry-data:
修改 hosts
編輯/etc/hosts
127.0.0.1 docker.domain.com
啟動
$ docker-compose up -d
這樣我們就搭建好了一個具有許可權認證、TLS 的私有倉庫,接下來我們測試其功能是否正常。
測試私有倉庫功能
由於自行簽發的 CA 根證書不被系統信任,所以我們需要將 CA 根證書ssl/root-ca.crt
移入/etc/docker/certs.d/docker.domain.com
資料夾中。
$ sudo mkdir -p /etc/docker/certs.d/docker.domain.com
$ sudo cp ssl/root-ca.crt /etc/docker/certs.d/docker.domain.com/ca.crt
登入到私有倉庫。
$ docker login docker.domain.com
嘗試推送、拉取映象。
$ docker pull ubuntu:18.04
$ docker tag ubuntu:18.04 docker.domain.com/username/ubuntu:18.04
$ docker push docker.domain.com/username/ubuntu:18.04
$ docker image rm docker.domain.com/username/ubuntu:18.04
$ docker pull docker.domain.com/username/ubuntu:18.04
如果我們退出登入,嘗試推送映象。
$ docker logout docker.domain.com
$ docker push docker.domain.com/username/ubuntu:18.04
no basic auth credentials
發現會提示沒有登入,不能將映象推送到私有倉庫中。
注意事項
如果你本機佔用了443
埠,你可以配置Nginx 代理,這裡不再贅述。
Nexus3.x 的私有倉庫
使用 Docker 官方的 Registry 建立的倉庫面臨一些維護問題。比如某些映象刪除以後空間預設是不會回收的,需要一些命令去回收空間然後重啟 Registry 程式。在企業中把內部的一些工具包放入 Nexus 中是比較常見的做法,最新版本Nexus3.x
全面支援 Docker 的私有映象。所以使用Nexus3.x
一個軟體來管理Docker
,Maven
,Yum
,PyPI
等是一個明智的選擇。
啟動 Nexus 容器
$ docker run -d --name nexus3 --restart=always \
-p 8081:8081 \
--mount src=nexus-data,target=/nexus-data \
sonatype/nexus3
等待 3-5 分鐘,如果nexus3
容器沒有異常退出,那麼你可以使用瀏覽器開啟http://YourIP:8081
訪問 Nexus 了。
第一次啟動 Nexus 的預設帳號是admin
密碼是admin123
登入以後點選頁面上方的齒輪按鈕進行設定。
建立倉庫
建立一個私有倉庫的方法:Repository->Repositories
點選右邊選單Create repository
選擇docker (hosted)
- Name: 倉庫的名稱
- HTTP: 倉庫單獨的訪問埠
- Enable Docker V1 API: 如果需要同時支援 V1 版本請勾選此項(不建議勾選)。
- Hosted -> Deployment pollcy: 請選擇 Allow redeploy 否則無法上傳 Docker 映象。
其它的倉庫建立方法請各位自己摸索,還可以建立一個 docker (proxy) 型別的倉庫連結到 DockerHub 上。再建立一個 docker (group) 型別的倉庫把剛才的 hosted 與 proxy 新增在一起。主機在訪問的時候預設下載私有倉庫中的映象,如果沒有將連結到 DockerHub 中下載並快取到 Nexus 中。
新增訪問許可權
選單Security->Realms
把 Docker Bearer Token Realm 移到右邊的框中儲存。
新增使用者規則:選單Security->Roles
->Create role
在Privlleges
選項搜尋 docker 把相應的規則移動到右邊的框中然後儲存。
新增使用者:選單Security->Users
->Create local user
在Roles
選項中選中剛才建立的規則移動到右邊的視窗儲存。
NGINX 加密代理
證書的生成請參見私有倉庫高階配置
裡面證書生成一節。
NGINX 示例配置如下
upstream register
{
server "YourHostName OR IP":5001; #埠為上面新增的私有映象倉庫是設定的 HTTP 選項的埠號
check interval=3000 rise=2 fall=10 timeout=1000 type=http;
check_http_send "HEAD / HTTP/1.0\r\n\r\n";
check_http_expect_alive http_4xx;
}
server {
server_name YourDomainName;#如果沒有 DNS 伺服器做解析,請刪除此選項使用本機 IP 地址訪問
listen 443 ssl;
ssl_certificate key/example.crt;
ssl_certificate_key key/example.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
large_client_header_buffers 4 32k;
client_max_body_size 300m;
client_body_buffer_size 512k;
proxy_connect_timeout 600;
proxy_read_timeout 600;
proxy_send_timeout 600;
proxy_buffer_size 128k;
proxy_buffers 4 64k;
proxy_busy_buffers_size 128k;
proxy_temp_file_write_size 512k;
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://register;
proxy_read_timeout 900s;
}
error_page 500 502 503 504 /50x.html;
}
原文整理:https://docker_practice.gitee.io/zh-cn/repository/