博客 / 詳情

返回

RustFS x Distribution Registry, 私有化鏡像倉庫的 SSOT 構建之道

容器鏡像倉庫是應用容器化部署的必選項,頂級玩家 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 中。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.