1. 摘要
倉(cāng)庫(kù)(Repository)是集中存放鏡像的地方。
一個(gè)容易混淆的概念是注冊(cè)服務(wù)器(Registry)。實(shí)際上注冊(cè)服務(wù)器是管理倉(cāng)庫(kù)的具體服務(wù)器谍失,每個(gè)服務(wù)器上可以有多個(gè)倉(cāng)庫(kù),而每個(gè)倉(cāng)庫(kù)下面有多個(gè)鏡像。從這方面來說棺榔,倉(cāng)庫(kù)可以被認(rèn)為是一個(gè)具體的項(xiàng)目或目錄。例如對(duì)于倉(cāng)庫(kù)地址 docker.io/ubuntu 來說隘道,docker.io 是注冊(cè)服務(wù)器地址爱沟,ubuntu 是倉(cāng)庫(kù)名潭辈。
大部分時(shí)候糟需,并不需要嚴(yán)格區(qū)分這兩者的概念旅赢。
2. 內(nèi)容
2.1 Docker Hub
目前 Docker 官方維護(hù)了一個(gè)公共倉(cāng)庫(kù) Docker Hub,其中已經(jīng)包括了數(shù)量超過 2,650,000 的鏡像激捏。大部分需求都可以通過在 Docker Hub 中直接下載鏡像來實(shí)現(xiàn)设塔。
注冊(cè)
你可以在 https://hub.docker.com 免費(fèi)注冊(cè)一個(gè) Docker 賬號(hào)。
登錄
可以通過執(zhí)行 docker login
命令交互式的輸入用戶名及密碼來完成在命令行界面登錄 Docker Hub缩幸。
你可以通過 docker logout
退出登錄壹置。
docker login -u duncanwang -p ***
docker logout
拉取鏡像
你可以通過 docker search
命令來查找官方倉(cāng)庫(kù)中的鏡像,并利用 docker pull
命令來將它下載到本地表谊。
例如以 centos
為關(guān)鍵詞進(jìn)行搜索:
$ docker search centos
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
centos The official build of CentOS. 6449 [OK]
ansible/centos7-ansible Ansible on Centos7 132 [OK]
consol/centos-xfce-vnc Centos container with "headless" VNC session… 126 [OK]
jdeathe/centos-ssh OpenSSH / Supervisor / EPEL/IUS/SCL Repos - … 117 [OK]
centos/systemd systemd enabled base container. 96 [OK]
可以看到返回了很多包含關(guān)鍵字的鏡像钞护,其中包括鏡像名字、描述爆办、收藏?cái)?shù)(表示該鏡像的受關(guān)注程度)难咕、是否官方創(chuàng)建(OFFICIAL
)、是否自動(dòng)構(gòu)建 (AUTOMATED
)距辆。
根據(jù)是否是官方提供余佃,可將鏡像分為兩類。
一種是類似 centos
這樣的鏡像跨算,被稱為基礎(chǔ)鏡像或根鏡像爆土。這些基礎(chǔ)鏡像由 Docker 公司創(chuàng)建、驗(yàn)證诸蚕、支持步势、提供氧猬。這樣的鏡像往往使用單個(gè)單詞作為名字。
還有一種類型坏瘩,比如 ansible/centos7-ansible
鏡像盅抚,它是由 Docker Hub 的注冊(cè)用戶創(chuàng)建并維護(hù)的,往往帶有用戶名稱前綴倔矾⊥可以通過前綴 username/
來指定使用某個(gè)用戶提供的鏡像,比如 ansible 用戶哪自。
另外丰包,在查找的時(shí)候通過 --filter=stars=N
參數(shù)可以指定僅顯示收藏?cái)?shù)量為 N
以上的鏡像。
下載官方 centos
鏡像到本地提陶。
$ docker pull centos
Using default tag: latest
latest: Pulling from library/centos
7a0437f04f83: Pull complete
Digest: sha256:5528e8b1b1719d34604c87e11dcd1c0a20bedf46e83b5632cdeac91b8c04efc1
Status: Downloaded newer image for centos:latest
docker.io/library/centos:latest
推送鏡像
用戶也可以在登錄后通過 docker push
命令來將自己的鏡像推送到 Docker Hub烫沙。
以下命令中的 username
請(qǐng)?zhí)鎿Q為你的 Docker 賬號(hào)用戶名。
$ 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 search username
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
username/ubuntu
自動(dòng)構(gòu)建
自動(dòng)構(gòu)建(Automated Builds
)功能對(duì)于需要經(jīng)常升級(jí)鏡像內(nèi)程序來說隙笆,十分方便。
有時(shí)候升筏,用戶構(gòu)建了鏡像撑柔,安裝了某個(gè)軟件,當(dāng)軟件發(fā)布新版本則需要手動(dòng)更新鏡像您访。
而自動(dòng)構(gòu)建允許用戶通過 Docker Hub 指定跟蹤一個(gè)目標(biāo)網(wǎng)站(支持 GitHub 或 BitBucket)上的項(xiàng)目铅忿,一旦項(xiàng)目發(fā)生新的提交 (commit
)或者創(chuàng)建了新的標(biāo)簽(tag
),Docker Hub 會(huì)自動(dòng)構(gòu)建鏡像并推送到 Docker Hub 中灵汪。
要配置自動(dòng)構(gòu)建檀训,包括如下的步驟:
登錄 Docker Hub;
在 Docker Hub 點(diǎn)擊右上角頭像享言,在賬號(hào)設(shè)置(
Account Settings
)中關(guān)聯(lián)(Linked Accounts
)目標(biāo)網(wǎng)站峻凫;在 Docker Hub 中新建或選擇已有的倉(cāng)庫(kù),在
Builds
選項(xiàng)卡中選擇Configure Automated Builds
览露;選取一個(gè)目標(biāo)網(wǎng)站中的項(xiàng)目(需要含
Dockerfile
)和分支荧琼;指定
Dockerfile
的位置,并保存差牛。
之后命锄,可以在 Docker Hub 的倉(cāng)庫(kù)頁(yè)面的 Timeline
選項(xiàng)卡中查看每次構(gòu)建的狀態(tài)。
2.2 私有倉(cāng)庫(kù)
有時(shí)候使用 Docker Hub 這樣的公共倉(cāng)庫(kù)可能不方便偏化,用戶可以創(chuàng)建一個(gè)本地倉(cāng)庫(kù)供私人使用脐恩。
本節(jié)介紹如何使用本地倉(cāng)庫(kù)。
docker-registry
是官方提供的工具侦讨,可以用于構(gòu)建私有的鏡像倉(cāng)庫(kù)驶冒。本文內(nèi)容基于 docker-registry
v2.x 版本析孽。
安裝運(yùn)行 docker-registry
你可以使用官方 registry 鏡像來運(yùn)行。
$ docker run -d -p 5000:5000 --restart=always --name registry registry
這將使用官方的 registry 鏡像來啟動(dòng)私有倉(cāng)庫(kù)只怎。默認(rèn)情況下袜瞬,倉(cāng)庫(kù)會(huì)被創(chuàng)建在容器的 /var/lib/registry 目錄下。你可以通過 -v 參數(shù)來將鏡像文件存放在本地的指定路徑身堡。例如下面的例子將上傳的鏡像放到本地的 /opt/data/registry 目錄邓尤。
$ docker run -d \
-p 5000:5000 \
-v /opt/data/registry:/var/lib/registry \
registry
在私有倉(cāng)庫(kù)上傳、搜索贴谎、下載鏡像
創(chuàng)建好私有倉(cāng)庫(kù)之后汞扎,就可以使用 docker tag 來標(biāo)記一個(gè)鏡像,然后推送它到倉(cāng)庫(kù)擅这。例如私有倉(cāng)庫(kù)地址為 127.0.0.1:5000澈魄。
先在本機(jī)查看已有的鏡像。
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
ubuntu latest ba5877dc9bec 6 weeks ago 192.7 MB
使用 docker tag 將 ubuntu:latest 這個(gè)鏡像標(biāo)記為 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 上傳標(biāo)記的鏡像。
$ 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 查看倉(cāng)庫(kù)中的鏡像溯香。
$ curl 127.0.0.1:5000/v2/_catalog
{"repositories":["ubuntu"]}
這里可以看到 {"repositories":["ubuntu"]}鲫构,表明鏡像已經(jīng)被成功上傳了。
先刪除已有鏡像玫坛,再嘗試從私有倉(cāng)庫(kù)中下載這個(gè)鏡像结笨。
$ 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
配置非 https 倉(cāng)庫(kù)地址
如果你不想使用 127.0.0.1:5000 作為倉(cāng)庫(kù)地址,比如想讓本網(wǎng)段的其他主機(jī)也能把鏡像推送到私有倉(cāng)庫(kù)湿镀。你就得把例如 192.168.199.100:5000 這樣的內(nèi)網(wǎng)地址作為私有倉(cāng)庫(kù)地址炕吸,這時(shí)你會(huì)發(fā)現(xiàn)無法成功推送鏡像。
這是因?yàn)?Docker 默認(rèn)不允許非 HTTPS 方式推送鏡像勉痴。我們可以通過 Docker 的配置選項(xiàng)來取消這個(gè)限制赫模,或者查看下一節(jié)配置能夠通過 HTTPS 訪問的私有倉(cāng)庫(kù)。
Ubuntu 16.04+, Debian 8+, centos 7
對(duì)于使用 systemd 的系統(tǒng)蚀腿,請(qǐng)?jiān)?/etc/docker/daemon.json 中寫入如下內(nèi)容(如果文件不存在請(qǐng)新建該文件)
{
"registry-mirror": [
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com"
],
"insecure-registries": [
"192.168.199.100:5000"
]
}
注意:該文件必須符合 json 規(guī)范嘴瓤,否則 Docker 將不能啟動(dòng)。
2.3 私有倉(cāng)庫(kù)高級(jí)配置
上一節(jié)我們搭建了一個(gè)具有基礎(chǔ)功能的私有倉(cāng)庫(kù)莉钙,本小節(jié)我們來使用 Docker Compose 搭建一個(gè)擁有權(quán)限認(rèn)證廓脆、TLS 的私有倉(cāng)庫(kù)。
新建一個(gè)文件夾磁玉,以下步驟均在該文件夾中進(jìn)行停忿。
準(zhǔn)備站點(diǎn)證書
如果你擁有一個(gè)域名,國(guó)內(nèi)各大云服務(wù)商均提供免費(fèi)的站點(diǎn)證書蚊伞。你也可以使用 openssl 自行簽發(fā)證書席赂。
這里假設(shè)我們將要搭建的私有倉(cāng)庫(kù)地址為 docker.domain.com吮铭,下面我們介紹使用 openssl 自行簽發(fā) docker.domain.com 的站點(diǎn) SSL 證書。
第一步創(chuàng)建 CA 私鑰颅停。
$ openssl genrsa -out "root-ca.key" 4096
第二步利用私鑰創(chuàng)建 CA 根證書請(qǐng)求文件谓晌。
$ 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 參數(shù)里的 /C 表示國(guó)家,如 CN癞揉;/ST 表示手饺狻;/L 表示城市或者地區(qū)喊熟;/O 表示組織名柏肪;/CN 通用名稱。
第三步配置 CA 根證書芥牌,新建 root-ca.cnf烦味。
[root_ca]
basicConstraints = critical,CA:TRUE,pathlen:1
keyUsage = critical, nonRepudiation, cRLSign, keyCertSign
subjectKeyIdentifier=hash
第四步簽發(fā)根證書。
$ 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
第五步生成站點(diǎn) SSL 私鑰壁拉。
$ openssl genrsa -out "docker.domain.com.key" 4096
第六步使用私鑰生成證書請(qǐng)求文件谬俄。
$ 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
第八步簽署站點(diǎn) 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
這樣已經(jīng)擁有了 docker.domain.com 的網(wǎng)站 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 這三個(gè)文件移入案铺,刪除其他文件。
配置私有倉(cāng)庫(kù)
私有倉(cāng)庫(kù)默認(rèn)的配置文件位于 /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 認(rèn)證文件
$ mkdir auth
$ docker run --rm \
--entrypoint htpasswd \
httpd:alpine \
-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
啟動(dòng)
$ docker-compose up -d
這樣我們就搭建好了一個(gè)具有權(quán)限認(rèn)證姑子、TLS 的私有倉(cāng)庫(kù),接下來我們測(cè)試其功能是否正常测僵。
測(cè)試私有倉(cāng)庫(kù)功能
由于自行簽發(fā)的 CA 根證書不被系統(tǒng)信任街佑,所以我們需要將 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
登錄到私有倉(cāng)庫(kù)捍靠。
$ 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
發(fā)現(xiàn)會(huì)提示沒有登錄,不能將鏡像推送到私有倉(cāng)庫(kù)中良风。
2.4 Nexus 3 私有倉(cāng)庫(kù)
使用 Docker 官方的 Registry 創(chuàng)建的倉(cāng)庫(kù)面臨一些維護(hù)問題谊迄。比如某些鏡像刪除以后空間默認(rèn)是不會(huì)回收的闷供,需要一些命令去回收空間然后重啟 Registry。在企業(yè)中把內(nèi)部的一些工具包放入 Nexus
中是比較常見的做法统诺,最新版本 Nexus3.x
全面支持 Docker 的私有鏡像歪脏。所以使用 Nexus3.x
一個(gè)軟件來管理 Docker
, Maven
, Yum
, PyPI
等是一個(gè)明智的選擇。
3. 參考
(1)訪問倉(cāng)庫(kù) https://yeasy.gitbook.io/docker_practice/repository