RustFS x Distribution Registry,构建本地镜像仓库

容器镜像仓库是应用容器化部署的必选项,顶级玩家 Dockerhub 由于网络原因,在国内使用不是很顺畅,因此搭建一个企业专属的私有化镜像仓库就成为了企业云原生转型的关键。现在市面上有很多类似的解决方案,比如 Harbor, GitLab Container Registry, GitHub Container Registry 等,但是这些项目都用到了开源项目 Distribution,这个项目的主要产品就是为使用 OCI Distribution 规范的容器镜像仓库提供一个开源的 Registry 实现,因此可以单独使用此开源项目搭建一个私有化的容器镜像托管平台。

由于 Distribution 支持将 S3 作为存储后端,而 RustFS 又是一个 S3 兼容的分布式对象存储系统,因此可以将 RustFS 配置为 Distribution 的存储后端。下面的整个实践过程。

入门配置

安装

将 Distribution 和 RustFS 进行容器化部署,整个过程使用三个容器:

  • Distribution:托管容器镜像。依赖 RustFS 和 MC 服务;配置如下:

    复制代码
    registry:
      depends_on:
        - rustfs
        - mc
      restart: always
      image: registry:3
      ports:
        - 5000:5000
      environment:
        REGISTRY_STORAGE: s3
        REGISTRY_AUTH: htpasswd
        REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
        REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
        REGISTRY_STORAGE_S3_ACCESSKEY: rustfsadmin
        REGISTRY_STORAGE_S3_SECRETKEY: rustfsadmin
        REGISTRY_STORAGE_S3_REGION: us-east-1
        REGISTRY_STORAGE_S3_REGIONENDPOINT: http://rustfs:9000
        REGISTRY_STORAGE_S3_BUCKET: docker-registry
        REGISTRY_STORAGE_S3_ROOTDIRECTORY: /var/lib/registry
        REGISTRY_STORAGE_S3_FORCEPATHSTYLE: true
        REGISTRY_STORAGE_S3_LOGLEVEL: debug
      volumes:
        - ./auth:/auth
      networks:
        - rustfs-oci

注意REGISTRY_AUTH 指定了和容器镜像仓库鉴权的方式,本文使用用户名和密码。使用如下方式生成加密的密码:

复制代码
docker run \
  --entrypoint htpasswd \
  httpd:2 -Bbn testuser testpassword > auth/htpasswd

