自建容器仓库:Self-Hosting a Container Registry

原文链接:packagemain.tech/p/self-host...

原文作者:Alex Pliutau

译者:菜小鸟魔王

01 什么是容器镜像?

在探讨容器仓库之前,我们先来弄清楚容器镜像的概念。简单来说,容器镜像就是一个包含了运行容器所需全部文件、库和配置的打包文件。它由多个 layers 构成,每个 layer 代表了文件系统的一系列变更,涉及文件的添加、移除或修改。

通常,我们通过编写 Dockerfile 来创建容器镜像。

bash 复制代码
# build an image
docker build -t pliutau/hello-world:v0 .

# check the images locally
docker images
# REPOSITORY    TAG       IMAGE ID       CREATED          SIZE
# hello-world   latest    9facd12bbcdd   22 seconds ago   11MB

这样,就能创建一个存储在本地机器上的容器镜像。但如果想要将这个镜像分享给他人,或者在另一台机器上使用,这就需要借助容器仓库来实现。

02 什么是容器仓库?

容器仓库是一个存储系统,我们可以在这里上传和下载容器镜像。镜像被分类存放在不同的仓库中,每个仓库是一组具有相同名称的相关镜像。例如,在 Docker Hub 上,nginx这个仓库存放着不同版本的 nginx 镜像。

有些仓库是公开的,任何人都可以在互联网上访问这些仓库中的镜像。公共仓库,如Docker Hub,是托管开源项目的理想场所。

相对地,私有仓库则为企业存储容器镜像提供了一种较为安全和隐私的方法,无论是云服务还是本地部署。这些私有仓库通常配备了先进的安全功能和专业技术支持。市面上有许多私有仓库可供选择,比如Amazon ECRGCP Artifact RegistryGitHub Container Registry,甚至 Docker Hub 也提供有私有仓库的功能。

开发人员可以使用 docker push 和 docker pull 命令与容器仓库进行交互。

bash 复制代码
docker push docker.io/pliutau/hello-world:v0

# In case of Docker Hub we could also skip the registry part
docker push pliutau/hello-world:v0

让我们来看看容器镜像 URL 的构造。

ruby 复制代码
docker pull docker.io/pliutau/hello-world:v0@sha256:dc11b2...
                |            |            |          |
                ↓            ↓            ↓          ↓
             registry    repository      tag       digest

03 为何要自行搭建容器仓库?

有时候,你或许希望不借助 AWS 或 GCP 等服务商,而是自行管理镜像。这样做可以将基础设施建立在企业内部,降低对外部供应商的依赖。在某些严格监管的行业中,这是必须遵守的规定。

自行搭建的容器仓库将在我们自己的服务器上运行,这让我们能够更自主地控制仓库的配置方式和镜像的存放位置。但与此同时,也意味着需要承担维护和保护仓库的额外成本。

04 如何自行搭建容器仓库?

目前市面上有几款开源的容器仓库解决方案。其中最受欢迎的是 Docker 官方支持的registry项目,它提供了存储和分发容器镜像及工件的功能。也就是说,我们可以在一个容器内运行自己的容器仓库。

以下是在服务器上搭建容器仓库的基本步骤:

  1. 在服务器上安装 Docker 和 Docker Compose。
  2. 配置并启动仓库容器。
  3. 运行 nginx 来处理 TLS 加密连接,并将请求转发至仓库容器。
  4. 安装 SSL 证书,并配置好域名。

05 Server

可以选用任何能够运行Docker的服务器。比如,可以选用带有Ubuntu系统的DigitalOcean Droplet。在本文中,我选择了Google Cloud Compute来创建一个装有Ubuntu系统的虚拟机。

ini 复制代码
neofetch

# OS: Ubuntu 20.04.6 LTS x86_64
# CPU: Intel Xeon (2) @ 2.200GHz
# Memory: 3908MiB

进入虚拟机后,我们需要安装Docker和Docker Compose。虽然Docker Compose并非必需,但它能让我们更轻松地管理多容器应用程序。

bash 复制代码
# install docker engine and docker-compose
sudo snap install docker

# verify the installation
docker --version
docker-compose --version

06 容器仓库的配置

接下来,我们需要配置 registry 容器。下面这个compose.yaml配置文件将创建一个 registry 容器,并为其分配两个卷,一个用于存放镜像,另一个用于存放密码文件。

yaml 复制代码
services:
  registry:
    image: registry:latest
    environment:
      REGISTRY_AUTH: htpasswd
      REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
      REGISTRY_AUTH_HTPASSWD_PATH: /auth/registry.password
      REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
    volumes:
      # Mount the password file
      - ./registry/registry.password:/auth/registry.password
      # Mount the data directory
      - ./registry/data:/data
    ports:
      - 5000

在配置中指定的REGISTRY_AUTH_HTPASSWD_PATH路径下的密码文件,将用于用户在推送或拉取镜像时进行身份验证。我们需要通过运行htpasswd命令来生成这个密码文件。同时,我们还需要创建一个目录来存放镜像文件。

