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

自動構建

自動構建(Automated Builds)功能對於需要經常升級鏡像內程序來說,十分方便。

有時候,用戶構建了鏡像,安裝了某個軟件,當軟件發布新版本則需要手動更新鏡像。

而自動構建允許用戶通過 Docker Hub 指定跟蹤一個目標網站(支持 GitHub 或 BitBucket)上的項目,一旦項目發生新的提交 (commit)或者創建了新的標簽(tag),Docker Hub 會自動構建鏡像並推送到 Docker Hub 中。

要配置自動構建,包括如下的步驟:

  • 登錄 Docker Hub;

  • 在 Docker Hub 點擊右上角頭像,在賬號設置(Account Settings)中關聯(Linked Accounts)目標網站;

  • 在 Docker Hub 中新建或選擇已有的倉庫,在 Builds 選項卡中選擇 Configure Automated Builds

  • 選取一個目標網站中的項目(需要含 Dockerfile)和分支;

  • 指定 Dockerfile 的位置,並保存。

之后,可以在 Docker Hub 的倉庫頁面的 Timeline 選項卡中查看每次構建的狀態。





私有倉庫

有時候使用 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/


免責聲明!

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



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