Docker學習筆記六:Docker搭建企業級私有倉庫


前言

Docker不僅是一個強大的服務器部署工具,而且它還有一個官方的Docker Hub registry用於儲存Docker鏡像。上傳鏡像到Docker Hub是免費的,上傳的鏡像文件同時也對公共領域開放,而這可能不是我們想要的。

本文介紹如何配置一個私有的Docker registry,在此上傳的鏡像是私密的,你可以從另一個聯網的主機以安全的方式下載此registry上的鏡像。

本文僅介紹registry的創建,而不討論應用的容器化。有關Docker鏡像創建的操作可參考這篇Docker入門文章。

本文在Ubuntu 14.04上實測通過,在其他Debian類系統上應該也可以通過。使用的Docker Registry版本為2.0版。
Docker基本概念

如果你此前尚未用過Docker,那么最好先花幾分鍾時間了解一下它的基本概念。如果你已經使用過Docker,只想了解建立私有registry部分的內容,則可跳過本小節。

Docker入門者可參閱這篇Docker Cheat Sheet。

Docker的核心理念是應用及其依賴項與其運行環境(操作系統)的分離,這種分離通過容器(containers)和鏡像(images)來實現。一個Docker鏡像本質上來說就是一個文件系統的模板,運行一個Docker鏡像就是在你的系統上的一個Docker容器中運行該文件系統的一個實例。默認來說,該容器是不會接觸到最初的那個鏡像或者Docker運行環境所處的宿主機上的文件系統:該容器是完全獨立的環境。

在容器內部操作進行的變更直接在容器中預存,而不會造成初始鏡像的變更;要保存這些變更,需要通過docker commit指令將變更提交給指定的Docker鏡像。也就是說,從一個舊的容器,你可以不斷的生成新的容器,而舊的那個容器(鏡像)永遠也不會因為意外而被搞砸。該模式對於Git用戶而言應該非常眼熟,這相當於創建新的分支(git branch相當於Docker image),運行一個鏡像相當於做一次git checkout。

運用同樣的類比,一個私有Docker registry就相當於一個私有的git倉庫。
准備工作

完成本教程需要如下准備工作:

    兩台Ubuntu 14.04的雲主機,一台作為私有Docker registry服務器,一台作為Docker客戶端。
    兩台服務器上都建立具有sudo權限的非root用戶(用戶建立教程可參考這篇文章)。
    兩台服務器上都安裝Docker以及Docker Compose(安裝教程見此)。
    為私有Docker registry服務器配置好可供客戶端訪問的域名。

步驟1:安全加固

針對Docker Registry的安全加固,建議使用Docker Compose。如此,我們可以在一個容器內運行Docker Registry,而與外部的通訊安全則交給另一個容器內的Nginx來處理。我們在准備工作中應該已經安裝過Docker Compose。

用Nginx來處理通訊安全,則需要將可訪問私有registry的用戶名和密碼的列表保存到一個文件里以供Nginx讀取。我們將安裝apache2-utils軟件包,該軟件包下的htpasswd可以很方便的生成一個Nginx可讀的密碼哈希:

sudo apt-get -y install apache2-utils

步驟2:安裝配置Docker Registry

如果你只需要管理一兩個Docker容器,那么Docker命令行工具就足夠好了。然而,大部分在容器內運行的應用並非是獨立運作的,他們需要成組配合才能運行。比如,大部分Web應用都至少需要一個Web服務器用於托管應用代碼、一個服務器用於運行PHP/Ruby on Rails等解釋腳本語言、一台數據庫服務器(如MySQL)。

Docker Compose可以讓我們為每一個容器用一個.yml配置文件,該文件不僅可以指定容器的配置項,還可以寫入有關該容器如何對外通訊的信息。docker-compose命令行工具可以對應用的各個組件下達指令。

Docker registry本身也是一個由多個組件組成的應用,因此我們將使用Docker Compose對其進行配置管理。

最簡單的registry配置就是其存儲數據的位置。讓我們先來創建一個最基本的Docker Compose YAML文件。

首先,創建一個目錄,用於儲存本教程將要用到的一些文件:

mkdir ~/docker-registry && cd $_
mkdir data

在該目錄下創建一個docker-compose.yml文件:

nano docker-compose.yml

將如下內容復制粘貼到該文件中:

