搭建容器的私有库


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

  • 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

结果完全正确。

Guess you like

Origin blog.csdn.net/witton/article/details/121558560