Docker-(5)docker的仓库 (公有,私有仓库)及用户的认证加密详解

一、仓库是什么

仓库(Repository)就是存放镜像的地方。类似于 Node 的 npm; Python 的 PyPi。

注册服务器(Registry)的概念比较容易与仓库混淆。实际上注册服务器是用来管理仓库的服务器,一个服务器上可以存在多个仓库,而每个仓库下可以有多个镜像。

例如对于仓库地址 hub.dockerpool.com/nginx 来说,hub.dockerpool.com 是注册服务器的地址,nginx 是仓库名。

二、Docker registry工作原理

一次docker pull 或 push背后发生的事情
在这里插入图片描述

index服务主要提供镜像索引以及用户认证的功能。当下载一个镜像的时候,首先会去index服务上做认证,然后查找镜像所在的registry的地址并放回给docker客户端,docker客户端再从registry下载镜像,在下载过程中registry会去index校验客户端token的合法性,不同镜像可以保存在不同的registry服务上,其索引信息都放在index服务上。

Docker Registry有三个角色,分别是index、registry和registry client。

  • index

负责并维护有关用户帐户、镜像的校验以及公共命名空间的信息。
Web UI
元数据存储
认证服务
符号化

  • registry

是镜像和图表的仓库,它不具有本地数据库以及不提供用户认证,通过Index Auth service的Token的方式进行认证。

  • Registry Client

Docker充当registry客户端来维护推送和拉取,以及客户端的授权。

接下来介绍几个情景:

情景A:用户要获取并下载镜像。

在这里插入图片描述

情景A:具体工作流程如下:

用户发送请求到index来下载镜像。
index 响应返回三个相关部分信息:
该镜像位于的registry
该镜像包括所有层的校验
以授权目的Token
用户通过响应中返回的Token和registry沟通,registry全权负责镜像,它存
储基本的镜像和继承的层。
registry现在要与index证实该token是被授权的。
index会发送“true” 或者 “false”给registry,由此允许用户下载所需要的镜像。

情景B:用户要推送镜像到registry中。

在这里插入图片描述

情景B:具体工作流程如下:

用户发送带证书请求到index要求分配库名。
在成功认证,命名空间可用以及库名被分配之后。index响应返回临时的token。
镜像连带token,一起被推送到registry中。
registry与index证实token,然后在index验证之后开始读取推送流。
该index然后更新由Docker生成的镜像校验。

情景C:用户要从index或registry中删除镜像。

在这里插入图片描述

情景C:具体工作流程如下:

    index接收来自Docker一个删除库的信号。
    如果index验证库成功,它将删除该库,并返回一个临时token。
    registry现在接收到带有该token的删除信号。
    registry与index核实该token,然后删除库以及所有相关信息。
    Docker现在通知有关删除的index,然后index移除库的所有记录

三、Docker Hub

目前 Docker 官方维护的一个公共仓库,大部分需求我们都可以从 Docker Hub 中直接下载镜像来实现。

注册

我们可以在 https://hub.docker.com/ 注册一个 Docker 账号。

登录

可以通过 docker login 命令在终端输入用户名及密码来完成 Docker Hub 的登录。

我们也可以通过 docker logout 退出登录。

镜像分类

通过上一篇文章可以知道,使用 docker search 搜索镜像时,搜索出来可以看到下面的镜像列表。

[root@server1 ~]# docker search nginx
NAME                              DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
nginx                             Official build of Nginx.                        12036               [OK]
jwilder/nginx-proxy               Automated Nginx reverse proxy for docker con…   1671                                    [OK]
richarvey/nginx-php-fpm           Container running Nginx + PHP-FPM capable of…   742                                     [OK]
linuxserver/nginx                 An Nginx container, brought to you by LinuxS…   78
bitnami/nginx                     Bitnami nginx Docker Image                      71                                      [OK]
tiangolo/nginx-rtmp               Docker image with Nginx using the nginx-rtmp…   56                                      [OK]
nginxdemos/hello                  NGINX webserver that serves a simple page co…   28                                      [OK]
jlesage/nginx-proxy-manager       Docker container for Nginx Proxy Manager        24                                      [OK]
jc21/nginx-proxy-manager          Docker container for managing Nginx proxy ho…   24
nginx/nginx-ingress               NGINX Ingress Controller for Kubernetes         22
privatebin/nginx-fpm-alpine       PrivateBin running on an Nginx, php-fpm & Al…   18                                      [OK]
schmunk42/nginx-redirect          A very simple container to redirect HTTP tra…   17                                      [OK]
blacklabelops/nginx               Dockerized Nginx Reverse Proxy Server.          12                                      [OK]