registry:
  image: registry:2
  ports:
    - 127.0.0.1:5000:5000
  environment:
    REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
  volumes:
    - ./data:/data

注意這部分內容:environment: REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data為Docker registry容器設置了一個環境變量路徑/data,如此,Docker registry在啟動時就會檢查這個環境變量,從而將其數據保存到/data路徑下。

最后的volumes: - ./data:/data這一段的意思是,容器內的/data路徑應該映射到宿主機的./data路徑,也就是說Docker registry的數據都會保存到宿主機的~/docker-registry/data目錄下。

現在啟動Docker Compose:

cd ~/docker-registry
docker-compose up

輸入該命令后,你會看到一系列下載進度條,這些是Docker在從官方Registry下載Docker registry鏡像文件的下載進度。如果一切順利,下載應該在一兩分鍾內完成,最終呈現的輸出應該是這樣的:

registry_1 | time="2015-10-18T23:45:58Z" level=warning msg="No HTTP secret provided - generated random secret. This may cause problems with uploads if multiple registries are behind a load-balancer. To provide a shared secret, fill in http.secret in the configuration file or set the REGISTRY_HTTP_SECRET environment variable." instance.id=44c828de-c27a-401e-bb2e-38b17e6a4b7b version=v2.1.1
registry_1 | time="2015-10-18T23:45:58Z" level=info msg="redis not configured" instance.id=44c828de-c27a-401e-bb2e-38b17e6a4b7b version=v2.1.1
registry_1 | time="2015-10-18T23:45:58Z" level=info msg="using inmemory blob descriptor cache" instance.id=44c828de-c27a-401e-bb2e-38b17e6a4b7b version=v2.1.1
registry_1 | time="2015-10-18T23:45:58Z" level=info msg="listening on [::]:5000" instance.id=44c828de-c27a-401e-bb2e-38b17e6a4b7b version=v2.1.1
registry_1 | time="2015-10-18T23:45:58Z" level=info msg="Starting upload purge in 1m0s" instance.id=44c828de-c27a-401e-bb2e-38b17e6a4b7b version=v2.1.1

里面有一條No HTTP secret provided的警告信息,不用在意它。

至此,你的Docker registry已經在運行,監聽端口為5000(這個端口可以在docker-compose.yml文件中的ports:部分設置)。不過這個registry現在還用處不大:一方面它需要手動啟動,另一方面它還沒設置任何身份驗證機制所以並不安全。

默認狀態下,Docker Compose會一直等待你輸入指令。現在我們直接CTRL-C將其關閉退出。
步驟3:設置Nginx容器

現在來解決安全認證的問題。首先我們需要一個Nginx容器,再把它跟剛才的Docker registry容器連接起來。

創建一個新目錄用於保存Nginx配置項:

mkdir ~/docker-registry/nginx

打開剛才的docker-compose.yml文件:

nano docker-compose.yml

將下面的內容復制粘貼到文件開頭處:

nginx:
  image: "nginx:1.9"
  ports:
    - 5043:443
  links:
    - registry:registry
  volumes:
    - ./nginx/:/etc/nginx/conf.d:ro

這將基於官方Nginx鏡像創建一個新的Docker容器。注意這里的links部分,這個功能可以自動建立兩個容器之間的連接:當Nginx容器啟動時,它將能夠直接使用registry這個主機名訪問registry容器(無論該容器的IP地址為何。其背后的機制其實是在nginx容器里面的/etc/hosts文件把registry容器的IP自動填寫進去)。

volumes:部分跟上面一樣,是容器內外路徑的映射關系。末尾的:ro意思是只讀,即該Nginx容器對宿主機文件系統只有只讀權限。

到目前為止,完整的docker-compose.yml文件應該是這樣的:

nginx:
  image: "nginx:1.9"
  ports:
    - 5043:443
  links:
    - registry:registry
  volumes:
    - ./nginx/:/etc/nginx/conf.d
registry:
  image: registry:2
  ports:
    - 127.0.0.1:5000:5000
  environment:
    REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
  volumes:
    - ./data:/data

現在如果再次運行docker-compose up,將會啟動兩個容器:一個Docker registry和一個Nginx。不過我們需要先配置好Nginx。創建一個新的Nginx配置文件registry.conf:

nano ~/docker-registry/nginx/registry.conf

