搭建容器的私有库


我们在使用容器的时候,一般都是从公有库比如:

  • docker.io
  • registry.fedoraproject.org
  • quay.io
  • registry.access.redhat.com
  • registry.centos.org
    等地方进行拉取镜像的,如果有相应库的账号,也可以自己创建容器镜像推送到公有库中。
    如果是不想推送到公有库中,比如公司内部使用的容器,想推送到公司自己的私有库中,那就需要自行搭建私有库。

笔者以Ubuntun 21.10下的podman为例,介绍如何搭建容器的私有库。

一、拉取registry容器

1、使用cockpit来拉取

如果系统安装了cockpit来管理容器,可以很方便地拉取,如下图所示:
在这里插入图片描述
Ubuntu系统可能没有公有库地址,可以参考:配置与管理Ubuntu 21.10一文中“Podman容器”部分。

2、 使用命令拉取

使用下面的命令来拉取registry镜像

sudo podman pull registry

如果是docker就换成docker命令即可,格式是一样的

sudo docker pull registry

podman的输出如下所示:

witton@witton:~$ sudo podman pull registry
Trying to pull docker.io/library/registry:latest...
Getting image source signatures
Copying config b8604a3fe8 done  
Writing manifest to image destination
Storing signatures
b8604a3fe8543c9e6afc29550de05b36cd162a97aa9b2833864ea8a5be11f3e2

使用命令

sudo podman images

查看拉取的镜像:

witton@witton:~$ sudo podman images
REPOSITORY                       TAG       IMAGE ID      CREATED       SIZE
docker.io/library/registry       latest    b8604a3fe854  1 minutes ago   26.8 MB

二、 运行registry镜像

1、使用cockpit运行registry

使用cockpit运行容器非常方便,如下图所示,命令一行默认就填写好了,名称会自动随机一个名字,其它的都可以不用管,直接点“运行”就好。这样运行的registry是只能在宿主机上使用容器的IP地址进行访问,如果容器IP地址发生变化,相应地使用时也需要跟着变化。同时registry存储的镜像也是保存在容器内部的,如果容器被删除,相应的镜像也会一同被删除。
在这里插入图片描述

所以为了使用方便,需要映射容器的端口到宿主机;同时为了安全起见需要把容器中存储镜像的地址映射到主机。

registry容器的配置文件为容器中的/etc/docker/registry/config.yml
可以在容器(名字为registry)运行起来后,使用下面的命令复制到宿主机上来查看:

sudo podman cp registry:/etc/docker/registry/config.yml ~/

内容如下:

version: 0.1
log:
  fields:
    service: registry
storage:
  cache:
    blobdescriptor: inmemory
  filesystem:
    rootdirectory: /var/lib/registry
http:
  addr: :5000
  headers:
    X-Content-Type-Options: [nosniff]
health:
  storagedriver:
    enabled: true
    interval: 10s
    threshold: 3

从中可以看到镜像存储的路径为/var/lib/registry,监听的端口为5000,我们需要映射到宿主机,所以如下图所示进行填写,然后运行。
在这里插入图片描述
运行成功后,可以从日志窗口查看到相应的日志信息:
在这里插入图片描述
这里面有一条警告需要注意:

WARN[0000] 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.

这里没有相应的情况,可以暂时不用管它,当然也可以按它的要求,在前面的运行对话框中填写REGISTRY_HTTP_SECRET环境变量。

需要注意的是这样搭建的registry容器是以http的方式提供服务的,而非公有库的https方式

2、使用命令行的方式运行registry

命令行的方式就需要记住命令格式,相对于cockpit来说要复杂得多:

sudo podman run -dt -p 5000:5000 --privileged --restart=always --name=registry -v /con_registry:/var/lib/registry docker.io/library/registry

podman run :创建一个新的容器并运行一个命令,具体用法可以使用podman run --help来查看帮助。

witton@witton:~$ sudo podman run -dt -p 5000:5000 --privileged --restart=always --name=registry -v /con_registry:/var/lib/registry docker.io/library/registry
3050d7ee304d89efe1006d633a630563f042779c5f6283e295b45da233b26272

三、测试

1、拉取所需容器

比如拉取一个centos7镜像,然后可以对这个容器进行一系列的定制,比如前面博客中所提到的建立外部可访问的SSHD服务。

查看拉取的镜像:

