科技新知

在構建投産環境時,如果 server 群沒有互聯網,又或對私隱很有要求,需要自建一個最簡單的 registry ,可以用這個。當然,那台機第一次必需經互聯網。架起後就可以斷網,並由其他 client 提送新的 registry image更新。

Registry Server 起動方式

最簡單的起動方式,但什麼都不設定。 

docker run -d -p 5000:5000 --name registry registry:3

若想要加入 SSL,讓你的 client 不會認為它是不安全的 registry ,最簡易可以寫成 docker compose, 由 docker compose up -d 執行。

# docker-compose.ymlregistry:restart:alwaysimage:registry:3ports:-5000:5000environment:REGISTRY_HTTP_TLS_CERTIFICATE:/certs/domain.crtREGISTRY_HTTP_TLS_KEY:/certs/domain.keyvolumes:-/path/data:/var/lib/registry-/path/certs:/certs

上述的 environment 中,有條件的話,還請設定需要登入才能訪問限制。最簡單,可以使用 apache http header 驗證方式。

# docker-compose.yml
registry:
  restart: always
  image: registry:3
  ports:
    - 5000:5000
  environment:
    REGISTRY_HTTP_TLS_CERTIFICATE: /certs/domain.crt
    REGISTRY_HTTP_TLS_KEY: /certs/domain.key
+   REGISTRY_AUTH: htpasswd+   REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd+   REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
  volumes:
    - /path/data:/var/lib/registry
    - /path/certs:/certs
+   - /path/auth:/auth

REGISTRY_AUTHREGISTRY_AUTH_HTPASSWD_PATHREGISTRY_AUTH_HTPASSWD_REALM 的值照抄就好,然後/path/auth/htpasswd 就需要以 htpasswd 的格式提供內容 apache password_encryptions。即是以下那個樣子 

USERNAME_1:BCRYPT_HASH_1
USERNAME_2:BCRYPT_HASH_2
USERNAME_3:BCRYPT_HASH_3

Client 連線方式

一切都設定好後,在 client 端,就可以登入並推送你的 image,(題外話,cli登入的都是以明文的方式存在電腦中,所以不要隨便在公開的地方存入自己的帳號)

 
# login
docker login YOUR_DOMAIN:5000
# try re-upload image
docker image tag registry:3 YOUR_DOMAIN:5000/registry:3
docker image push YOUR_DOMAIN:5000/registry:3

如果 server 端沒有提供SSL,那麼 client 就只能設定 http 的不安全連線。 https://distribution.github.io/distribution/about/insecure/

修改 client 端的 /etc/docker/daemon.json (Windows Docker Desktop請經 Gui修改),然後重啟 client 端的 docker

 
{
  "insecure-registries" : ["YOUR_DOMAIN:5000"]
}

Registry Server 維護 - Garbage collection 垃圾回收

當我們設立了自己的 Registry 倉庫之後,少不免就是要維護硬碟的用量。很多過期的 Image ,沒有需要,那就手動刪除,然後進行 Garbage collection (垃圾回收)。另一種情況,就如前述教學中,大家使用統一版本號,例如 latest ,表面上看似只有一個 tag ,但其實底下可能已經藏有多個不同的版本,也需要經過Garbage collection來清理空間。

因為回收過程比較危險,所以官方並不建議自動做,以下就簡單講講為了做刪除和回收,設定檔要怎樣改。為方便改設定,我們更新 docker compose yaml 檔,把 server config 都帶到 container 外面。

 
registry:
  restart: always
  image: registry:3
  ports:
    - 5000:5000
  environment:
    REGISTRY_HTTP_TLS_CERTIFICATE: /certs/domain.crt
    REGISTRY_HTTP_TLS_KEY: /certs/domain.key
    REGISTRY_AUTH: htpasswd
    REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
    REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
  volumes:
    - /path/data:/var/lib/registry
    - /path/certs:/certs
    - /path/auth:/auth
+   - /path/config.yml:/etc/distribution/config.yml

config.yml 就如下所示,為了提供 API 刪除 image 的可能,storage.delete.enbled 要為 true,又為著之後進行回收時,可以避免有人於回收中途上載,所以預先加入 storage.maintenance.readonly.enabled 的控制項。回收之前要把readonly改為true,回收後再調為false。 每次修改完,記得重啟一下 docker service 。

 
storage:filesystem:rootdirectory:/var/lib/registrydelete:enabled:truemaintenance:readonly:enabled:false

Garbage collection 指令

 
# inside container# bin/registry garbage-collect [--dry-run] [--delete-untagged] [--quiet] /path/to/config.yml
bin/registry garbage-collect --delete-untagged=true /etc/docker/registry/config.yml

# outside container, at host level
docker exec -it YOUR_CONATINER_NAME bin/registry garbage-collect --delete-untagged=true /etc/docker/registry/config.yml

馬交野