遇過非常多人使用 Distribution 和 RHEL 來建立人生第一個容器映像檔倉庫 (Container Registry) 時,都會遇到 SSL/TLS 相關的問題,大多都是用 insecure-registries 來避掉,今天要來分享自簽憑證的作法
系統規格
- Hostname: registry.lab.test
- IP: 10.0.100.7/24
- Necessary Software
- Distribution 3.1.2,使用官方容器映像
- RHEL 9 / 10
- Podman、OpenSSL 3、Skopeo,使用對應 RHEL 套件庫提供的版本
安裝過程
準備 OS
Firewalld 開啟、SELinux 保持 Enforcing- 以 RHEL 9/10 為核心,已配置有效的 BaseOS、AppStream 套件庫
- 以下指令以 root 執行,使用 rootful Podman;RHEL 9/10 可使用相同指令,但套件版本與預設設定可能不同
- 伺服器與客戶端均需透過 DNS 或
/etc/hosts 將 registry.lab.test 解析到 10.0.100.7
Docker Distribution
安裝 Distribution
1
2
3
| dnf install -y podman openssl firewalld ca-certificates
install -d -m 0750 /etc/distribution/certs /var/lib/registry
podman pull docker.io/library/registry:3.1.2
|
RHEL 9/10 使用 Podman 執行官方映像,設定與憑證統一放在 /etc/distribution。
設定 Distribution
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| cat << 'EOF' > /etc/distribution/config.yml
---
version: 0.1
log:
fields:
service: registry
storage:
cache:
blobdescriptor: inmemory
filesystem:
rootdirectory: /var/lib/registry
http:
addr: 0.0.0.0:5000
host: https://registry.lab.test:5000
tls:
certificate: /etc/distribution/certs/registry.crt
key: /etc/distribution/certs/registry.key
EOF
|
依據上述的設定檔,/var/lib/registry 是指定主要放置 Container Images 檔案的位置,後面會掛載主機的同一路徑;:5000 開的 Port 預設是 5000,但可以依據需求修改;certificate、key 則是放置 SSL/TLS 的憑證和金鑰,後面會講怎麼快速自簽;若想要瞭解更多的設定檔,可以參考 Distribution - Configuring a registry
自簽 OpenSSL
1
2
3
4
5
6
7
| umask 077
openssl req -x509 -noenc -sha256 -days 365 -newkey rsa:2048 \
-keyout /etc/distribution/certs/registry.key \
-out /etc/distribution/certs/registry.crt \
-subj "/CN=registry.lab.test" \
-addext "subjectAltName=DNS:registry.lab.test,IP:10.0.100.7"
chmod 0600 /etc/distribution/certs/registry.key
|
注意 subjectAltName 務必要填自己的 hostname;若要透過 IP 存取,也要填入對應的 IP。現代客戶端不能只靠 Common Name 驗證 hostname。RHEL 9/10 的 OpenSSL 3 可使用 -noenc 和 -addext,不需要互動式填寫憑證欄位。
在 RHEL 匯入自簽憑證:
1
2
3
4
5
| openssl x509 \
-in /etc/distribution/certs/registry.crt \
-out /etc/pki/ca-trust/source/anchors/workstation.pem \
-outform PEM
update-ca-trust
|
建議把 /etc/distribution/certs/registry.crt 透過可信管道提供給其他機器,未來只要有需要用到該 Container Registry 的 RHEL 客戶端,都要執行上面的動作匯入憑證,並將 -in 改成該機器實際存放憑證的位置;不要提供 .key 私鑰檔案。
啟動 Distribution
1
2
3
4
5
6
7
8
9
10
| podman run -d --name registry --restart=always \
--publish 10.0.100.7:5000:5000 \
--volume /etc/distribution:/etc/distribution:ro,Z \
--volume /var/lib/registry:/var/lib/registry:Z \
--env OTEL_TRACES_EXPORTER=none \
docker.io/library/registry:3.1.2 \
serve /etc/distribution/config.yml
systemctl enable podman-restart.service
podman logs registry
|
:Z 會設定容器需要的 SELinux 標籤,:ro 將設定和憑證目錄設為唯讀。podman-restart.service 用來在主機開機後恢復這個 rootful 容器;修改設定或憑證後,執行 podman restart registry。
此範例只設定 TLS,不含登入驗證,僅供受控網路測試。
啟用 Firewall
先用 firewall-cmd --get-active-zones 確認網卡所屬區域;以下以 public 為例,請依環境調整:
1
2
3
4
5
6
| systemctl enable --now firewalld
firewall-cmd --get-active-zones
firewall-cmd --zone=public --add-port=5000/tcp --permanent
firewall-cmd --reload
podman network reload registry
firewall-cmd --zone=public --list-all
|
驗證 Container Registry
1
2
3
4
5
6
7
| dnf install -y skopeo
skopeo copy --all \
docker://docker.io/library/alpine:3.24.3 \
docker://registry.lab.test:5000/library/alpine:3.24.3
skopeo inspect docker://registry.lab.test:5000/library/alpine:3.24.3
|
--all 會一併複製多平台映像;測試映像改用 Alpine,避免沿用已停止維護的 CentOS 7。
結語
整個過程其實蠻簡單的,大概不用半小時就可以建立完,但他能提供的功能,就是非常基本中的基本 - 放映像檔,若要尋求多功能的 Container Registry,可以考慮使用紅帽宣布 Red Hat Introduces open source Project Quay container registry 的 Project Quay,比較符合現實生活。
References