將如下內容復制粘貼進去:

upstream docker-registry {
  server registry:5000;
}

server {
  listen 443;
  server_name myregistrydomain.com;

  # SSL
  # ssl on;
  # ssl_certificate /etc/nginx/conf.d/domain.crt;
  # ssl_certificate_key /etc/nginx/conf.d/domain.key;

  # disable any limits to avoid HTTP 413 for large image uploads
  client_max_body_size 0;

  # required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486)
  chunked_transfer_encoding on;

  location /v2/ {
    # Do not allow connections from docker 1.5 and earlier
    # docker pre-1.6.0 did not properly set the user agent on ping, catch "Go *" user agents
    if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) {
      return 404;
    }

    # To add basic authentication to v2 use auth_basic setting plus add_header
    # auth_basic "registry.localhost";
    # auth_basic_user_file /etc/nginx/conf.d/registry.password;
    # add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always;

    proxy_pass                          http://docker-registry;
    proxy_set_header  Host              $http_host;   # required for docker client's sake
    proxy_set_header  X-Real-IP         $remote_addr; # pass on real client's IP
    proxy_set_header  X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header  X-Forwarded-Proto $scheme;
    proxy_read_timeout                  900;
  }
}

保存退出。現在可以啟動Docker Compose了:

docker-compose up

Nginx在啟動時沒有輸出信息,不過我們可以用curl來測試一下它是不是已經成功啟動並連接至registry。首先用curl發送HTTP請求給registry:

curl http://localhost:5000/v2/

你應該能看到返回的結果——一個空json對象:

{}

現在再給Nginx端口發送HTTP請求:

curl http://localhost:5043/v2/

你應該看到同樣的返回結果:

{}

如果一切順利,在docker-compose的終端能看到如下的輸出內容:

    registry_1 | time="2015-08-11T10:24:53.746529894Z" level=debug msg="authorizing request" environment=development http.request.host="localhost:5043" http.request.id=55c3e2a6-4f34-4b0b-bc57-11c814b4f4d3 http.request.method=GET http.request.remoteaddr=172.17.42.1 http.request.uri="/v2/" http.request.useragent="curl/7.35.0" instance.id=55634dfc-c9e0-4ec9-9872-6f4930c17759 service=registry version=v2.0.1
    registry_1 | time="2015-08-11T10:24:53.747650205Z" level=info msg="response completed" environment=development http.request.host="localhost:5043" http.request.id=55c3e2a6-4f34-4b0b-bc57-11c814b4f4d3 http.request.method=GET http.request.remoteaddr=172.17.42.1 http.request.uri="/v2/" http.request.useragent="curl/7.35.0" http.response.contenttype="application/json; charset=utf-8" http.response.duration=8.143193ms http.response.status=200 http.response.written=2 instance.id=55634dfc-c9e0-4ec9-9872-6f4930c17759 service=registry version=v2.0.1
    registry_1 | 172.17.0.21 - - [11/Aug/2015:10:24:53 +0000] "GET /v2/ HTTP/1.0" 200 2 "" "curl/7.35.0"
    nginx_1    | 172.17.42.1 - - [11/Aug/2015:10:24:53 +0000] "GET /v2/ HTTP/1.1" 200 2 "-" "curl/7.35.0" "-"

如果你看到registry_這樣的前綴(后面的數字不一定是1),則說明一切正常,Nginx已經成功建立了到Docker registry的代理。

CTRL-C退出,准備進行下一步操作。
步驟4:設置驗證信息

現在我們需要讓Nginx驗證訪問Docker registry的用戶權限。首先我們需要用htpasswd工具創建一個Apache格式的驗證文件(Nginx也可以識別該文件):

cd ~/docker-registry/nginx
htpasswd -c registry.password USERNAME

其中的USERNAME是你自己指定的用戶名。指令輸入后,命令行會請求為該用戶建立一個密碼。

如果以后要添加新用戶,還是一樣使用htpasswd工具,只是不用再輸入-c選項了(c是新建的意思):

htpasswd registry.password USERNAME

現在我們有了一個registry.password文件,里面保存了可以訪問registry的用戶名列表。這個文件是可以隨時查看編輯的。

接下來需要讓Nginx把這個文件用起來。還是打開~/docker-registry/nginx/registry.conf文件:

