前言html
最近開始研究 Docker 的應用,因而打算 搭建一個私有的 Docker 倉庫,並使用阿里雲的 OSS 做爲存儲引擎 。從網上搜索到的資料大都是比較舊的,新版本的 Registry 服務與舊版本的差異比較大,瞎折騰了一天,踩坑無數。忽然有感, 網上的過期資料(或者說得不清不楚的)真是坑死人不償命 ,仍是得把這兩天摸索出來的門道記錄下來,一是好讓本身過一段時間後再部署 Docker 倉庫時不用重踩一次坑,二來也順便給後來者提個醒。linux
系統環境nginx
客戶端 docker 版本git
docker version
Client:
Version: 1.9.1
API version: 1.21
Go version: go1.4.3
Git commit: a34a1d5
Built: Fri Nov 20 17:56:04 UTC 2015
OS/Arch: darwin/amd64github
Server:
Version: 1.9.1
API version: 1.21
Go version: go1.4.3
Git commit: a34a1d5
Built: Fri Nov 20 17:56:04 UTC 2015
OS/Arch: linux/amd64
服務器端 docker 版本redis
Boot2Docker version 1.9.1, build master : cef800b - Fri Nov 20 19:33:59 UTC 2015
Docker version 1.9.1, build a34a1d5
客戶端 docker-compose 版本docker
docker-compose version 1.5.2, build 7240ff3
docker-py version: 1.5.0
CPython version: 2.7.9
OpenSSL version: OpenSSL 1.0.1j 15 Oct 2014
若是系統沒有docker-compose命令,能夠執行如下命令安裝:ubuntu
$ curl -L https://github.com/docker/com...uname -s
-uname -m
> /usr/local/bin/docker-compose
$ chmod +x /usr/local/bin/docker-compose
啓動 Registry 服務api
安裝服務器
爲了發揮 Docker 容器技術的優點,咱們直接使用 Docker 鏡像來部署服務。
首先在 服務器端 新建工做目錄並進入該目錄:
$ mkdir my_registry && cd my_registry
在當前目錄下新建文件docker-compose.yml:
registry:
restart: always
image: "registry:2"
ports:
- 127.0.0.1:5000:5000
volumes:
- ./auth:/auth - ./data:/var/lib/registry
environment:
- REGISTRY_AUTH=htpasswd - REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm - REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd
在啓動 Registry 服務時,須要用到如下兩個目錄:
auth目錄用於存放docker login時的帳號和密碼
data目錄用於存放docker push時上傳上來的文件
執行如下命令新建這兩個目錄:
$ mkdir auth && mkdir data
接着,建立一個測試帳號(用戶名:test,密碼:123456)並保存到auth/htpasswd中:
$ htpasswd -Bbn test 123456 > auth/htpasswd
如今咱們來啓動 Registry 服務:
$ docker-compose up -d
因爲本地沒有名爲registry:2的鏡像,控制檯可能會打印出以下信息而後暫停一陣:
Pulling registry (registry:2)...
稍等一兩分鐘,能夠看到控制檯打印出以下信息則說明已經啓動成功了:
Creating dockertest_registry_1
Attaching to dockertest_registry_1
registry_1 | time="2016-01-13T21:57:14Z" 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." go.version=go1.5.2 instance.id=25aa4d1d-0510-4cb6-9006-1083bff5fc15 version=v2.2.1
registry_1 | time="2016-01-13T21:57:14Z" level=info msg="redis not configured" go.version=go1.5.2 instance.id=25aa4d1d-0510-4cb6-9006-1083bff5fc15 version=v2.2.1
registry_1 | time="2016-01-13T21:57:14Z" level=info msg="using inmemory blob descriptor cache" go.version=go1.5.2 instance.id=25aa4d1d-0510-4cb6-9006-1083bff5fc15 version=v2.2.1
registry_1 | time="2016-01-13T21:57:14Z" level=info msg="Starting upload purge in 11m0s" go.version=go1.5.2 instance.id=25aa4d1d-0510-4cb6-9006-1083bff5fc15 version=v2.2.1
registry_1 | time="2016-01-13T21:57:14Z" level=info msg="listening on [::]:5000" go.version=go1.5.2 instance.id=25aa4d1d-0510-4cb6-9006-1083bff5fc15 version=v2.2.1
測試
如今再打開一個命令行窗口,並進入my_registry目錄。
執行如下命令建立一個新鏡像:
$ docker tag registry:2 127.0.0.1:5000/test/registry
說明:鏡像名爲127.0.0.1:5000/test/registry,其中127.0.0.1:5000表示服務器地址,test/registry表示鏡像名。
上傳以前要先登陸:
$ docker login 127.0.0.1:5000
說明:按提示輸入上文建立的用戶名和密碼,郵箱能夠不用填寫。
登錄成功後,執行如下命令便可上傳:
$ docker push 127.0.0.1:5000/test/registry
配置阿里雲 OSS
首先在剛纔執行docker-compose up的命令行窗口中按CTRL + C退出服務。
將文件docker-compose.yml改成如下內容:
registry:
restart: always
image: "registry:2"
ports:
- 127.0.0.1:5000:5000
volumes:
- ./auth:/auth
environment:
- REGISTRY_AUTH=htpasswd - REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm - REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd - REGISTRY_STORAGE=oss - REGISTRY_STORAGE_OSS_ACCESSKEYID=your_oss_accesskey_id - REGISTRY_STORAGE_OSS_ACCESSKEYSECRET=your_oss_accesskey_secret - REGISTRY_STORAGE_OSS_REGION=your_oss_region - REGISTRY_STORAGE_OSS_BUCKET=your_oss_bucket - REGISTRY_STORAGE_OSS_ENDPOINT=your_oss_bucket.your_oss_region.aliyuncs.com
說明:因爲使用阿里雲 OSS 做爲存儲引擎,因此不須要再將文件存儲到本地,所以將volumes中的data目錄配置去掉;environment新增了REGISTRY_STORAGE系列的環境變量配置,須要將該部分的值替換爲對應的accesskey_id、accesskey_secret、region、bucket和endpoint等信息。
刪除data目錄並從新啓動服務:
$ rm -Rf data && docker-compose up
再執行剛纔的命令上傳鏡像:
$ docker push 127.0.0.1:5000/test/registry
能夠感受到此次的上傳速度沒有第一次的快,由於它還須要上傳到阿里雲 OSS。待上傳完畢,能夠打開阿里雲 OSS 的控制檯界面檢查文件是否被正確上傳上去了。
配置 SSL 證書
若是咱們要在客戶端(不是在服務器端測試)pull或push鏡像時,docker使用的是https協議,所以會報unable to ping registry endpoint錯誤:
The push refers to a repository [registry.example.com:5000/test] (len: 1)
unable to ping registry endpoint https://registry.example.com:...
v2 ping attempt failed with error: Get https://registry.example.com:... dial tcp registry.example.com:5000: i/o timeout
v1 ping attempt failed with error: Get https://registry.example.com:... dial tcp 199.99.99.9:9000: i/o timeout
因此必需要配置 SSL 證書。
安裝
首先須要準備證書文件,分別保存到auth/domain.crt和auth/domain.key中。
新建 Nginx 的配置文件auth/nginx.conf:
upstream docker-registry {
server registry:5000;
}
map $upstream_http_docker_distribution_api_version $docker_distribution_api_version {
'registry/2.0' '';
default registry/2.0;
}
server {
listen 443 ssl;
server_name myregistrydomain.com;
# SSL
ssl_certificate /etc/nginx/conf.d/domain.crt;
ssl_certificate_key /etc/nginx/conf.d/domain.key;
# Recommendations from https://raymii.org/s/tutorial...
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
# 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/doc...
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. auth_basic "Registry realm"; auth_basic_user_file /etc/nginx/conf.d/nginx.htpasswd; ## If $docker_distribution_api_version is empty, the header will not be added. ## See the map directive above where this variable is defined. add_header 'Docker-Distribution-Api-Version' $docker_distribution_api_version 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.yml改成以下內容:
nginx:
image: "nginx:1.9"
ports:
- 443:443
links:
- registry:registry
volumes:
- ./auth/:/etc/nginx/conf.d
registry:
restart: always
image: "registry:2"
ports:
- 127.0.0.1:5000:5000
environment:
- REGISTRY_STORAGE=oss - REGISTRY_STORAGE_OSS_ACCESSKEYID=your_oss_accesskey_id - REGISTRY_STORAGE_OSS_ACCESSKEYSECRET=your_oss_accesskey_secret - REGISTRY_STORAGE_OSS_REGION=your_oss_region - REGISTRY_STORAGE_OSS_BUCKET=your_oss_bucket - REGISTRY_STORAGE_OSS_ENDPOINT=your_oss_bucket.your_oss_region.aliyuncs.com
說明:刪除registry項目的environment中REGISTRY_AUTH開頭的變量以及volumes項,由於auth認證已經在 Nginx 中配置了。
執行如下命令啓動服務:
$ docker-compose up
說明:若是本地不存在名爲nginx:1.9的鏡像,控制檯可能會打印出Pulling nginx (nginx:1.9)...並先下載該鏡像。
測試
假設剛纔配置的證書域名爲docker.ucdok.com,如今咱們 在客戶端執行如下命令 登陸:
$ docker login docker.ucdok.com
生成新的鏡像:
$ docker pull ubuntu
$ docker tag ubuntu docker.ucdok.com/test/ubuntu
上傳新的鏡像:
$ docker push docker.ucdok.com/test/ubuntu
其餘問題
增長用戶
能夠執行htpasswd命令來建立,並將其保存到auth/htpasswd文件中:
$ htpasswd -Bbn username password >> auth/htpasswd
在後臺啓動服務
啓動服務時增長-d參數:
$ docker-compose up -d
中止後臺服務
在docker-compose.yml文件所在目錄執行如下命令:
$ docker-compose stop