歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> 部署Docker Registry服務

部署Docker Registry服務

日期:2017/2/27 15:53:02   编辑:Linux教程
本文闡釋了怎樣部署私有的 Docker Registry 服務 —— 或為公司私用,或公開給其他用戶使用。例如,你公司可能需要私人的 Registry 來支持持續集成(CI)。又或,你的公司可能有大量鏡像方式的產品 或服務,你想以公司品牌的方式來整體提供和呈現。

Docker 公共的 Registry 裡維護有一個默認的 registry 鏡像可以用以協助該部署過程。該 Registry 鏡像對本地測試足矣,但不能用於生產環境。對於生產環境,應以 docker/distribution 為基礎,自行配置並構建自定義 Registry 鏡像。

注意:本文中的例子在 Ubuntu 14.04 下編寫及測試。如果你在不同的操作系統中運行 Docker,你或許需要“翻譯”這些命令,以適合你運行環境的需要。

官方鏡像下的簡單示例

本節中,將創建一個 Container 來運行 Docker 的官方 Registry 鏡像。你將推送(Push)一個鏡像到這個 Registry 服務器,然後再從該 Registry 中拉取(Pull)同一個鏡像。

這是個很好的練習,有助於理解客戶端與本地 Registry 的基本交互。

1. 安裝 Docker。

2. 從 Docker 公共 Registry 中運行 hello-world 鏡像。
$ docker run hello-world

run 命令自動從 Docker 的官方鏡像庫中將 hello-world 鏡像 pull 下來。

3. 在 localhost 上啟動 Registry 服務。
$ docker run -p 5000:5000 registry:2.0

這將在 DOCKER_HOST 上啟動一個 Registry 服務,並在 5000 端口監聽。

4. 列出鏡像。
$ docker images
REPOSITORY     TAG     IMAGE ID      CREATED       VIRTUAL SIZE
registry       2.0     bbf0b6ffe923  3 days ago    545.1 MB
golang         1.4     121a93c90463  5 days ago    514.9 MB
hello-world    latest  e45a5af57b00  3 months ago  910 B

這個列表應當包括一個由先前運行而得來的 hello-world 鏡像。

5. 為本地 repoistory 重新標記 hello-world 鏡像。
$ docker tag hello-world:latest localhost:5000/hello-mine:latest

此 命令使用 [REGISTRYHOST/]NAME[:TAG] 格式為 hello-world:latest 重新打標。REGISTRYHOST 在此例中是 localhost。在 Mac OSX 環境中,得把 localhost 換成 $(boot2docker ip):5000。

6. 列出新鏡像。
$ docker images
REPOSITORY                  TAG          IMAGE ID      CREATED       VIRTUAL SIZE
registry                    2.0     bbf0b6ffe923  3 days ago    545.1 MB
golang                      1.4     121a93c90463  5 days ago    514.9 MB
hello-world                 latest  e45a5af57b00  3 months ago  910 B
localhost:5000/hello-mine   latest  ef5a5gf57b01  3 months ago  910 B

可以看到,新鏡像已經出現在列表中。

7. 推送新鏡像到本地 Registry 中。
$ docker push localhost:5000/hello-mine:latest
The push refers to a repository [localhost:5000/hello-mine] (len: 1)
e45a5af57b00: Image already exists
31cbccb51277: Image successfully pushed
511136ea3c5a: Image already exists
Digest: sha256:a1b13bc01783882434593119198938b9b9ef2bd32a0a246f16ac99b01383ef7a