bash 复制代码
mkdir -p ./registry/data

# install htpasswd
sudo apt install apache2-utils

# create a password file. username: busy, password: bee
htpasswd -Bbn busy bee > ./registry/registry.password

配置完成后,我们就可以启动 registry 容器了。如果看到这条信息,说明一切正常。

arduino 复制代码
docker-compose up

# successfull run should output something like this:
# registry | level=info msg="listening on [::]:5000"

07 SSL证书和Nginx

前面提到,我们可以利用Nginx来处理TLS加密连接,并将请求代理到仓库容器。Docker仓库在运行时需要有效的可信SSL证书。你可以选择使用Let's Encrypt来自动获取证书,或者手动申请。你需要确保有一个域名指向你的服务器(例如我的域名是registry.pliutau.com)。在这个示例中,我已经通过certbot工具获取了证书,并存放在了./nginx/certs目录下。

由于我们的Docker仓库是作为容器运行的,我们同样可以在compose.yaml文件中添加相应的服务,以便将Nginx也作为容器来运行。

yaml 复制代码
services:
  registry:
    # ...
  nginx:
    image: nginx:latest
    depends_on:
      - registry
    volumes:
      # mount the nginx configuration
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      # mount the certificates obtained from Let's Encrypt
      - ./nginx/certs:/etc/nginx/certs
    ports:
      - "443:443"

nginx.conf文件如下所示:

ini 复制代码
worker_processes auto;

events {
    worker_connections 1024;
}

http {
    upstream registry {
        server registry:5000;
    }

    server {
        server_name registry.pliutau.com;
        listen 443 ssl;

        ssl_certificate /etc/nginx/certs/fullchain.pem;
        ssl_certificate_key /etc/nginx/certs/privkey.pem;

        location / {
            # important setting for large images
            client_max_body_size                1000m;

            proxy_pass                          http://registry;
            proxy_set_header  Host              $http_host;
            proxy_set_header  X-Real-IP         $remote_addr;
            proxy_set_header  X-Forwarded-For   $proxy_add_x_forwarded_for;
            proxy_set_header  X-Forwarded-Proto $scheme;
            proxy_read_timeout                  900;
        }
    }
}

08 Ready to go!

执行完上述步骤后,我们就可以运行自己的仓库和Nginx容器了。

复制代码
docker-compose up

接下来,在客户端能够从私有仓库中推送和拉取镜像。在此之前,需要先登录到镜像仓库。

bash 复制代码
docker login registry.pliutau.com

# Username: busy
# Password: bee
# Login Succeeded

现在,我们可以开始构建镜像,并将其推送到我们自行搭建的仓库了!

bash 复制代码
docker build -t registry.pliutau.com/pliutau/hello-world:v0 .

docker push registry.pliutau.com/pliutau/hello-world:v0
# v0: digest: sha256:a56ea4... size: 738

同时,你可以在服务器上的存储目录中查看已上传的镜像。

bash 复制代码
ls -la ./registry/data/docker/registry/v2/repositories/

09 其他选择

依照上面的例子,同样可以在Kubernetes上部署仓库。或者,可以选择使用Harbor这样的托管仓库服务,这是一个开源项目,提供高级安全功能,并且与Docker和Kubernetes无缝对接。

如果你希望为自己的私有仓库添加一个图形界面,可以尝试使用joxit/docker-registry-ui这样的项目,并在单独的容器中运行。

10 总结

自建容器仓库让我们能够全面掌控容器仓库及其部署过程。但这也意味着我们需要承担起维护和保护仓库的责任。

不管出于何种目的选择自建仓库,你现在应该已经掌握了必要的操作方法。接下来,你可以根据自身需求,比较不同的方案,做出最佳选择。

You can find the full source code for this demo on GitHub. Also, you can watch it as a video on our YouTube channel.

相关推荐
江湖有缘21 分钟前
Docker环境下使用RustScan端口扫描工具教程
运维·docker·容器
70asunflower26 分钟前
镜像仓库(Image Registries)详解
linux·docker·容器
青树寒鸦35 分钟前
wsl的docker备份redis和迁移
redis·docker·容器
岩屿36 分钟前
Ubuntu下安装Docker并部署.NET API(二)
运维·docker·容器·.net
hopsky1 小时前
限制 Docker Desktop 的资源使用
运维·docker·容器
春日见1 小时前
docker崩溃,闪退,与vscode断开连接
vscode·docker·容器
为什么不问问神奇的海螺呢丶1 小时前
n9e categraf k8s监控配置-n9e k8s监控看板
java·容器·kubernetes
Suchadar1 小时前
Docker搭建Web测试靶场
运维·docker·容器
Cyber4K1 小时前
【Kubernetes专项】K8s 配置管理中心 ConfigMap 实现微服务配置管理
微服务·云原生·容器·kubernetes
fleaxin2 小时前
统信服务器操作系统V20(1070)安装过程
docker·操作系统·nvidia·统信