根据是否是官方提供,可以将镜像分为两类。

一类是类似 nginx 这样的镜像,被称为基础镜像或跟镜像。这些基础镜像由 Docker 公司创建、验证、支持、提供。这样的镜像往往使用单个单词作为名字

还有一种类型,比如 cl82/nginx 镜像,它是由 Docker Hub 的注册用户创建并维护的,往往带有用户名称前缀。可以通过前缀 username/ 来指定使用某个用户提供的镜像,比如 feiben 用户。

推送镜像

用户登录后可以通过 docker push 命令来把自己的镜像推送到 Docker Hub,例如将 nginx 镜像改成我们自己的镜像,然后推送到 Docker Hub。

首先通过 docker pull nginx 将 nginx 镜像下载到本地。

给 nginx 添加标签 :

[root@server1 ~]# docker tag nginx:latest cl82/nginx
[root@server1 ~]# docker images 
REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
cl82/nginx                        latest              ed21b7a8aee9        8 days ago          127MB
nginx                             latest              ed21b7a8aee9        8 days ago          127MB

将自己的镜像推送到 Docker Hub

[root@server1 ~]# docker push cl82/nginx
The push refers to repository [docker.io/cl82/nginx]
d37eecb5b769: Mounted from library/nginx 
99134ec7f247: Mounted from library/nginx 
c3a984abe8a8: Mounted from library/nginx 
latest: digest: sha256:7ac7819e1523911399b798309025935a9968b277d86d50e5255465d6592c0266 size: 948

稍等片刻,我们就可以搜索出推送的镜像了

[root@server1 ~]# docker search cl82
NAME                DESCRIPTION         STARS               OFFICIAL            AUTOMATED
cl82/nginx                              0        

自动构建

我们可以通过 Docker Hub 指定跟踪一个目标网站(支持 GitHub 或 BitBucket)上的项目,项目一旦有新的提交或者创建了新标签,将会触发 Docker Hub 自动构建镜像并推送到 Docker Hub中。

设置自动构建的步骤如下:

登录 Docker Hub
点击头像,选择 Account Setting 再选择 Linked Accounts 管理账号
在 Docker Hub 中新建或选择已有的仓库,在 Builds 选项卡中选择 Configure Automated Builds
选取一个目标网站中的项目(需要含 Dockerfile)和分支
指定 Dockerfile 的位置,并保存

完成自动构建配置之后,指定的分支一旦提交代码就会触发自动构建,我们可以在仓库页面的 Timeline 选项卡中查看每次构建的状态。

除了 Docker Hub 的自动构建外,我们也可以使用 Travis CI 等持续集成工具来实现自动构建。

四、创建私有仓库

在这里插入图片描述
公司的项目一般不予许我们上传到 Docker Hub 这类的公共仓库中,所有学会创建一个私有仓库也是非常必要的。

容器运行

我们可以通过获取官方的 registry 镜像来运行。

[root@server1 ~]# docker pull registry

 

docker run -d -p 5000:5000 --restart=always --name registry registry

这将使用官方提供的 registry 镜像来启动私有仓库。默认情况下,仓库会被创建在容器的 /var/lib/registry 目录下。我们可以通过 -v 参数将镜像文件存放在本地的指定路径。

[root@server1 ~]# docker run -d \
> -p 5000:5000 \
> -v /opt/data/registry:/var/lib/registry \
> --restart=always \
> registry

这时我们可以通过浏览器访问 http://domain:5000/v2/_catalog 查看仓库是否启动成功。

  • 其中 domain 是你的域名或 ip 地址,下文中的 domain 同理。也可以编辑解析文件/etc/hosts,有解析时domain就可以换成域名。

在私有仓库搜索、上传、下载镜像

本地上传,下载镜像

首先使用 docker tag 将本地的 nginx 镜像添加标签

[root@server1 ~]# docker tag nginx:latest localhost:5000/nginx:latest

接下来就可以使用 docker push 命令将镜像推送到我们的私有仓库中

[root@server1 ~]# docker push localhost:5000/nginx
The push refers to repository [localhost:5000/nginx]
d37eecb5b769: Pushed 
99134ec7f247: Pushed 
c3a984abe8a8: Pushed 
latest: digest: sha256:7ac7819e1523911399b798309025935a9968b277d86d50e5255465d6592c0266 size: 948

