本文主要討論的是如何創建Docker私有倉庫,並通過自簽證書實現通過域名訪問私有倉庫。

Introduction

搭建Docker私有倉庫需要使用docker/docker-registry,但該項目已經被Docker官方廢棄,當前的 Docker Registry 2.0docker/distribution。文檔說明見https://github.com/docker/distribution/blob/master/docs/index.md

Preparations

OS

根據官方文檔 Installation on CentOS,Docker需要64-bit系統環境,且內核版本不低於3.10。以下是本人測試環境信息:

Item Info
OS CentOS Linux release 7.2.1511 (Core)
Kernel 3.10.0-327.13.1.el7.x86_64

Docker Engine

Docker的介紹、安裝和配置,可參考本人之前的博文 Docker Instroduction and Installation on CentOS 7

此處假定已經安裝docker-engine,並且啟動該服務。

Docker Distribution

在Docker Hub的registry中有如下說明:

The tags >= 2 refer to the new registry. Older tags refer to the deprecated registry.

即要想使用新的registry,需指定tag,且>=2,如registry:2.4

下載registry鏡像時如果不加tag,則默認為老版本

docker pull registry:2

注意: 運行registry:2須啟動iptables服務,否則會報錯。

sudo yum install -y iptables-services
sudo systemctl start  iptables
sudo systemctl enable iptables

Private Registry Storage Path

創建私有鏡像存儲路徑,此處以/data/docker-registry為例

  • 創建鏡像存儲路徑

    sudo mkdir -pv /data/docker-registry
    
  • 將目錄屬組改為Docker

    sudo chown :docker /data/docker-registry/
    

Generate Self-signed Certificate

參考官方文檔 Using self-signed certificates進行相關操作。

此處建議以root用戶身份運行相關命令

使用openssl命令套件創建自簽署證書,並保存在目錄/etc/docker/certs目錄下,以域名docker.lempstacker.com為例

  • 創建目錄

    [ ! -d /etc/docker/certs ] && mkdir -pv /etc/docker/certs
    
  • 進入目錄

    cd /etc/docker/certs
    
  • 生成自簽證書

    openssl req -x509 -newkey rsa:4096 -days 365 -nodes -sha256 -keyout registry.key -out registry.crt
    

