Docker Registry v2 + Token Auth Server (Registry v2 認證)實例。

關於Registry

對於registry v1 --> v2中,其中的原理、優化等,這裏再也不作一一介紹。這裏有篇文章我瞄過幾眼應該是比較不錯的介紹文章了:http://dockone.io/article/747 。
nginx

Registry v2 token機制

官方document:https://docs.docker.com/registry/spec/auth/token/

目前docker registry v2 認證分爲如下6個步驟:
git

sg-ipumiT6V-wNu3mFExqVQ.png



1. docker client 嘗試到registry中進行push/pull操做;
2. registry會返回401未認證信息給client(未認證的前提下),同時返回的信息中還包含了到哪裏去認證的信息;
3. client發送認證請求到認證服務器(authorization service);
4. 認證服務器(authorization service)返回token;
5. client攜帶這附有token的請求,嘗試請求registry;
6. registry接受了認證的token而且使得client繼續操做;

github

而後咱們來詳細分解、討論下以上的6個步驟

Step #1 , Client 向registry 發起鏈接

一般,Docker Client在進行pull/push操做時,會先嚐試鏈接docker registry。
Note: 當你訪問遠程的registry時,會用到tls驗證域名的有效性(證書),不然會出現以下錯誤:
docker

FATA[0000] Error response from daemon: v1 ping attempt failed with error:
Get https://registry.example.com/v1/_ping: tls: oversized record received with length 20527. 
If this private registry supports only HTTP or HTTPS with an unknown CA certificate,please add 
`--insecure-registry registry.example.com` to the daemon's arguments.
In the case of HTTPS, if you have access to the registry's CA certificate, no need for the flag;
simply place the CA certificate at /etc/docker/certs.d/registry.example.com/ca.crt


在docker的啓動中加入下面的命令,來忽略對registry域名證書的審覈:
json

--insecure-registry registry.example.com


Step #2 , 未認證響應(Unauthorized response)

Registry server會返回401而且會附帶Authentication endpoint:
ubuntu

$ curl https://registry.example.com/v2 -k -IL
HTTP/1.1 301 Moved Permanently
Server: nginx/1.4.7
Date: Sun, 22 Nov 2015 09:01:42 GMT
Content-Type: text/plain; charset=utf-8
Connection: keep-alive
Docker-Distribution-Api-Version: registry/2.0
Location: /v2/

HTTP/1.1 401 Unauthorized
Server: nginx/1.4.7
Date: Sun, 22 Nov 2015 09:01:42 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 87
Connection: keep-alive
Docker-Distribution-Api-Version: registry/2.0
Www-Authenticate: Bearer realm="https://registry.example.com:5001/auth",service="Docker registry"
X-Content-Type-Options: nosniff


Authentication server返回的頭信息中包含了如何去或許token,它有幾個重要的查詢參數:
bash

realm: #### 描述了認證的enpoint。

realm="https://registry.example.com:5001/auth"


service: #### 描述了持有資源服務器的名稱。

service="Docker registry"


scope: #### 描述了client端操做資源的方法(push/pull)

scope="repository:shuyun/hello:push"


account: #### 描述了操做的帳號

account=admin


Step #3&4 , 認證endpoint通信

這2步描述了client與認證服務2者的驗證過程
須要明確的是,你須要知道:client發送請求到認證服務器簽署token,請求信息中包含的基自己份驗證信息將於服務器中的用戶列表作匹配,而後根據請求中的scope要操做的範圍、方法進而進行匹配,最後服務器匹配成功後將token進行簽名,而且將token返回給客戶端。
服務器

Step #5&6 , 最後溝通

Client嘗試與registry鏈接(此次帶了token信息),registry接到請求後驗證token,繼而開始pull/push操做。

markdown

開始搭建registry v2 與認證服務器

系統環境:Cent OS 7.0
Registry: registry:2.2.0
Auth Server:cesanta/docker_auth ,能夠基於本地、LDAP、Google Sign-In。
這裏我建立了2個目錄結構(他們都是基於/data目錄而論的)
app

auth_server/
├── config
│   └── auth_config.yml
└── ssl
├── server.key
└── server.pem
docker_registry/
└── data/