nano ~/docker-registry/nginx/registry.conf

找到下面這幾行內容:

# To add basic authentication to v2 use auth_basic setting plus add_header
# auth_basic "registry.localhost";
# auth_basic_user_file /etc/nginx/conf.d/registry.password;
# add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always;

將auth_basic和add_header這兩行前面的井號去掉:

# To add basic authentication to v2 use auth_basic setting plus add_header
auth_basic "registry.localhost";
auth_basic_user_file /etc/nginx/conf.d/registry.password;
add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always;

這樣就啟動了HTTP驗證功能。保存退出,來把容器們啟動起來看看:

cd ~/docker-registry
docker-compose up

還是用curl來給Nginx發送請求:

curl http://localhost:5043/v2/

這次的返回結果是一個驗證失敗的頁面:

<html>
<head><title>401 Authorization Required</title></head>
<body bgcolor="white">
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx/1.9.7</center>
</body>
</html>

現在加上用戶名和密碼,再用curl發送一次請求:

curl http://USERNAME:PASSWORD@localhost:5043/v2/

這次,你應該能看到之前的返回結果——空json對象{}。在docker-compose的終端也能夠看到registry_部分的內容。

CTRL-C退出,准備進行下一步。
步驟5:設置SSL

雖然已經有了基本的HTTP驗證,但現在還是不夠安全,因為連接是未加密的。我們需要把SSL啟用起來。還是打開剛才的Nginx配置文件:

nano ~/docker-registry/nginx/registry.conf

找到如下內容:

server {
  listen 443;
  server_name myregistrydomain.com;

  # SSL
  # ssl on;
  # ssl_certificate /etc/nginx/conf.d/domain.crt;
  # ssl_certificate_key /etc/nginx/conf.d/domain.key;

把SSL以下的三行前面的井號刪掉。不要忘了把server_name部分的值改成你的服務器域名:

server {
  listen 443;
  server_name myregistrydomain.com;

  # SSL
  ssl on;
  ssl_certificate /etc/nginx/conf.d/domain.crt;
  ssl_certificate_key /etc/nginx/conf.d/domain.key;

保存退出。Nginx將使用/etc/nginx/conf.d/domain.crt證書以及/etc/nginx/conf.d/domain.key密鑰來提供SSL服務。根據之前的配置,容器內的/etc/nginx/conf.d/路徑是映射到宿主機的~/docker-registry/nginx/路徑下,所以我們需要把證書文件復制到這里。你可以購買證書,也可以獲取一個免費的SSL證書。或者,你也可以使用自簽名的SSL證書。
自簽名的SSL證書

目前為止,Docker還無法正式支持自簽名的SSL證書,所以這個配置起來要麻煩一些——我們需要將宿主機設置為證書的頒發機構。

到~/docker-registry/nginx目錄下,創建一個新的root key:

cd ~/docker-registry/nginx
openssl genrsa -out devdockerCA.key 2048

生成一個root證書(需要填寫國家省市信息之類的,這些可以隨便填):

openssl req -x509 -new -nodes -key devdockerCA.key -days 10000 -out devdockerCA.crt

然后,生成key(這個密鑰就是上面需要用到的ssl_certificate_key):

openssl genrsa -out domain.key 2048

然后,我們需要進行一個證書簽名的請求。

輸入如下命令。輸入之后,OpenSSL會向你提出幾個問題。其他問題怎么回答都好,不過關於"Common Name"這一項,務必要填寫服務器的域名或IP:

openssl req -new -key domain.key -out dev-docker-registry.com.csr

比如,如果你的Docker registry使用的域名是www.ilovedocker.com,則需要這樣填寫:

Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:www.ilovedocker.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

A challenge password []:這里不要填。

然后,我們要給這個證書請求做簽名:

openssl x509 -req -in dev-docker-registry.com.csr -CA devdockerCA.crt -CAkey devdockerCA.key -CAcreateserial -out domain.crt -days 10000

因為我們剛才生成的這些證書沒有被任何權威機構(比如VeriSign)驗證過,因此我們需要用另外的方法告訴所有使用這個Docker registry的客戶端說,這個Docker registry使用的證書是合法的。這個方法就是,在每個Docker客戶端上做如下設置(需要把剛才生成的devdockerCA.crt復制過去):

sudo mkdir /usr/local/share/ca-certificates/docker-dev-cert
sudo cp devdockerCA.crt /usr/local/share/ca-certificates/docker-dev-cert
sudo update-ca-certificates

重啟Docker守護進程以使該證書生效:

sudo service docker restart

詳細配置過程見本文步驟9。上述指令在本機執行可直接生效。
步驟6:測試SSL

現在啟動容器:

cd ~/docker-registry
docker-compose up

再做一次curl,但是用https(這里輸入的域名或IP必須與剛才在證書生成過程中填寫的Common Name部分完全一致):

curl https://USERNAME:PASSWORD@[YOUR-DOMAIN]:5043/v2/

如果剛才用了自簽名證書,你會看到如下問題報告:

curl: (60) SSL certificate problem: self signed certificate

為curl命令加上-k選項可以跳過該驗證:

curl -k https://USERNAME:PASSWORD@[YOUR-DOMAIN]:5043/v2/

如此,應該可以得到空json對象{}的返回結果。docker-compose的終端窗口那邊也會輸出registry_部分內容。否則的話,則需要回去重新檢查SSL設置的步驟。

至此,如果你的防火牆配置允許來自外部的請求訪問5043端口,則你應該可以使用自己的用戶名和密碼通過docker login https://<YOURDOMAIN>登陸到該Docker registry上了。
步驟7:將SSL端口設置為443

443是標准的SSL端口,所以我們要把之前設置的5043改成443。不過在Linux上,1024以下的端口都是“特權”端口,所以docker-compose容器必須以root權限運行才能使用該端口。

打開docker-compose.yml進行編輯:

nano ~/docker-registry/docker-compose.yml

在Nginx部分的ports:段落,原本的內容是- 5043:443,即把宿主機的5043端口映射到Nginx容器的443端口。我們要把它改成- 443:443:

nginx:
  image: "nginx:1.9"
  ports:
    - 443:443
  links:
    - registry:registry
  volumes:
    - ./nginx/:/etc/nginx/conf.d:ro
registry:
  image: registry:2
  ports:
    - 127.0.0.1:5000:5000
  environment:
    REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
  volumes:
    - ./data:/data

CTRL-C退出之前運行的docker-compose(如果之前已經退出就無需進行此操作),然后以sudo權限再次啟動:

sudo docker-compose up

現在docker-compose已經啟動,再次使用curl命令來做一次測試。這次我們在URL中不再指定端口:

curl https://<YOURUSERNAME>:<YOURPASSWORD>@YOUR-DOMAIN/v2/

檢查返回的結果是否為{},docker-compose終端窗口的輸出是否包含registry_。在外部的另一台機器上重復本操作,以確保Docker registry可以從外部訪問。

如果一切正常,CTRL-C退出,准備進行下一步。
步驟8:將Docker Registry啟動為服務

接下來我們創建一個Upstart腳本以使Docker registry在每次系統啟動時一起啟動。

首先我們需要移除之前已經生成的容器,好把整個Docker registry目錄移動到系統通用目錄下,再將其權限更改為root權限:

cd ~/docker-registry
docker-compose rm   # 移除現有的容器
sudo mv ~/docker-registry /docker-registry
sudo chown -R root: /docker-registry

然后創建一個Upstart腳本:

sudo nano /etc/init/docker-registry.conf

將以下內容復制粘貼到文件中(該腳本內容有一些復雜,其說明可參考這篇博文。有關Upstart的用法可參考這篇教程。):

description "Docker Registry"

start on runlevel [2345]
stop on runlevel [016]

respawn
respawn limit 10 5

chdir /docker-registry

exec /usr/local/bin/docker-compose up

現在用如下命令測試一下該Upstart腳本:

sudo service docker-registry start

返回的結果應該是這樣的:

docker-registry start/running, process 25303

使用如下命令檢查Docker服務是否已經在運行:

docker ps

返回的結果應該是這樣的(其中包含dockerregistry_的項目):

CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS                          NAMES
d4b6fef0b4d1        nginx:1.9           "nginx -g 'daemon of   2 minutes ago       Up 2 minutes        80/tcp, 0.0.0.0:443->443/tcp   dockerregistry_nginx_1
77668352bd39        registry:2          "registry cmd/regist   2 minutes ago       Up 2 minutes        127.0.0.1:5000->5000/tcp       dockerregistry_registry_1

Upstart會把docker-compose命令的輸出都錄入到/var/log/upstart/docker-registry.log日志文件中。用tail命令檢查一下這個日志文件(需要使用sudo,因為upstart日志是以root用戶寫入的):

sudo tail -f /var/log/upstart/docker-registry.log

里面應該能看到包含registry_的條目。再從本機的新終端窗口或另一台機器curl到registry服務器上:

curl https://<YOUR_USERNAME>:<YOURPASSWORD>@[YOUR-DOMAIN]/v2/

檢查返回的結果是否為{}。日志文件中應該能看到跟之前一樣的信息:

registry_1 | time="2015-08-12T08:01:12.241887501Z" level=debug msg="authorizing request" environment=development http.request.host=docker.meatflavoredbeer.com http.request.id=e8d69e16-9448-4c48-afd8-57b1f1302742 http.request.method=GET http.request.remoteaddr=106.1.247.4 http.request.uri="/v2/" http.request.useragent="curl/7.37.1" instance.id=14d4727b-fda1-463f-8d0e-181f4c70cb17 service=registry version=v2.0.1
registry_1 | time="2015-08-12T08:01:12.242206499Z" level=info msg="response completed" environment=development http.request.host=docker.meatflavoredbeer.com http.request.id=e8d69e16-9448-4c48-afd8-57b1f1302742 http.request.method=GET http.request.remoteaddr=106.1.247.4 http.request.uri="/v2/" http.request.useragent="curl/7.37.1" http.response.contenttype="application/json; charset=utf-8" http.response.duration=3.359883ms http.response.status=200 http.response.written=2 instance.id=14d4727b-fda1-463f-8d0e-181f4c70cb17 service=registry version=v2.0.1
registry_1 | 172.17.0.4 - - [12/Aug/2015:08:01:12 +0000] "GET /v2/ HTTP/1.0" 200 2 "" "curl/7.37.1"
nginx_1    | 106.1.247.4 - nik [12/Aug/2015:08:01:12 +0000] "GET /v2/ HTTP/1.1" 200 2 "-" "curl/7.37.1" "-"

步驟9:配置需要訪問Docker Registry的客戶端

如步驟5所述,對於使用自簽名SSL證書的情況,所有需要訪問該Docker registry的客戶端都需要添加我們創建的證書。我們需要把~/docker-registry/nginx/devdockerCA.crt這個文件復制到客戶端機器上。

首先在服務器上查看該證書文件:

sudo cat /docker-registry/nginx/devdockerCA.crt

文件內容差不多是這樣的形式:

-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJANiXy7fHSPrmMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTQwOTIxMDYwODE2WhcNNDIwMjA2MDYwODE2WjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAuK4kNFaY3k/0RdKRK1XLj9+IrpR7WW5lrNaFB0OIiItHV9FjyuSWK2mj
ObR1IWJNrVSqWvfZ/CLGay6Lp9DJvBbpT68dhuS5xbVw3bs3ghB24TntDYhHMAc8
GWor/ZQTzjccHUd1SJxt5mGXalNHUharkLd8mv4fAb7Mh/7AFP32W4X+scPE2bVH
OJ1qH8ACo7pSVl1Ohcri6sMp01GoELyykpXu5azhuCnfXLRyuOvQb7llV5WyKhq+
SjcE3c2C+hCCC5g6IzRcMEg336Ktn5su+kK6c0hoD0PR/W0PtwgH4XlNdpVFqMST
vthEG+Hv6xVGGH+nTszN7F9ugVMxewIDAQABo1AwTjAdBgNVHQ4EFgQULek+WVyK
dJk3JIHoI4iVi0FPtdwwHwYDVR0jBBgwFoAULek+WVyKdJk3JIHoI4iVi0FPtdww
DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAkignESZcgr4dBmVZqDwh
YsrKeWSkj+5p9eW5hCHJ5Eg2X8oGTgItuLaLfyFWPS3MYWWMzggxgKMOQM+9o3+k
oH5sUmraNzI3TmAtkqd/8isXzBUV661BbSV0obAgF/ul5v3Tl5uBbCXObC+NUikM
O0C3fDmmeK799AM/hP5CTDehNaFXABGoVRMSlGYe8hZqap/Jm6AaKThV4g6n4F7M
u5wYtI9YDMsxeVW6OP9ZfvpGZW/n/88MSFjMlBjFfFsorfRd6P5WADhdfA6CBECG
LP83r7/MhqO06EOpsv4n2CJ3yoyqIr1L1+6C7Erl2em/jfOb/24y63dj/ATytt2H
6g==
-----END CERTIFICATE-----

把證書內容復制到剪貼板上。

登陸到客戶端機器,創建證書目錄:

sudo mkdir /usr/local/share/ca-certificates/docker-dev-cert

再創建證書文件,使用同樣的文件名devdockerCA.crt:

sudo nano /usr/local/share/ca-certificates/docker-dev-cert/devdockerCA.crt

將剛才復制到剪貼板上的內容粘貼進來。保存退出。再使用cat查看一下新創建的文件,檢查內容是否正確:

cat /usr/local/share/ca-certificates/docker-dev-cert/devdockerCA.crt

確認無誤后,更新證書信息:

sudo update-ca-certificates

返回的結果應該包含1 added信息:

Updating certificates in /etc/ssl/certs... 1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d....done.

重啟Docker以重新加載系統CA證書列表:

sudo service docker restart

現在可以使用如下指令登入Docker registry了:

docker login https://YOUR-DOMAIN

服務器會要求你輸入用戶名、密碼和Email。用戶名和密碼就是剛才在服務器上創建的,Email可以隨便填:

Username: USERNAME
Password: PASSWORD
Email:
Account created. Please see the documentation of the registry http://localhost:5000/v1/ for instructions how to activate it.

如果輸入的信息無誤,應該可以看到登陸成功的信息:

Login Succeeded

步驟10:將本機鏡像發布到Docker Registry

我們先在客戶端上創建一個簡單的鏡像(基於Docker Hub上的ubuntu鏡像。如果本機上已經有鏡像那就可以省去這一步了):

docker run -t -i ubuntu /bin/bash

該指令會下載ubuntu鏡像並運行其中的bash以等待我們給該容器輸入指令,這可能需要一段時間。等等待輸入的指令出現之后,我們來創建一個文件SUCCESS:

touch /SUCCESS

現在可以退出容器了:

exit

將變更后的鏡像提交為test-image:

docker commit $(docker ps -lq) test-image

根據我們上面的操作,這個test-image鏡像與官方ubuntu鏡像相比,只是添加了一個空文件SUCCESS。

現在我們把這個測試鏡像推送到registry。

登陸到registry服務器:

docker login https://YOUR-DOMAIN

輸入用戶名和密碼:

Username: USERNAME
Password: PASSWORD
Email:
Account created. Please see the documentation of the registry http://localhost:5000/v1/ for instructions how to activate it.

現在可以推送剛才的鏡像。根據Docker的設計,我們推送之前,需要給它加一個tag用於標注registry的位置:

docker tag test-image [YOUR-DOMAIN]/test-image

這里需要注意的是,tag中的域名不需要https://,只需要域名、端口、加上鏡像名稱即可。

現在可以推送了:

docker push [YOUR-DOMAIN]/test-image

推送需要一段時間,完成后應該能看到如下內容:

latest: digest: sha256:5ea1cfb425544011a3198757f9c6b283fa209a928caabe56063f85f3402363b4 size: 8008

步驟11:從Docker Registry拉取鏡像

現在測試從另一台機器拉取該鏡像(我們也可以直接在registry服務器上進行本測試)。

登陸到registry服務器:

docker login https://[YOUR-DOMAIN]

使用剛才創建的tag拉取鏡像:

docker pull [YOUR-DOMAIN]/test-image

Docker會下載該鏡像。下載完成后,輸入如下指令運行鏡像以進入到里面:

docker run -t -i [YOUR-DOMAIN]/test-image /bin/bash

看看里面是不是有剛才創建的文件:

ls

應該可以看到SUCCESS文件出現在列表中:

SUCCESS  bin  boot  dev  etc  home  lib  lib64  media   mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

總結

至此,我們已經成功創建了一個私有Docker Registry服務器,並且完成了鏡像的推送和拉取。現在可以盡情的玩弄你的Docker啦!

轉載:http://blog.csdn.net/zstack_org/article/details/53301211?locationNum=12&fps=1


免責聲明!

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



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