将本地的镜像删除之后测试下载:

[root@server1 ~]# docker rmi localhost:5000/nginx:latest 
Untagged: localhost:5000/nginx:latest
Untagged: localhost:5000/nginx@sha256:7ac7819e1523911399b798309025935a9968b277d86d50e5255465d6592c0266
[root@server1 ~]# docker pull localhost:5000/nginx
Using default tag: latest
latest: Pulling from nginx
Digest: sha256:7ac7819e1523911399b798309025935a9968b277d86d50e5255465d6592c0266
Status: Downloaded newer image for localhost:5000/nginx:latest
localhost:5000/nginx:latest

下载完成。

远程主机上传下载镜像

准备一台虚拟机(server2:172.25.63.2)安装好docker

首先尝试拉取server1仓库中的镜像:

[root@server2 ~]# docker pull 172.25.63.1:5000/nginx
Using default tag: latest
Error response from daemon: Get https://172.25.63.1:5000/v2/: http: server gave HTTP response to HTTPS client

出现上面的提示时,说明拉取失败了。因为 Docker 默认使用 HTTPS 的方式推送镜像。我们可以通过 Docker 的配置来取消这个限制。
对于 Linux 系统,我们可以在 /etc/docker/deamon.json (deamon.josn 文件不存在则新建该文件)添加下面的配置,表示走非加密通道:

[root@server2 ~]# cat /etc/docker/daemon.json 
{
"insecure-registries": ["reg.westos.org:5000"]
}

[root@server2 ~]# systemctl daemon-reload 
[root@server2 ~]# systemctl restart docker

注意如果在文件中填写域名一定要做解析。

设置完成后再使用上面的命令进行拉取就可以成功。除了上面这种方式外,我们也可以将私有仓库的地址配置成支持 HTTPS 访问的,下一部分我们展开来讲。

[root@server2 ~]# docker pull reg.westos.org:5000/nginx
Using default tag: latest
latest: Pulling from nginx
c499e6d256d6: Pull complete 
74cda408e262: Pull complete 
ffadbd415ab7: Pull complete 
Digest: sha256:7ac7819e1523911399b798309025935a9968b277d86d50e5255465d6592c0266
Status: Downloaded newer image for reg.westos.org:5000/nginx:latest
reg.westos.org:5000/nginx:latest


五、 为docker仓库添加加密功能

仓库配置

生成证书:

[root@server1 ~]# mkdir -p certs
[root@server1 ~]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout certs/reg.westos.org.key -x509 -days 365 -out certs/reg.westos.org.crt

填写信息后打开certs目录即可看到证书:

[root@server1 ~]# cd certs/
[root@server1 certs]# ls
reg.westos.org.crt  reg.westos.org.key

注意要求在server1中做解析。
下一步我们需要运行registry,运行之前需要关闭上个实验所运行的容器:

[root@server1 certs]# docker rm -f registry			#删除容器
registry
[root@server1 certs]# docker volume prune			#删除卷
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
4b6a8739615b4eb56ee8a940ca774242efc01dddcc3e24d8f6383688dff69569
cfd3c38ef73b58b09e9d79e45de6780fe16da3e15bfa498dc5a43fd06aa81782

Total reclaimed space: 51.02MB

运行容器:

[root@server1 certs]# cd
[root@server1 ~]# docker run -d --name registry -v "$(pwd)"/certs:/certs -v /opt/registry:/var/lib/registry -e REGISTRY_HTTP_ADDR=0.0.0.0:443 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/reg.westos.org.crt -e REGISTRY_HTTP_TLS_KEY=/certs/reg.westos.org.key -p 443:443   registry

查看运行状态:

[root@server1 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                            NAMES
34b75ec2d1ec        registry            "/entrypoint.sh /etc…"   3 minutes ago       Up 3 minutes        0.0.0.0:443->443/tcp, 5000/tcp   registry

客户端配置

将证书复制给每一个客户端:
这里以本机为例:

mkdir /etc/docker/certs.d/			#这个目录不可以改动
cd /etc/docker/certs.d/
mkdir reg.westos.org
cd reg.westos.org/						#需要访问的仓库主机名
cp ~/certs/reg.westos.org.crt .			#将证书复制到指定目录
mv reg.westos.org.crt ca.crt			#必须要命名为ca.crt

本机测试

测试上传镜像:

[root@server1 ~]# docker tag ubuntu:latest reg.westos.org/ubuntu
[root@server1 ~]# docker push reg.westos.org/ubuntu
The push refers to repository [reg.westos.org/ubuntu]
16542a8fc3be: Layer already exists 
6597da2e2e52: Layer already exists 
977183d4e999: Layer already exists 
c8be1b8f4d60: Layer already exists 
latest: digest: sha256:e5dd9dbb37df5b731a6688fa49f4003359f6f126958c9c928f937bec69836320 size: 1152

上传成功,上传成功后可以查看容器挂载目录:

[root@server1 ~]# cd /opt/registry/
[root@server1 registry]# ls
docker

远程主机测试

测试之前需要确保远程主机的指定目录有证书信息:

[root@server2 ~]# cd /etc/docker/certs.d/reg.westos.org/ 
[root@server2 reg.westos.org]# ls
ca.crt

此时在server2测试访问,测试之前删除server2之前设置的非加密配置信息:

[root@server2 ~]# cd /etc/docker/
[root@server2 docker]# rm -f daemon.json 

测试拉取:

[root@server2 ~]# docker pull reg.westos.org/ubuntu
Using default tag: latest
latest: Pulling from ubuntu
5bed26d33875: Pull complete 
f11b29a9c730: Pull complete 
930bda195c84: Pull complete 
78bf9a5ad49e: Pull complete 
Digest: sha256:e5dd9dbb37df5b731a6688fa49f4003359f6f126958c9c928f937bec69836320
Status: Downloaded newer image for reg.westos.org/ubuntu:latest
reg.westos.org/ubuntu:latest

拉取成功。

六、 为docker仓库添加认证功能

仓库配置

建立认证目录和认证用户:

[root@server1 ~]# mkdir auth		#建立认证文件目录
[root@server1 ~]# docker run --rm --entrypoint htpasswd registry -Bbn cl westos > auth/htpasswd			#将用户填入认证文件
[root@server1 ~]# docker run --rm --entrypoint htpasswd registry -Bbn admin redhat >> auth/htpasswd
[root@server1 ~]# cat auth/htpasswd 		#查看认证文件
cl:$2y$05$69YorsVhTtQoVEy9lcK1HuvP60oILY7Tu5LCSDODdExz6aU1pixvm

admin:$2y$05$s8n0yELcYcj6mJFOfq/kc.n9o1zAWwN9lt16jVbYOm3j1MGLwq3pS
[root@server1 ~]# docker rm -f registry 		#删除之前实验运行的容器
registry
[root@server1 ~]# docker run -d --name registry -v "$(pwd)"/certs:/certs -v /opt/registry:/var/lib/registry -v "$(pwd)"/auth:/auth -e REGISTRY_HTTP_ADDR=0.0.0.0:443 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/reg.westos.org.crt -e REGISTRY_HTTP_TLS_KEY=/certs/reg.westos.org.key -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd  -p 443:443   registry

上述最后一个命令是运行容器的命令。

测试

在server1上传一个镜像(上传不需要登陆):

[root@server1 ~]# docker push reg.westos.org/base-debian10
The push refers to repository [reg.westos.org/base-debian10]
1d3b68b6972f: Layer already exists 
de1602ca36c9: Layer already exists 
latest: digest: sha256:732acc54362badaa64d9c01619020cf96ce240b97e2f1390d2a44cc22b9ba6a3 size: 737

之后在远程主机测试拉取镜像:

[root@server2 ~]# docker pull reg.westos.org/base-debian10
Using default tag: latest
Error response from daemon: Get https://reg.westos.org/v2/base-debian10/manifests/latest: no basic auth credentials

发现不能拉取,登陆后再进行拉取:

[root@server2 ~]# docker login reg.westos.org
Username: cl		#输入刚才建立的用户名
Password: 			#输入刚才建立的用户密码
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

[root@server2 ~]# docker pull  reg.westos.org/base-debian10
Using default tag: latest
latest: Pulling from base-debian10
cfb92865f5ba: Pull complete 
8dd350b5e0d5: Pull complete 
Digest: sha256:732acc54362badaa64d9c01619020cf96ce240b97e2f1390d2a44cc22b9ba6a3
Status: Downloaded newer image for reg.westos.org/base-debian10:latest
reg.westos.org/base-debian10:latest

发现拉取成功,即表示用户认证配置成功。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值