witton@witton:~$ sudo podman images
REPOSITORY                       TAG       IMAGE ID      CREATED       SIZE
docker.io/library/registry       latest    b8604a3fe854  1 days ago   26.8 MB
docker.io/library/centos         7.9.2009  eeb6ee3f44bd  2 months ago  212 MB

查看运行的容器:

witton@witton:~$ sudo podman ps
CONTAINER ID  IMAGE                              COMMAND               CREATED        STATUS            PORTS                   NAMES
af476904e658  docker.io/library/centos:7.9.2009  /bin/bash             4 minutes ago     Up 6 hours ago    0.0.0.0:2022->22/tcp    centos7
c11ac6538f34  docker.io/library/registry:latest  /etc/docker/regis...  6 minutes ago  Up 6 minutes ago  0.0.0.0:5000->5000/tcp  registry

2、提交镜像

在定制好centos7容器后,把它提交为centos7-ssh
从前面可以看到centos7容器的ID为af476904e658
使用下面的命令进行提交:

sudo podman commit af476904e658 centos7-ssh

结果:

witton@witton:~$ sudo podman commit af476904e658 centos7-ssh
Getting image source signatures
Copying blob 174f56854903 skipped: already exists  
Copying blob 6faad18d6fae done  
Copying config df178b51d2 done  
Writing manifest to image destination
Storing signatures
df178b51d2fb7ea1563543a50372f4e78be8351c96c0ab4ea62f87c640ed2b7a

查看镜像:

witton@witton:~$ sudo podman images
REPOSITORY                       TAG       IMAGE ID      CREATED       SIZE
localhost/centos7-ssh            latest    df178b51d2fb  4 minutes ago   592 MB
docker.io/library/registry       latest    b8604a3fe854  1 days ago   26.8 MB
docker.io/library/centos         7.9.2009  eeb6ee3f44bd  2 months ago  212 MB

可以看到刚才提交的镜像localhost/centos7-ssh

3、推送镜像

前面提交镜像是提交到本地,还没有推送到registry服务器,熟悉git的话应该很好理解。
接下来就是推送到自己搭建的私有库中:

sudo podman push df178b51d2fb 127.0.0.1:5000/centos7-ssh

结果却推送失败了:

witton@witton:/$ sudo podman push df178b51d2fb 127.0.0.1:5000/centos7-ssh
Getting image source signatures
Error: Error trying to reuse blob sha256:174f5685490326fc0a1c0f5570b8663732189b327007e47ff13d2ca59673db02 at destination: error pinging docker registry 127.0.0.1:5000: Get "https://127.0.0.1:5000/v2/": http: server gave HTTP response to HTTPS client

提示127.0.0.1:5000提供的registry服务是HTTP的结果返回给HTTPS的客户端,即两边使用的协议不一致,服务器使用的HTTP协议,而客户端使用的是HTTPS协议。

在旧版本中,特别是 v1 配置版本,podman 和支持它的 libcontainer 库可以使用一个名为[registries.insecure]的块来列出不安全的registry服务,但是在v2版本中不再有效,它会报如下错误:

witton@witton:/$ sudo podman push df178b51d2fb 127.0.0.1:5000/centos7-ssh
Error: Error initializing destination docker://127.0.0.1:5000/centos7-ssh:latest: error getting username and password: error loading registries configuration "/etc/containers/registries.conf": mixing sysregistry v1/v2 is not supported

最好的方式,当然是把registry服务配置成HTTPS服务,但是要配置成HTTPS服务相对要麻烦很多(参见第五部分:构建HTTPS私有库)。

如果是公司内部使用,使用HTTP服务也不会有太大的安全问题。在这种情况下,可以使用新的v2的配置方式。在宿主机上创建一个文件/etc/containers/registries.conf.d/myreg.conf文件,内容如下:

[[registry]]
location = "127.0.0.1:5000"
insecure = true

然后使用命令

sudo systemctl restart podman

重启podman服务。

再推送镜像:

witton@witton:/$ sudo podman push df178b51d2fb 127.0.0.1:5000/centos7-ssh
[sudo] password for witton: 
Getting image source signatures
Copying blob 174f56854903 done  
Copying blob 6faad18d6fae done  
Copying config df178b51d2 done  
Writing manifest to image destination
Storing signatures

我们可以在宿主机上查看一下/con_registry目录的内容,可以查到成功存储到指定目录了。
在这里插入图片描述

