有時候使用 Docker Hub 這樣的公共倉庫可能不方便,用戶能夠建立一個本地倉庫供私人使用。nginx
本節介紹如何使用本地倉庫。git
docker-registry 是官方提供的工具,能夠用於構建私有的鏡像倉庫。本文內容基於 docker-registry v2.x 版本。docker
安裝運行 docker-registry
容器運行
你能夠經過獲取官方 registry 鏡像來運行。json
$ docker run -d -p 5000:5000 --restart=always --name registry registry
這將使用官方的 registry 鏡像來啓動私有倉庫。默認狀況下,倉庫會被建立在容器的 /var/lib/registry 目錄下。你能夠經過 -v 參數來將鏡像文件存放在本地的指定路徑。例以下面的例子將上傳的鏡像放到本地的 /opt/data/registry 目錄。ubuntu
$ docker run -d \ -p 5000:5000 \ -v /opt/data/registry:/var/lib/registry \ registry
在私有倉庫上傳、搜索、下載鏡像
建立好私有倉庫以後,就可使用 docker tag 來標記一個鏡像,而後推送它到倉庫。例如私有倉庫地址爲 127.0.0.1:5000。centos
先在本機查看已有的鏡像。dom
$ 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。curl
格式爲 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 14.04, Debian 7 Wheezy
對於使用 upstart 的系統而言,編輯 /etc/default/docker 文件,在其中的 DOCKER_OPTS 中增長以下內容:
DOCKER_OPTS="--registry-mirror=https://registry.docker-cn.com --insecure-registries=192.168.199.100:5000"
從新啓動服務。
$ sudo service docker restart
Ubuntu 16.04+, Debian 8+, centos 7
對於使用 systemd 的系統,請在 /etc/docker/daemon.json 中寫入以下內容(若是文件不存在請新建該文件)
{ "registry-mirror": [ "https://registry.docker-cn.com" ], "insecure-registries": [ "192.168.199.100:5000" ] }
注意:該文件必須符合 json 規範,不然 Docker 將不能啓動。
其餘
對於 Docker for Windows 、 Docker for Mac 在設置中編輯 daemon.json 增長和上邊同樣的字符串便可。
上一節咱們搭建了一個具備基礎功能的私有倉庫,本小節咱們來使用 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。
新建 ssl 文件夾並將 docker.domain.com.key docker.domain.com.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
docker.domain.com 127.0.0.1
啓動
$ docker-compose up -d
這樣咱們就搭建好了一個具備權限認證、TLS 的私有倉庫,接下來咱們測試其功能是否正常。
登陸到私有倉庫。
$ docker login docker.domain.com
嘗試推送、拉取鏡像。
$ docker pull ubuntu:17.10 $ docker tag ubuntu:17.10 docker.domain.com/username/ubuntu:17.10 $ docker push docker.domain.com/username/ubuntu:17.10 $ docker image rm docker.domain.com/username/ubuntu:17.10 $ docker pull docker.domain.com/username/ubuntu:17.10
若是咱們退出登陸,嘗試推送鏡像。
$ docker logout docker.domain.com $ docker push docker.domain.com/username/ubuntu:17.10 no basic auth credentials
發現會提示沒有登陸,不能將鏡像推送到私有倉庫中。
注意事項 若是你本機佔用了 443 端口,你能夠配置 Nginx 代理,這裏再也不贅述。