8. 使用 curl 命令及 Docker Registry 服務 API v2 列出 Registry 中的鏡像:
$ curl -v -X GET http://localhost:5000/v2/hello-mine/tags/list
* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 5000 (#0)
> GET /v2/hello-mine/tags/list HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:5000
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=utf-8
< Docker-Distribution-Api-Version: registry/2.0
< Date: Sun, 12 Apr 2015 01:29:47 GMT
< Content-Length: 40
<
{"name":"hello-mine","tags":["latest"]}
* Connection #0 to host localhost left intact

也可以通過在浏覽器中訪問以下地址來獲取這些信息:
http://localhost:5000/v2/hello-mine/tags/list

9. 從你的本地環境中移除所有未使用的鏡像:
$ docker rmi -f $(docker images -q -a )

此命令僅用於說明目的;移除鏡像強制 run 從 Registry 而不是從本地緩存拉取。如果在這之後運行docker images,在你的鏡像列表中,應該看不到任何 hello-world 或 hello-mine 的實例。
$ docker images
REPOSITORY      TAG      IMAGE ID      CREATED       VIRTUAL SIZE
registry         2.0     bbf0b6ffe923  3 days ago    545.1 MB
golang           1.4     121a93c90463  5 days ago    514.9 MB

10. 試運行 hello-mine。
$ docker run hello-mine
Unable to find image 'hello-mine:latest' locally
Pulling repository hello-mine
FATA[0001] Error: image library/hello-mine:latest not found

命令 run 運行失敗,因為你的新鏡像在 Docker 公共 Registry 中是不存在的。

11. 現在,嘗試指定鏡像的 Registry 來運行鏡像:
$ docker run localhost:5000/hello-mine

如果你在這之後運行 docker images, 你會發現裡面多了一個 hello-mine 的實例。
使 Docker 官方 Registry 鏡像做好生產環境准備

Docker 的官方鏡像只為簡單的測試或除錯准備。其配置對多數生產環境來講都不適用。例如,任何能訪問服務器 IP 的客戶端,都能推送及拉取鏡像。參看下一節,獲取使該鏡像做好生產環境准備的信息。
理解生產環境的部署

當部署一個用於生產環境發布的 Registry 時,須考慮如下因素:
backend storage 應在何處存儲鏡像?
access and/or authentication 用戶是否應擁有全部或受控的訪問權限?這取決於你為公眾提供鏡像服務,還是只為公司內部提供。
debugging 當問題或狀況發生時,是否有解決這些它們的方法。日志由於可以看到問題動向,這使其很有用。
caching 快速提取鏡像可能至關重要,如果依賴鏡像進行測試、構建,或有其他自動化系統的話。

我們可以配置 Registry 功能特性,用以調整適配這些因素。可以在命令行裡指定選項來干這個,或者更通常地,用一個 Registry 配置文件來完成此事。配置文件是 YAML 格式的。

Docker 的官方 Repository 鏡像用以下配置文件做了預置:
```yaml
version: 0.1
log:
  level: debug
  fields:
    service: registry
    environment: development
storage:
  cache:
      layerinfo: inmemory
  filesystem:
      rootdirectory: /tmp/registry-dev
http:
  addr: :5000
  secret: asecretforlocaldevelopment
  debug:
      addr: localhost:5001
redis:
  addr: localhost:6379
  pool:
    maxidle: 16
    maxactive: 64
    idletimeout: 300s
  dialtimeout: 10ms
  readtimeout: 10ms
  writetimeout: 10ms
notifications:
  endpoints:
      - name: local-8082
        url: http://localhost:5003/callback
        headers:
           Authorization: [Bearer <an example token>]
        timeout: 1s
        threshold: 10
        backoff: 1s
        disabled: true
      - name: local-8083
        url: http://localhost:8083/callback
        timeout: 1s
        threshold: 10
        backoff: 1s
        disabled: true
```

這個配置非常基本,可以看到這在生產環境下會有一些問題。例如,http 區塊詳述了運行 Registry 的主機的 HTTP 服務器配置,但服務器沒有使用甚至是最低要求的傳輸層安全性(TLS)配置。接下來我們將配置這些東西。
在 Registry 服務器上配置 TLS

在本節中,將在服務器上配置 TLS,使能通過 https 協議來通信。在服務器上啟用 TLS 是在企業防火牆內運行 Registry 推薦的最低安全配置。達成這一目標的方法之一就是構建你自己的 Registry 鏡像。
下載 source 並生成 certificates

1. 下載 Registry 源碼。

當然,也可以使用 git clone 命令。

2. 把下載的包解壓到本地目錄。

解壓後創建 distribution 目錄。

3. 進入 distribution 目錄。
$ cd distribution

4. 新建 certs 子目錄。
$ mkdir certs

5. 使用 SSL 生成自簽名證書。
$ openssl req \
-newkey rsa:2048 -nodes -keyout certs/domain.key \
-x509 -days 365 -out certs/domain.crt

此命令將提示你回答一些基本的信息,用於創建證書。

6. 列出 certs 目錄的內容。
$ ls certs
domain.crt domain.key

當你構建這個 Container 時,certs 目錄及其內容也會自動被復制。
將 TLS 加入配置

distribution 軟件庫在 cmd 子目錄中包含有示例 Registry 配置。在本節中,您可以編輯這些配置之一,以添加 TLS 支持。

1. 編輯 ./cmd/registry/config.yml 文件。
$ vi ./cmd/registry/config.yml

2. 定位到 http 區塊。
http:
addr: :5000
secret: asecretforlocaldevelopment
debug:
addr: localhost:5001

3. 給服務器的自簽名證書新增一個 tls 區塊:
http:
addr: :5000
secret: asecretforlocaldevelopment
debug:
addr: localhost:5001
tls:
certificate: /go/src/github.com/docker/distribution/certs/domain.crt
key: /go/src/github.com/docker/distribution/certs/domain.key

提供 Container 內到證書的路徑。如果你希望跨 Layer 使用兩步認證,那麼你可以增加一個 clientcas 區塊選項。

4. 保存並關閉該文件。
構建並運行你的 Registry 鏡像

1. 構建你的 Registry 鏡像。
1

$ docker build -t secure_registry .

2. 運行你的新鏡像。
$ docker run -p 5000:5000 registry_local:latest
time="2015-04-12T03:06:18.616502588Z" level=info msg="endpoint local-8082 disabled, skipping" environment=development instance.id=bf33c9dc-2564-406b-97c3-6ee69dc20ec6 service=registry
time="2015-04-12T03:06:18.617012948Z" level=info msg="endpoint local-8083 disabled, skipping" environment=development instance.id=bf33c9dc-2564-406b-97c3-6ee69dc20ec6 service=registry
time="2015-04-12T03:06:18.617190113Z" level=info msg="using inmemory layerinfo cache" environment=development instance.id=bf33c9dc-2564-406b-97c3-6ee69dc20ec6 service=registry
time="2015-04-12T03:06:18.617349067Z" level=info msg="listening on :5000, tls" environment=development instance.id=bf33c9dc-2564-406b-97c3-6ee69dc20ec6 service=registry
time="2015-04-12T03:06:18.628589577Z" level=info msg="debug server listening localhost:5001"
2015/04/12 03:06:28 http: TLS handshake error from 172.17.42.1:44261: remote error: unknown certificate authority

觀察啟動時的信息。你應該可以看到 tls 在運行。

3. 使用 curl 驗證可以通過 https 連接。
$ curl -v https://localhost:5000
* Rebuilt URL to: https://localhost:5000/
* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 5000 (#0)
* successfully set certificate verify locations:
*   CAfile: none
CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS alert, Server hello (2):
* SSL certificate problem: self signed certificate
* Closing connection 0
curl: (60) SSL certificate problem: self signed certificate
More details here: http://curl.haxx.se/docs/sslcerts.html

配置適合 v1 及 v2 版本 Registry 的 Nginx

本 節介紹了如何使用 docker-compose ,在 nginx 代理背後運行版本 1 和 2 並存的 Registry 服務。並存的 Registry 服務都用 localhost:5000 訪問。如果 docker 客戶端版本小於 1.6,那麼 Nginx 將其請求路由到 1.0 版本的 Registry 服務。從更新版本客戶端發來的請求,將路由到 2.0 版本的 Registry 服務。

此過程使用您在上面最後一個過程中創建的 distribution 目錄。該目錄包含有一個 compose 配置示例。
安裝 Docker Compose

1. 在你 distribution 目錄所在主機上打開一個新的終端窗口。

2. 獲取 docker-compose 二進制可執行文件。
$ sudo wget https://github.com/docker/compose/releases/download/1.1.0/docker-compose-`uname -s`-`uname -m` -O /usr/local/bin/docker-compose

此命令將二進制可執行文件安裝到 /usr/local/bin 目錄。

3. 添加可執行權限到二進制文件。
$ sudo chmod +x /usr/local/bin/docker-compose
做一些清理

1. 移除早先的鏡像。
$ docker rmi -f $(docker images -q -a )

該步驟是一個內部管理步驟。這可以防止你在這個例子裡錯誤地選取了舊的鏡像。

2. 編輯 distribution/cmd/registry/config.yml 文件,並移除 tls 區塊。

如果沿用了前面例子裡的東西,你就會有一個 tls 區塊。

4. 保存變更並關閉文件。
配置 SSL
1. 進入 distribution/contrib/compose/nginx 目錄。
該目錄包含了 Nginx 及 Registry 的配置文件。

2. 使用 SSL 生成自簽名證書。
$ openssl req \
-newkey rsa:2048 -nodes -keyout domain.key \
-x509 -days 365 -out domain.crt

此命令將提示你回答一些問題,供證書創建使用。

3. 編輯 Dockerfile 並添加以下行。
COPY domain.crt /etc/nginx/domain.crt
COPY domain.key /etc/nginx/domain.key

當你全部搞完的時候,這個文件看上去像下面。
FROM nginx:1.7

COPY nginx.conf /etc/nginx/nginx.conf
COPY registry.conf /etc/nginx/conf.d/registry.conf
COPY docker-registry.conf /etc/nginx/docker-registry.conf
COPY docker-registry-v2.conf /etc/nginx/docker-registry-v2.conf
COPY domain.crt /etc/nginx/domain.crt
COPY domain.key /etc/nginx/domain.key

4. 保存並關閉 Dockerfile 文件。

5. 編輯 registry.conf 文件並增加以下配置。
ssl on;
ssl_certificate /etc/nginx/domain.crt;
ssl_certificate_key /etc/nginx/domain.key;

這是一個 nginx 配置文件。

6. 保存並關閉 registry.conf 文件。
構建並運行

1. 進到 distribution/contrib/compose 目錄
此目錄包含單一個 docker-compose.yml 配置。
nginx:
build: "nginx"
ports:
- "5000:5000"
links:
- registryv1:registryv1
- registryv2:registryv2
registryv1:
image: registry
ports:
- "5000"
registryv2:
build: "../../"
ports:
- "5000"

此配置按 nginx/Dockerfile 所指定,構建一個新的 nginx 鏡像。1.0 版本的 Registry 來自 Docker 的官方公開鏡像。Registry 2.0 鏡像將從你前面用到的 distribution/Dockerfile 來構建。

2. 獲取 Registry 1.0 鏡像。
$ docker pull registry:0.9.1

Compose 的配置是在本地尋找此鏡像。如果你不做這步,那後面的步驟會失敗。

3. 構建 nginx,Registry 2.0 鏡像,以及
$ docker-compose build
registryv1 uses an image, skipping
Building registryv2...
Step 0 : FROM golang:1.4

...

Removing intermediate container 9f5f5068c3f3
Step 4 : COPY docker-registry-v2.conf /etc/nginx/docker-registry-v2.conf
---> 74acc70fa106
Removing intermediate container edb84c2b40cb
Successfully built 74acc70fa106

此命令將輸出其執行過程,直到運行結束。

4. 啟動使用了 Compose 的配置。
$ docker-compose up
Recreating compose_registryv1_1...
Recreating compose_registryv2_1...
Recreating compose_nginx_1...
Attaching to compose_registryv1_1, compose_registryv2_1, compose_nginx_1
...

5. 在另一個終端,顯示運行中的配置。
$ docker ps
CONTAINER ID        IMAGE                       COMMAND                CREATED             STATUS              PORTS                                     NAMES
a81ad2557702        compose_nginx:latest        "nginx -g 'daemon of   8 minutes ago       Up 8 minutes        80/tcp, 443/tcp, 0.0.0.0:5000->5000/tcp   compose_nginx_1        
0618437450dd        compose_registryv2:latest   "registry cmd/regist   8 minutes ago       Up 8 minutes        0.0.0.0:32777->5000/tcp                   compose_registryv2_1  
aa82b1ed8e61        registry:latest             "docker-registry"      8 minutes ago       Up 8 minutes        0.0.0.0:32776->5000/tcp                   compose_registryv1_1

浏覽一下

1. 檢查一下你 nginx 服務器上的 TLS。
$ curl -v https://localhost:5000
* Rebuilt URL to: https://localhost:5000/
* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 5000 (#0)
* successfully set certificate verify locations:
*   CAfile: none
CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS alert, Server hello (2):
* SSL certificate problem: self signed certificate
* Closing connection 0
curl: (60) SSL certificate problem: self signed certificate
More details here: http://curl.haxx.se/docs/sslcerts.html

2. 標記 v1 registry 鏡像。
$ docker tag registry:latest localhost:5000/registry_one:latest
3. 將其推送到 localhost。
$ docker push localhost:5000/registry_one:latest
如果你在使用 1.6 版本的 Docker 客戶端,這將推送鏡像到 v2 registry。

4. 使用 curl 來列出 Registry 中的鏡像。
$ curl -v -X GET http://localhost:32777/v2/registry1/tags/list
* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 32777 (#0)
> GET /v2/registry1/tags/list HTTP/1.1
> User-Agent: curl/7.36.0
> Host: localhost:32777
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=utf-8
< Docker-Distribution-Api-Version: registry/2.0
< Date: Tue, 14 Apr 2015 22:34:13 GMT
< Content-Length: 39
<
{"name":"registry1","tags":["latest"]}
* Connection #0 to host localhost left intact

本例參照引用了分配給 2.0 Registry 服務的特定端口。早些時候,在使用 docker ps 命令顯示正在運行的容器時,你應該看到過這個端口。
Copyright © Linux教程網 All Rights Reserved