部署 Docker registry Https 服务,以及做 Token 权限验证
目录
[TOC]
* 在本地运行 Registry
* 复制一个镜像到你的 Registry
* 停止运行的 Registry
* 存储定制
* 设置外部访问
* 限制访问
* 基本验证
* 使用 Auth Server 进行验证
* 参考文章
在部署 Registry
之前,需要在主机上安装 Docker
。
registry
是使用的 registry image 镜像,并在 Docker
中运行。
在本地运行 Registry
使用如下命令启动 Registry
容器:
[root@c0 ~]# docker run -d -p 80:80 --restart=always --name registry idoall/registry:2.7.1
浏览 http://localhost/v2 可以看到效果:
[root@c0 ~]# curl localhost/v2/_catalog
{"repositories":[]}
上面的示例显示了仅适用于测试的
Registry
配置。
生产环境中的Registry
必须受TLS
保护,理想情况下应使用访问控制机制。
复制一个镜像到你的 Registry
拉取 alpine
镜像
[root@c0 ~]# docker pull idoall/alpine:3.9.3
重新命名镜像的 Tag
标记为 localhost/alpine:3.9.3
。
这会为现有图像创建一个附加标记。
标记的第一部分是主机名和端口,Docker
在推送时将其解释为 Registry
的位置。
[root@c0 ~]# docker tag idoall/alpine:3.9.3 localhost/alpine:3.9.3
Push
到本地的 Registry
localhost:
[root@c0 ~]# docker push localhost/alpine:3.9.3
通过下面的命令,能够看到 alpine
已经提交到本地的 Registry
中
[root@c0 ~]# curl localhost/v2/_catalog
{"repositories":["alpine"]}
移除本地的 localhost/alpine:3.9.3
和 idoall/alpine:3.9.3
镜像,然后尝试从本地的 Registry 拉取 localhost/alpine:3.9.3
[root@c0 ~]# docker image remove localhost/alpine:3.9.3
[root@c0 ~]# docker image remove idoall/alpine:3.9.3
[root@c0 ~]# docker pull localhost/alpine:3.9.3
停止运行的 Registry
可以使用 docker container stop
命令,来停止运行中的容器
[root@c0 ~]# docker container stop registry
删除容器,可以使用 docker container rm
[root@c0 ~]# docker container stop registry && docker container rm -v registry
存储定制
如果要将 Registry
内容存储在系统上的特定位置,以下示例将主机目录 /root/registry/data
绑定到Registry
容器的 / var/lib/registry/
目录。
[root@c0 ~]# docker run -d \
-p 80:80 \
--restart=always \
--name registry \
-v /root/registry/data:/var/lib/registry \
idoall/registry:2.7.1
设置外部访问
运行仅在 localhost 上可访问的 Registry
用途有限。
为了使您的 Registry
可供外部访问,您必须首先使用 TLS
保护。
创建 certs
目录,将 registry.mshk.top.pem
和 registry.mshk.top.key
文件复制到 certs
目录中。
[root@c0 ~]# mkdir -p mshk.top.registry/certs
文章中用到的域名证书,可以去阿里云申请免费1年的版本。
停止当前运行的容器
[root@c0 ~]# docker container stop registry
重新启动 Registry
,指示它使用 TLS
证书。
此命令将 /root/mshk.top.registry/certs
目录绑定到 /certs/
的容器中,并设置环境变量,告诉容器在哪里可以找到 registry.mshk.top.pem
和 registry.mshk.top.key
文件。
Registry
在端口443(默认HTTPS端口)上运行。
[root@c0 ~]# docker run -d \
-p 80:80 \
--restart=always \
--name registry \
-v /root/mshk.top.registry/certs:/certs \
-e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry.mshk.top.pem \
-e REGISTRY_HTTP_TLS_KEY=/certs/registry.mshk.top.key \
-p 443:443 \
idoall/registry:2.7.1
Docker
客户端现在可以从外部地址 ,访问您 Registry
中的镜像,进行 push
或 pull
以下命令演示了这一点
[root@c0 ~]# docker tag idoall/alpine:3.9.3 registry.mshk.top/alpine:3.9.3
[root@c0 ~]# docker push registry.mshk.top/alpine:3.9.3
The push refers to repository [registry.mshk.top/alpine]
4545836b8bdc: Layer already exists
a464c54f93a9: Layer already exists
3.9.3: digest: sha256:09d77b37f3091a2cd648f21fd64b9c8207bb4bf4ad0425bbe3a33e70e35dc819 size: 739
[root@c0 ~]# docker pull registry.mshk.top/alpine:3.9.3
3.9.3: Pulling from alpine
Digest: sha256:09d77b37f3091a2cd648f21fd64b9c8207bb4bf4ad0425bbe3a33e70e35dc819
Status: Image is up to date for registry.mshk.top/alpine:3.9.3
限制访问
基本验证
实现访问限制的最简单方法是通过基本身份验证(这与其他Web服务器的基本身份验证机制非常相似)。
此示例使用 htpasswd
使用本机基本身份验证来存储机密。
不能将身份验证用于以明文形式发送凭据的身份验证方案。
您必须首先配置TLS
才能进行身份验证。
创建一个用户 testuser
密码是 testpassword
[root@c0 ~]# mkdir -p /root/mshk.top.registry/auth
[root@c0 ~]# docker run \
--entrypoint htpasswd \
idoall/registry:2.7.1 -Bbn testuser testpassword > /root/mshk.top.registry/auth/htpasswd
停止容器
[root@c0 ~]# docker container stop registry
使用基本身份验证启动 Registry
[root@c0 ~]# docker run -d \
-p 80:80 \
--restart=always \
--name registry \
-v /root/mshk.top.registry/auth:/auth \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
-v /root/mshk.top.registry/certs:/certs \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry.mshk.top.pem \
-e REGISTRY_HTTP_TLS_KEY=/certs/registry.mshk.top.key \
idoall/registry:2.7.1
这时尝试从 Registry
中提取图像,或将图像推送到 Registry
,都交会失败。
使用我们刚才设置的用户 testuser
密码 testpassword
登录到 Registry
后,现在可以从 Registry
中 Push
或 Pull
[root@c0 ~]# docker login registry.mshk.top
使用 Auth Server 进行验证
Docker Registry V2 认证的流程如下:
Auth Server
我们使用 Docker
镜像 cesanta/docker_auth
.
接下来我们创建一个 cesanta/docker_auth
容器的配置文件 config.yml
,内容如下:
server: # Server settings.
# Address to listen on.
addr: ":5001"
# TLS certificate and key.
certificate: "/certs/myregistry_auth.mshk.top.pem"
key: "/certs/myregistry_auth.mshk.top.key"
token: # Settings for the tokens.
issuer: "Auth Service" # Must match issuer in the Registry config.
expiration: 900
# Static user map.
users:
# 使用基本验证中的 htpasswd 创建的密码
"admin":
password: "$2y$05$RLe09.ii3ah1pKBzNdN7pO6xj4UteelVzsyR2ksuEtbffOBCwYKzi"
"ubuntu":
password: "$2y$05$dG0p/JJl0O.X/E41JY4q6.l1a4q9j8FdadRGta3qOV5kCmEOuMmni"
"read":
password: "$2y$05$/IX9B3OABna4y9fJTTWPOuBm8ikI4JXgKK8RaSet/Lqh6kY6NUgqm"
"": {} # Allow anonymous (no "docker login") access.
acl:
# admin 可以做所有事情.
- match: {account: "admin"}
actions: ["*"]
# ubuntu 用户只可以操作 ubuntu
- match: {account: "ubuntu", name: "ubuntu"}
actions: ["*"]
# All logged in users can pull all images.
- match: {account: "/.+/"}
actions: ["pull"]
# Anonymous users can pull "hello-world".
- match: {account: "", name: "hello-world"}
actions: ["pull"]
# Access is denied by default.
使用 Auth Sever 验证需要启动2个容器,所以我们使用 docker-compose
工具来启动容器,下面是 docker-compose.yml
的内容:
version: '2'
# https://github.com/docker/docker.github.io/blob/master/compose/compose-file/compose-file-v2.md
services:
mshk.top.registryauth:
image: "cesanta/docker_auth:stable"
hostname: mshk.top.registryauth
container_name: mshk.top.registryauth
volumes:
- /root/mshk.top.registryauth/registry-auth.yml:/registry-auth.yml
- /root/mshk.top.registryauth/certs:/certs
command: /registry-auth.yml
ports:
- "5001:5001"
restart: always
mshk.top.registry::
image: "idoall/registry:2.7.1"
hostname: mshk.top.registry:
container_name: mshk.top.registry:
volumes:
- /root/mshk.top.registry/data:/var/lib/registry
- /root/mshk.top.registry/certs:/certs
environment:
- REGISTRY_HTTP_ADDR=0.0.0.0:443
- REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry.mshk.top.pem
- REGISTRY_HTTP_TLS_KEY=/certs/registry.mshk.top.key
- REGISTRY_AUTH_TOKEN_REALM=https://registryauth.mshk.top:5001/auth
- REGISTRY_AUTH_TOKEN_SERVICE="Docker registry"
- REGISTRY_AUTH_TOKEN_ISSUER="Auth Service"
- REGISTRY_AUTH_TOKEN_ROOTCERTBUNDLE=/certs/registryauth.mshk.top.pem
links:
- "mshk.top.registryauth:registryauth"
ports:
- "80:80"
- "443:443"
depends_on:
- mshk.top.registryauth
restart: always
REGISTRY_AUTH_TOKEN_REALM
验证的 URL
REGISTRY_AUTH_TOKEN_SERVICE
服务名称
REGISTRY_AUTH_TOKEN_ISSUER
证书的颁发者,必须要和 Auth Server 的配置文件中一对和
REGISTRY_AUTH_TOKEN_ROOTCERTBUNDLE
是在 Auth Server 用于签 Token 的证书
通过 docker-compose up -d
启动容器后,我们获取 hello-world
镜像,Push
后会提示拒绝访问,因为在权限设置中,我们只允许匿名用户 Pull hello-world
镜像。
[root@c0 ~]# docker pull hello-world
Using default tag: latest
latest: Pulling from library/hello-world
1b930d010525: Pull complete
Digest: sha256:92695bc579f31df7a63da6922075d0666e565ceccad16b59c3374d2cf4e8e50e
Status: Downloaded newer image for hello-world:latest
[root@c0 ~]# docker tag hello-world registry.mshk.top/hello-world
[root@c0 ~]# docker push registry.mshk.top/hello-world
The push refers to repository [registry.mshk.top/hello-world]
af0b15c8625b: Preparing
denied: requested access to the resource is denied
再次使用 admin
帐号登录,然后重新 Push
会看到 Push
成功的信息。
[root@c0 ~]# docker login registry.mshk.top
Username: admin
Password:
Login Succeeded
[root@c0 ~]# docker push registry.mshk.top/hello-world
The push refers to repository [registry.mshk.top/hello-world]
af0b15c8625b: Pushed
latest: digest: sha256:92c7f9c92844bbbb5d0a101b22f7c2a7949e40f8ea90c8b3bc396879d95e899a size: 524
参考文章
Docker Registry v2 + Token Auth Server (Registry v2 认证)实例
Creating Private Docker Registry 2.0 with Token Authentication Service
希望本文对您有帮助,感谢您的支持和阅读我的博客。
博文作者:迦壹
博客地址:部署 Docker registry Https 服务,以及做 Token 权限验证
转载声明:可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明,谢谢合作!