證書建立過程省略。。。

啓動 Auth Server

docker run -d --name docker_auth -p 5001:5001 -v /data/auth_server/config:/config:ro -v /var/log/docker_auth:/logs --restart=always -v /data/auth_server/ssl:/ssl cesanta/docker_auth /config/auth_config.yml


auth_config.yml 內容以下:

server:  # Server settings.
# Address to listen on.
addr: ":5001"
# TLS certificate and key.
certificate: "/ssl/server.pem"
key: "/ssl/server.key"

token:  # Settings for the tokens.
issuer: "Auth Service"  # 須要和 Registry config 匹配。
expiration: 900Static user map.users:
# Password is specified as a BCrypt hash. Use htpasswd -B to generate. Apache版本須要2.4以上
"admin":
password: "xxx"
"hussein":
password: "xxx"
"": {}  # Allow anonymous (no "docker login") access.

acl:
# Admin has full access to everything.
- match: {account: "admin"}
actions: ["*"]
# User "test" has full access to ubuntu p_w_picpath but nothing else.
- match: {account: "hussien", name: "ubuntu"}
actions: ["*"]
- match: {account: "test"}
actions: []
# All logged in users can pull all p_w_picpaths.
- match: {account: "/.+/"}
actions: ["pull"]
# Anonymous users can pull "hello-world".
- match: {account: "", name: "hello-world"}
actions: ["pull"]
# Access is denied by default.


更多的配置信息,能夠參考他們的github

啓動 Registry Server

因爲要配置Registry到Auth Server中認證,因此須要設置一些例如"REGISTRY_variable"的環境變量。例如這樣:

auth:
token:
issuer: "Auth Service"


須要設置成這樣:

REGISTRY_AUTH_TOKEN_ISSUER="Auth Service"


因此配置token認證,須要配置的信息大體以下:

$ docker run -d -p 5000:5000 \
-e REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY=/var/lib/registry \
-e REGISTRY_AUTH=token \
-e REGISTRY_AUTH_TOKEN_REALM=https://registry.example.com:5001/auth \
-e REGISTRY_AUTH_TOKEN_SERVICE="Docker registry" \
-e REGISTRY_AUTH_TOKEN_ISSUER="Auth Service" \
-e REGISTRY_AUTH_TOKEN_ROOTCERTBUNDLE=/ssl/server.pem \
-v /root/auth_server/ssl:/ssl \
-v /root/docker_registry/data:/var/lib/registry \
--restart=always \
--name registry registry:2


最後,啓動起來,進行相應的調試~過程忽略。

使用 Docker Compose

dockerauth:
p_w_picpath: cesanta/docker_auth
ports:
- "5001:5001"
volumes:
- /data/auth_server/config:/config:ro
- /var/log/docker_auth:/logs
- /data/auth_server/ssl:/ssl
command: /config/auth_config.yml
restart: always

registry:
p_w_picpath: registry:2.2.0
ports:
- "5000:5000"
volumes:
- /data/auth_server/ssl:/ssl
- /data/docker_registry/data:/var/lib/registry
restart: always
environment:
- REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY=/var/lib/registry
- REGISTRY_AUTH=token
- REGISTRY_AUTH_TOKEN_REALM=https://registry.example.com:5001/auth
- REGISTRY_AUTH_TOKEN_SERVICE="Docker registry"
- REGISTRY_AUTH_TOKEN_ISSUER="Auth Service"
- REGISTRY_AUTH_TOKEN_ROOTCERTBUNDLE=/ssl/server.pem


而後 # docker-compose up 啓動
測試過程暫時忽略,markdown格式寫真心有點彆扭。。

Note:

這款Auth Server是沒有UI界面的,暫時我也沒有找到很好的UI支撐。
另外有一款搭建在SUSE上的UI+Auth系統,暫時沒有測試,附上連接: https://github.com/SUSE/Portus

相關連接:
https://the.binbashtheory.com/ ... vice/
https://hub.docker.com/r/cesanta/docker_auth/
https://github.com/cesanta/docker_auth

相關文章
相關標籤/搜索