以下是相關參數

Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:Shanghai
Locality Name (eg, city) [Default City]:Shanghai
Organization Name (eg, company) [Default Company Ltd]:LempStacker
Organizational Unit Name (eg, section) []:LempStacker
Common Name (eg, your name or your server's hostname) []:docker.lempstacker.com
Email Address []:test@lempstacker.com

因本機IP為192.168.0.109,故而在/etc/hosts中添加

192.168.0.109 docker.lempstacker.com

其它需要連接私有倉庫的主機也可添加該行記錄,用作域名解析。

Trust The Certificate

cd /etc/docker/certs/

mkdir docker.lempstacker.com:5000

cp ./registry.crt docker.lempstacker.com\:5000/ca.crt

cp /etc/docker/certs/registry.crt /etc/pki/ca-trust/source/anchors/docker.lempstacker.com.crt

update-ca-trust

操作完成後,重啟Docker服務

sudo systemctl restart docker

Run Registry Container

啟動容器,使用/var/lib/registry而非/tmp/registry

docker run -d -p 5000:5000 --restart=always --name registry \
  -v /etc/docker/certs:/certs \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry.crt \
  -e REGISTRY_HTTP_TLS_KEY=/certs/registry.key \
  -v /data/docker-registry:/var/lib/registry \
  registry:2
  • 使用參數-v將本地磁盤中的/data/docker-registry目錄映射到容器(container)中的/var/lib/registry目錄
  • 使用參數-v將本地磁盤中的/etc/docker/certs目錄映射到容器中的/certs目錄

可用過docker ps命令查看容器運行情況

Testing

以鏡像hello-world為例

  • 獲取遠程鏡像

    docker pull hello-world
    
  • 添加標籤

    docker tag hello-world docker.lempstacker.com:5000/hello-world
    
  • 將新創建的鏡像push到私有倉庫

    docker push docker.lempstacker.com:5000/hello-world
    

以下是操作過程

[flying@lemp ~]$ docker pull hello-world
Using default tag: latest
latest: Pulling from library/hello-world
4276590986f6: Pull complete
a3ed95caeb02: Pull complete
Digest: sha256:a7d7a8c072a36adb60f5dc932dd5caba8831ab53cbf016bcdd6772b3fbe8c362
Status: Downloaded newer image for hello-world:latest

[flying@lemp ~]$ docker tag hello-world docker.lempstacker.com:5000/hello-world

[flying@lemp ~]$ docker run -d -p 5000:5000 --restart=always --name registry \
>   -v /etc/docker/certs:/certs \
>   -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry.crt \
>   -e REGISTRY_HTTP_TLS_KEY=/certs/registry.key \
>   -v /data/docker-registry:/var/lib/registry \
>   registry:2
f3ea6cd5ef2a266538c7936c0dbaeb06d1b639a8bfd15f2296f6992ba69a3d4c

[flying@lemp ~]$ docker push docker.lempstacker.com:5000/hello-world
The push refers to a repository [docker.lempstacker.com:5000/hello-world]
5f70bf18a086: Pushed
33e7801ac047: Pushed
latest: digest: sha256:17372d4bad2fe1355ba3dd9fe5178e2c7ea72c91529c1691e3ab5a75371135b4 size: 708

[flying@lemp ~]$ ls /data/docker-registry/docker/registry/v2/repositories
hello-world

[flying@lemp ~]$ docker rmi docker.lempstacker.com:5000/hello-world
Untagged: docker.lempstacker.com:5000/hello-world:latest

[flying@lemp ~]$ docker images | grep docker.lempstacker.com:5000/hello-world

[flying@lemp ~]$ docker pull docker.lempstacker.com:5000/hello-world
Using default tag: latest
latest: Pulling from hello-world
Digest: sha256:17372d4bad2fe1355ba3dd9fe5178e2c7ea72c91529c1691e3ab5a75371135b4
Status: Downloaded newer image for docker.lempstacker.com:5000/hello-world:latest

[flying@lemp ~]$ docker images | grep docker.lempstacker.com:5000/hello-world
docker.lempstacker.com:5000/hello-world   latest              94df4f0ce8a4        5 weeks ago         967 B
[flying@lemp ~]$

Other Hosts

其餘主機如果想使用該私有倉庫須進行如下操作:

進行如下操作

echo '192.168.0.109 docker.lempstacker.com' >> /etc/hosts

touch /etc/pki/ca-trust/source/anchors/docker.lempstacker.com.crt

將registry主機的/etc/docker/certs/registry.crt中內容複製到該文件中或使用scp

update-ca-trust

其它主機測試過程

[lemp@raxtone ~]$ docker pull docker.lempstacker.com:5000/hello-world
Using default tag: latest
latest: Pulling from hello-world
4276590986f6: Pull complete
a3ed95caeb02: Pull complete
Digest: sha256:17372d4bad2fe1355ba3dd9fe5178e2c7ea72c91529c1691e3ab5a75371135b4
Status: Downloaded newer image for docker.lempstacker.com:5000/hello-world:latest
[lemp@raxtone ~]$ docker run docker.lempstacker.com:5000/hello-world

Hello from Docker.
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker Hub account:
 https://hub.docker.com

For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/

[lemp@raxtone ~]$

Errors

遇到的報錯

  • docker: Error response from daemon: failed to create endpoint registry on network bridge: iptables failed: iptables –wait -t nat -A DOCKER -p tcp -d 0/0 –dport 5000 -j DNAT –to-destination 172.17.0.2:5000 ! -i docker0: iptables: No chain/target/match by that name. (exit status 1). [flying@lemp ~]$ docker run -d -p 5000:5000 --restart=always --name registry \ > -v /etc/docker/certs:/certs \ > -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry.crt \ > -e REGISTRY_HTTP_TLS_KEY=/certs/registry.key \ > -v /data/docker-registry:/var/lib/registry \ > registry:2 0a4712d7a1205f72bd27d0fa83131067b1b69539d057ac53fe0268dbe1847e72 docker: Error response from daemon: failed to create endpoint registry on network bridge: iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 5000 -j DNAT --to-destination 172.17.0.2:5000 ! -i docker0: iptables: No chain/target/match by that name. (exit status 1). [flying@lemp ~]$

解決方案:安裝並啟用iptables

  • x509: certificate signed by unknown authority [root@ptdb/data/docker-registry] #docker push docker.lempstacker.com:5000/hello-world The push refers to a repository [docker.lempstacker.com:5000/hello-world] Get https://docker.lempstacker.com:5000/v1/_ping: x509: certificate signed by unknown authority (possibly because of "crypto/rsa: verification error" while trying to verify candidate authority certificate "docker.lempstacker.com")

References


Change Log

  • 2016.06.06 22:07 Mon Asia/Shanghai
    • 初稿完成

  • Note Time: 2016.06.06 22:07 Mon
  • Note Location: Asia/Shanghai
  • Writer: lempstacker