四、添加到镜像源

我们成功搭建了私有库,以后想要从私有库中拉取,还需要把私有库添加到镜像源中。
可以参考:配置与管理Ubuntu 21.10一文中“Podman容器”部分。

五、构建HTTPS私有库

1、修改openssl配置

在生成证书之前,需要修改openssl.cnf配置文件

  • ubuntu21.10系统路径为:/etc/ssl/openssl.cnf
  • centos8系统路径为:/etc/pki/tls/openssl.cnf

在[v3_ca]下面添加:subjectAltName = IP:域名|IP地址

subjectAltName=IP:192.168.1.8

其中的IP为宿主机的IP地址,不然在推送的时候会报错:

x509: cannot validate certificate for 192.168.1.8 because it doesn't contain any IP SANs

在这里插入图片描述

2、生成证书

使用下面的命令生成证书:

cd ~
mkdir certs
openssl req -newkey rsa:4096 -nodes -sha256 -keyout ~/certs/domain.key  -x509 -days 365 -out ~/certs/domain.crt

我的结果:

witton@witton:~$ mkdir certs
witton@witton:~$ openssl req -newkey rsa:4096 -nodes -sha256 -keyout ~/certs/domain.key -x509 -days 365 -out ~/certs/domain.crt
Generating a RSA private key
.......................................++++
....++++
writing new private key to '/home/witton/certs/domain.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
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) []:
Email Address []:

中间的交互的地方直接回车即可。

3、复制证书到宿主系统

ubuntu系统为:

ln -s ~/certs/domain.crt /etc/ssl/certs/

centos系统为:

cat ~/certs/domain.crt >> /etc/pki/tls/certs/ca-bundle.crt

4、运行registry容器

sudo podman run -dt -p 5000:5000 --privileged --restart=always --name=registry -v /con_registry:/var/lib/registry -v /home/witton/certs/:/root/certs -e REGISTRY_HTTP_TLS_CERTIFICATE=/root/certs/domain.crt -e REGISTRY_HTTP_TLS_KEY=/root/certs/domain.key -e REGISTRY_HTTP_SECRET=true docker.io/library/registry
  • -v /con_registry:/var/lib/registry
    映射宿主目录/con_registry到容器/var/lib/registry,用于存储镜像
  • -v /home/witton/certs/:/root/certs
    映射宿主目录/home/witton/certs到容器/root/certs,将生成的证书存放目录映射到容器/root/certs
  • -e REGISTRY_HTTP_TLS_CERTIFICATE=/root/certs/domain.crt
    设置环境变量REGISTRY_HTTP_TLS_CERTIFICATE的值为/root/certs/domain.crt,这是容器中的路径
  • -e REGISTRY_HTTP_TLS_KEY=/root/certs/domain.key
    设置环境变量REGISTRY_HTTP_TLS_KEY的值为/root/certs/domain.key,这是容器中的路径
  • -e REGISTRY_HTTP_SECRET=true
    设置环境变量REGISTRY_HTTP_SECRET的值,消除registry容器启动警告
witton@witton:~$ sudo podman run -dt -p 5000:5000 --privileged --restart=always --name=registry -v /con_registry:/var/lib/registry -v /home/witton/certs/:/root/certs -e REGISTRY_HTTP_TLS_CERTIFICATE=/root/certs/domain.crt -e REGISTRY_HTTP_TLS_KEY=/root/certs/domain.key -e REGISTRY_HTTP_SECRET=true docker.io/library/registry
d314b2f9c1d92a6adbbb91f834aa3087a33bb91c09e5d88a5b8865cff24bd3f1

5、测试推送

如果是使用的docker,可能需要重启一下docker服务,以更新密钥:

systemctl restart docker

笔者使用的podman,在测试中没有重启也可以使用,如果不成功,也可以重启一下podman服务:

systemctl restart podman

现在测试推送:

sudo podman push df178b51d2fb 192.168.1.8:5000/centos7-ssh

我的输出:

witton@witton:~$ sudo podman push df178b51d2fb 192.168.1.8:5000/centos7-ssh
Getting image source signatures
Copying blob 174f56854903 done  
Copying blob 6faad18d6fae done  
Copying config df178b51d2 done  
Writing manifest to image destination
Storing signatures

结果完全正确。

Supongo que te gusta

Origin blog.csdn.net/witton/article/details/121558560
Recomendado
Clasificación