将生成的 auth/htpasswd 文件挂载到 Registry 容器中即可,后续就能使用 testuser/testpassword 进行仓库登陆了。

  • RustFS:存储镜像仓库数据。配置如下:

    复制代码
    rustfs:
      image: rustfs/rustfs:1.0.0-alpha.77
      container_name: rustfs
      hostname: rustfs
      environment:
        - RUSTFS_VOLUMES=/data
        - RUSTFS_ADDRESS=0.0.0.0:9000
        - RUSTFS_CONSOLE_ENABLE=true
        - RUSTFS_CONSOLE_ADDRESS=0.0.0.0:9001
        - RUSTFS_ACCESS_KEY=rustfsadmin
        - RUSTFS_SECRET_KEY=rustfsadmin
        - RUSTFS_OBS_LOGGER_LEVEL=debug
        - RUSTFS_OBS_LOG_DIRECTORY=/logs
      healthcheck:
        test:
          [
            "CMD",
            "sh", "-c",
            "curl -f http://localhost:9000/health && curl -f http://localhost:9001/rustfs/console/health"
          ]
        interval: 10s
        timeout: 5s
        retries: 3
        start_period: 30s
      ports:
        - "9000:9000"  # API endpoint
        - "9001:9001"  # Console
      networks:
        - rustfs-oci
  • MC:创建 bucket 以存储数据。依赖 RustFS 服务;

    复制代码
    mc:
      depends_on:
        - rustfs
      image: minio/mc
      container_name: mc
      networks:
        - rustfs-oci
      environment:
        - AWS_ACCESS_KEY_ID=rustfsadmin
        - AWS_SECRET_ACCESS_KEY=rustfsadmin
        - AWS_REGION=us-east-1
      entrypoint: |
        /bin/sh -c "
        until (/usr/bin/mc alias set rustfs http://rustfs:9000 rustfsadmin rustfsadmin) do echo '...waiting...' && sleep 1; done;
        /usr/bin/mc rm -r --force rustfs/docker-registry;
        /usr/bin/mc mb rustfs/docker-registry;
        /usr/bin/mc policy set public rustfs/docker-registry;
        tail -f /dev/null
        "

将上述三个容器的配置写到 docker-compose.yml 文件中,然后执行:

复制代码
docker compose up -d

查看服务状态:

复制代码
docker ps
CONTAINER ID   IMAGE                          COMMAND                   CREATED             STATUS                       PORTS                                                                                NAMES
7834dee8cbbf   registry:3                     "/entrypoint.sh /etc..."    38 minutes ago      Up 38 minutes                0.0.0.0:80->5000/tcp, 0.0.0.0:443->5000/tcp, [::]:80->5000/tcp, [::]:443->5000/tcp   docker-registry-registry-1
f922568dd11f   minio/mc                       "/bin/sh -c '\nuntil ..."   About an hour ago   Up About an hour                                                                                                  mc
bf20a5b2ab4b   rustfs/rustfs:1.0.0-alpha.77   "/entrypoint.sh rust..."    About an hour ago   Up About an hour (healthy)   0.0.0.0:9000-9001->9000-9001/tcp, [::]:9000-9001->9000-9001/tcp                      rustfs

测试验证

通过使用 docker 命令登录容器镜像仓库并推送容器镜像来进行测试。

  • 登录容器镜像仓库

    docker login localhost:5000
    Username: testuser
    Password:

    WARNING! Your credentials are stored unencrypted in '/root/.docker/config.json'.
    Configure a credential helper to remove this warning. See
    https://docs.docker.com/go/credential-store/

    Login Succeeded

  • 推送镜像

    拉取镜像

    docker pull rustfs/rustfs:1.0.0-alpha.77

    tag 镜像

    docker tag rustfs/rustfs:1.0.0-alpha.77 localhost:5000/rustfs:1.0.0-alpha.77

    推送镜像

    docker push localhost:5000/rustfs:1.0.0-alpha.77
    The push refers to repository [localhost:5000/rustfs]
    4f4fb700ef54: Pushed
    8d10e1ace7fc: Pushed
    fcd530aedb30: Pushed
    ea6fa4aba595: Pushed
    2d35ebdb57d9: Pushed
    67d0472105ad: Pushed
    09194c842438: Pushed
    1.0.0-alpha.77: digest: sha256:88eafb9e9457dbabb08b9e93cfed476f01474e48ec85e7a9038f1f4290380526 size: 1680

    i Info → Not all multiplatform-content is present and only the available single-platform image was pushed
    sha256:f761246690fdf92fc951c90c12ce4050994c923fb988e3840f072c7d9ee11a63 -> sha256:88eafb9e9457dbabb08b9e93cfed476f01474e48ec85e7a9038f1f4290380526

  • RustFS 验证

在 RustFS 上查看 docker-registry 存储桶中的内容,以确定镜像数据被存储到了 RustFs。

可以看到容器镜像 localhost:5000/rustfs:1.0.0-alpha.77 的相关数据已经存储到 RustFS 中了。

进阶配置

以上的配置,Distribution Registry 都是通过 HTTP 来提供服务,而在企业生产中,这种方式是不允许的,必须配置 HTTPS。

对于 Distribution Registry 来讲,可以通过多种方式进行 HTTPS 配置。比如本地提供 certificate 或者直接使用 Let's encrypt。本文选择后者。

Distribution Registry 配置 Let's encrypt 会用到如下四个参数:

参数 是否必须 描述
cachefile yes Let's Encrypt 代理用来缓存数据的文件路径(绝对路径)。
email yes 注册 Let's Encrypt 所使用的邮箱地址。
hosts no 允许使用 Let's Encrypt 证书的主机名(域名)列表。
directoryurl no 使用 ACME server 的 URL(这个指私有化部署的 ACME Server)。

因此配置如下参数即可:

复制代码
REGISTRY_HTTP_TLS_LETSENCRYPT_CACHEFILE: /auth/acme.json
REGISTRY_HTTP_TLS_LETSENCRYPT_EMAIL: email@com
REGISTRY_HTTP_TLS_LETSENCRYPT_HOSTS: '["example.rustfs.com"]'

然后再次执行:

复制代码
docker compose up -d

在另外一个服务器上验证即可:

复制代码
docker login example.rustfs.com
Authenticating with existing credentials... [Username: testuser]

i Info → To login with a different account, run 'docker logout' followed by 'docker login'


Login Succeeded

再次执行前面的镜像推送和 RustFS 控制台验证即可。

后面就可以使用 example.rustfs.com 这个域名对应的镜像仓库来托管企业内部的所有容器镜像了,而且还可以将整个容器镜像的构建和推送集成到 CI/CD 中。

相关推荐
yunteng5212 小时前
wifi安全实践
安全·wifi·渗透
rayylee2 小时前
从零开始安装Asterinas NixOS操作系统
rust·操作系统·os
计算机小手2 小时前
快速部署一个轻量级邮件发送 API 服务,Go 语言开发,Docker 快速部署
经验分享·docker·开源软件
lifewange2 小时前
Kafka 是什么?
分布式·kafka
boligongzhu2 小时前
ubuntu22.04 安装Docker Engine和Compose
linux·ubuntu·docker·容器
weixin_307779132 小时前
通过AWS Transfer Family集成Active Directory实现安全SFTP文件访问
安全·云计算·aws
DisonTangor2 小时前
腾讯开源混元翻译——HY-MT1.5
学习·自然语言处理·开源·aigc
youxiao_902 小时前
Docker 容器(四)
运维·docker·容器
深耕AI2 小时前
【深析】 Docker Desktop 中的容器文件系统:OverlayFS vs Containerd Snapshots
运维·docker·容器