科技新知
Docker Swarm - Private Registry 私有影像倉庫
在構建投産環境時,如果 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_AUTH
, REGISTRY_AUTH_HTPASSWD_PATH
, REGISTRY_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