podman ローカル プライベート レジストリの構築
インストール
$ sudo dnf install -y podman httpd-tools
メタデータの期限切れの最終確認: 1:14:37 前の 2024年03月19日 06時13分34秒 に実施しました。 パッケージ podman-5:4.9.3-1.fc39.x86_64 は既にインストールされています。 パッケージ httpd-tools-2.4.58-1.fc39.x86_64 は既にインストールされています。 依存関係が解決しました。 行うべきことはありません。 完了しました!
レジストリ構築
レジストリ用のディレクトリを作成🤔
$ sudo mkdir -p /var/lib/registry/{auth,certs,data} && sudo ls -al /var/lib/registry
合計 0 drwxr-xr-x 1 root root 26 3月 19 07:36 . drwxr-xr-x. 1 root root 1042 3月 19 07:36 .. drwxr-xr-x 1 root root 0 3月 19 07:36 auth drwxr-xr-x 1 root root 0 3月 19 07:36 certs drwxr-xr-x 1 root root 0 3月 19 07:36 data
レジストリ認証用の htpasswd ファイルを作成🤔
$ sudo htpasswd -cB /var/lib/registry/auth/htpasswd tomoyan
New password: password 入力 Re-type new password: 確認 password 入力 Adding password for user tomoyan
$ sudo bat -n /var/lib/registry/auth/htpasswd
1 tomoyan:$2y$05$MO8AFjpgWM5mVvYxbDpeIeWntMr0jxkkQ6krWEZ04n39RA73F2PWC
htpasswd の使い方 🤤
$ htpasswd
Usage: htpasswd [-cimBdpsDv] [-C cost] passwordfile username htpasswd -b[cmBdpsDv] [-C cost] passwordfile username password htpasswd -n[imBdps] [-C cost] username htpasswd -nb[mBdps] [-C cost] username password -c Create a new file. -n Don't update file; display results on stdout. -b Use the password from the command line rather than prompting for it. -i Read password from stdin without verification (for script usage). -m Force MD5 encryption of the password (default). -2 Force SHA-256 crypt() hash of the password (very secure). -5 Force SHA-512 crypt() hash of the password (very secure). -B Force bcrypt encryption of the password (very secure). -C Set the computing time used for the bcrypt algorithm (higher is more secure but slower, default: 5, valid: 4 to 17). -r Set the number of rounds used for the SHA-256, SHA-512 algorithms (higher is more secure but slower, default: 5000). -d Force CRYPT encryption of the password (8 chars max, insecure). -s Force SHA-1 encryption of the password (insecure). -p Do not encrypt the password (plaintext, insecure). -D Delete the specified user. -v Verify password for the specified user. On other systems than Windows and NetWare the '-p' flag will probably not work. The SHA-1 algorithm does not use a salt and is less secure than the MD5 algorithm.
使用法: htpasswd [-cimBdpsDv] [-C cost] passwordfile username htpasswd -b[cmBdpsDv] [-C cost] passwordfile username password htpasswd -n[imBdps] [-C cost] username htpasswd -nb[mBdps] [-C cost] username password -c 新しいファイルを作成します。 -n ファイルを更新しません。結果を標準出力に表示します。 -b パスワードを要求するのではなく、コマンドラインからパスワードを使用します。 -i 検証なしで標準入力からパスワードを読み取ります (スクリプト使用のため)。 -m パスワードの MD5 暗号化を強制します (デフォルト)。 -2 パスワードの SHA-256 crypt() ハッシュを強制します (非常に安全)。 -5 パスワードの SHA-512 crypt() ハッシュを強制します (非常に安全)。 -B パスワードの bcrypt 暗号化を強制します (非常に安全です)。 -C bcrypt アルゴリズムに使用される計算時間を設定します。 (値が高いほど安全ですが速度は遅くなります、デフォルト: 5、有効: 4 ~ 17)。 -r SHA-256、SHA-512 アルゴリズムに使用されるラウンド数を設定します。 (値が高いほど安全性は高くなりますが、速度は遅くなります。デフォルト: 5000)。 -d パスワードの CRYPT 暗号化を強制します (最大 8 文字、安全ではありません)。 -s パスワードの SHA-1 暗号化を強制します (安全ではありません)。 -p パスワードを暗号化しません (平文、安全ではありません)。 -D 指定したユーザーを削除します。 -v 指定されたユーザーのパスワードを確認します。 Windows および NetWare 以外のシステムでは、'-p' はおそらくフラグは機能しないでしょう。 SHA-1 アルゴリズムはソルトを使用しないため、MD5 アルゴリズムよりも安全性が低くなります。
自己署名 SSL 証明書の作成🤔
ここではファイル名 wicked-beat.crt を作成する
$ sudo openssl req -newkey rsa:4096 -nodes -sha256 -keyout /var/lib/registry/certs/wicked-beat.key \ -x509 -days 365 -out /var/lib/registry/certs/wicked-beat.crt \ -subj "/CN=localhost,wicked-beat,wicked-beat.fireball.lan" \ -addext "subjectAltName=DNS:localhost,DNS:wicked-beat,DNS:wicked-beat.fireball.lan"
..+..........+..+......+.+.........+...........+......+....+.....+.........+.+++++++++++++++++++++++++++++++++++++++++++++*......+.+..+.......+......+..+...+....+..................+..+...+.+.........+..+.........+....+...+..+.+....................+.+......+..+.......+...........+...+.+.....+......+++++++++++++++++++++++++++++++++++++++++++++*...+............+...+++++ .....+.+.....+.........+......+...+..........+..+.+++++++++++++++++++++++++++++++++++++++++++++*..........+.......+..+..........+...+..+......+...+.......+.....+.......+.....+.+......+++++++++++++++++++++++++++++++++++++++++++++*....+.....+......+............+..........+...+...+..+.........+....+...........+......+...+..........+...............+............+............+.....+...+.......+...+............+.................+....+.....+.........+......+......+.+...+......+.....+.+.....+....+...+...+..+...+.......+..+.....................+.......+........+...+.+......+.................+.............+.........+...+..+........................+.......+...+..+++++ -----
作成された自己署名 SSL 証明書の内容確認🤔
$ sudo openssl x509 -in /var/lib/registry/certs/wicked-beat.crt -text -noout
Certificate: Data: Version: 3 (0x2) Serial Number: 26:86:56:c8:1a:fa:0c:32:13:7b:87:54:10:de:66:12:98:f5:b6:28 Signature Algorithm: sha256WithRSAEncryption Issuer: CN = "localhost,wicked-beat,wicked-beat.fireball.local" Validity Not Before: Mar 20 20:16:18 2024 GMT Not After : Mar 20 20:16:18 2025 GMT Subject: CN = "localhost,wicked-beat,wicked-beat.fireball.lan" Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (4096 bit) Modulus: 00:99:f1:8c:dd:3b:6e:53:8a:1d:79:47:03:d8:48: 21:de:03:79:af:7c:0e:ff:e8:61:b2:48:45:a9:a5: 〜省略〜 41:f8:cb:9c:f2:98:43:85:ab:86:80:27:cc:10:b8: ac:5b:41 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: B5:65:A6:BB:E7:BF:E4:DF:9E:E8:FF:FE:11:5D:80:72:FB:F6:CF:8B X509v3 Authority Key Identifier: B5:65:A6:BB:E7:BF:E4:DF:9E:E8:FF:FE:11:5D:80:72:FB:F6:CF:8B X509v3 Basic Constraints: critical CA:TRUE X509v3 Subject Alternative Name: DNS:localhost, DNS:wicked-beat, DNS:wicked-beat.fireball.lan Signature Algorithm: sha256WithRSAEncryption Signature Value: 68:9e:7f:a9:17:6e:86:83:16:fb:2b:45:7b:20:bb:5b:7e:7e: c9:77:45:ce:f6:a2:05:c2:c5:cb:9f:22:2b:aa:90:2e:0d:e7: 〜省略〜 ae:c7:0b:d1:19:72:15:2d:67:db:fe:b7:d0:46:c0:87:dc:c1: aa:e9:3b:ce:e8:5c:11:e0
クライアント/ホストでの SSL 証明書の信頼🤔
$ sudo cp /var/lib/registry/certs/wicked-beat.crt /etc/pki/ca-trust/source/anchors/ $ sudo update-ca-trust $ trust list | grep -i "wicked-beat"
label: localhost,wicked-beat,wicked-beat.fireball.lan
ホストのファイアウォールを設定🤔
$ sudo firewall-cmd --add-port=5000/tcp --zone=internal --permanent
success
$ sudo firewall-cmd --add-port=5000/tcp --zone=public --permanent
success
$ sudo firewall-cmd --reload
success
レジストリの起動/停止
最新バージョンは registry Tags | Docker Hub で確認できる🤔
レジストリの起動🤔
$ sudo podman run -d --restart always --name registry \ -p 5000:5000 \ -v /var/lib/registry/data:/var/lib/registry:z \ -v /var/lib/registry/auth:/auth:z \ -e 'REGISTRY_AUTH=htpasswd' \ -e 'REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm' \ -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \ -v /var/lib/registry/certs:/certs:z \ -e 'REGISTRY_HTTP_TLS_CERTIFICATE=/certs/wicked-beat.crt' \ -e 'REGISTRY_HTTP_TLS_KEY=/certs/wicked-beat.key' \ -e REGISTRY_COMPATIBILITY_SCHEMA1_ENABLED=true \ -e REGISTRY_STORAGE_DELETE_ENABLED=true \ docker.io/library/registry:2.8.3
Trying to pull docker.io/library/registry:2.8.3... Getting image source signatures Copying blob 5daf2fb85fb9 done | Copying blob 68c26f40ad80 done | Copying blob 8f2a82336004 done | Copying blob ca5f23059090 done | Copying blob 619be1103602 done | Copying config 9363667f8a done | Writing manifest to image destination 304e2169d684ff81b5dd76f0de4a49035c73d1d7c70d59c4306feac5b66779be
レジストリを停止する場合…🤔
$ sudo sh -c 'podman stop registry && podman rm registry'
レジストリへのアクセス確認🤔
$ curl -u tomoyan https://wicked-beat:5000/v2/_catalog
Enter host password for user 'tomoyan': {"repositories":[]}
registry registry
証明書の検証🤔
$ openssl s_client -connect wicked-beat:5000 -servername wicked-beat
CONNECTED(00000003) depth=0 CN = "localhost,wicked-beat,wicked-beat.fireball.local" verify return:1 --- Certificate chain 0 s:CN = "localhost,wicked-beat,wicked-beat.fireball.local" i:CN = "localhost,wicked-beat,wicked-beat.fireball.local" a:PKEY: rsaEncryption, 4096 (bit); sigalg: RSA-SHA256 v:NotBefore: Mar 20 20:20:12 2024 GMT; NotAfter: Mar 20 20:20:12 2025 GMT --- Server certificate -----BEGIN CERTIFICATE----- MIIFeTCCA2GgAwIBAgIUItMtxtFJlg4OwxuJ/3QYs5TB5JEwDQYJKoZIhvcNAQEL BQAwMTEvMC0GA1UEAwwmd2lja2VkLWJlYXQsd2lja2VkLWJlYXQuZmlyZWJhbGwu bG9jYWwwHhcNMjQwMzIwMjAyMDEyWhcNMjUwMzIwMjAyMDEyWjAxMS8wLQYDVQQD 〜省略〜 I72x52OQk9dfvXp2yiXhTSjZVcqY2axwvdEm8dA7kBE+vImTbxUJYzGWetMo3n4a oZEMw11w4NNmuw1fvw== -----END CERTIFICATE----- subject=CN = "localhost,wicked-beat,wicked-beat.fireball.local" issuer=CN = "localhost,wicked-beat,wicked-beat.fireball.local" --- No client certificate CA names sent Peer signing digest: SHA256 Peer signature type: RSA-PSS Server Temp Key: X25519, 253 bits --- SSL handshake has read 2201 bytes and written 379 bytes Verification: OK --- New, TLSv1.3, Cipher is TLS_CHACHA20_POLY1305_SHA256 Server public key is 4096 bit This TLS version forbids renegotiation. Compression: NONE Expansion: NONE No ALPN negotiated Early data was not sent Verify return code: 0 (ok) --- --- Post-Handshake New Session Ticket arrived: SSL-Session: Protocol : TLSv1.3 Cipher : TLS_CHACHA20_POLY1305_SHA256 Session-ID: A930863BF5140DE8683A6A979F0BA450D05FE1871A5DF7C41B21412014C626BB Session-ID-ctx: Resumption PSK: 8A1A0CC8DBCD3534B4B3BD4572450A4DE453E6FB693AFCC8A371F8BAA22D33AE PSK identity: None PSK identity hint: None SRP username: None TLS session ticket lifetime hint: 604800 (seconds) TLS session ticket: 0000 - 43 d1 3e 3d 52 05 5d 46-04 5a 5e 6c 78 f3 be 80 C.>=R.]F.Z^lx... 0010 - 13 48 4b 79 4a df 76 2b-e0 29 5f 5b e1 81 e3 f6 .HKyJ.v+.)_[.... 0020 - 16 b3 4a 66 84 78 41 26-22 4b 5e a9 f6 0a 5f f6 ..Jf.xA&"K^..._. 0030 - 84 45 b9 da 86 77 e2 cf-d6 ac bf c1 6b ac 9d 7d .E...w......k..} 0040 - d9 5a eb 61 9c e4 f6 8f-10 8e 0e 99 37 70 a5 75 .Z.a........7p.u 0050 - 38 e0 3b f3 2f fa b9 fb-60 d4 82 6e 8a cb 55 56 8.;./...`..n..UV 0060 - 49 5a 21 6f 1a 25 31 ca-26 c2 ce 22 00 0e a7 e1 IZ!o.%1.&..".... 0070 - 28 ( Start Time: 1710966295 Timeout : 7200 (sec) Verify return code: 0 (ok) Extended master secret: no Max Early Data: 0 --- read R BLOCK
レジストリにログインする🤔
$ podman login wicked-beat:5000
Username: tomoyan Password: Login Succeeded!
ログイン中の認証情報は /run/user/<gid>/containers/auth.json
に base64 エンコードで保存されている🤔
$ bat -n /run/user/1000/containers/auth.json
1 { 2 "auths": { 3 "wicked-beat:5000": { 4 "auth": "aB1cd2efghiJklMnOPQ3STUv" 5 } 6 } 7 }
レジストリからログアウトする🤔
$ podman logout wicked-beat:5000
Removed login credentials for wicked-beat:5000
$ bat -n /run/user/1000/containers/auth.json
1 { 2 "auths": {} 3 }
レジストリへのプッシュ/プル
ログインする🤔
$ podman login wicked-beat:5000
Username: tomoyan Password: Login Succeeded!
プッシュする🤔
$ podman push localhost/haruo_podman:0.01 wicked-beat:5000/haruo_podman:v0.01
Getting image source signatures Copying blob 10650e391d43 done | Copying blob aacbd0b4169c done | Copying blob 80f811a7d4fe done | Copying blob 53f86715cdba done | Copying blob eb2eb8ccdc68 done | Copying config f291a9bf30 done | Writing manifest to image destination
プッシュされた内容を確認する🤔
$ podman search wicked-beat:5000/
NAME DESCRIPTION wicked-beat:5000/haruo_podman
削除してみる🤔
$ skopeo --debug delete docker://wicked-beat:5000/haruo_podman:v0.01
DEBU[0000] Using registries.d directory /etc/containers/registries.d DEBU[0000] Loading registries configuration "/etc/containers/registries.conf" DEBU[0000] Loading registries configuration "/etc/containers/registries.conf.d/000-shortnames.conf" DEBU[0000] Found credentials for wicked-beat:5000/haruo_podman in credential helper containers-auth.json in file /run/user/1000/containers/auth.json DEBU[0000] No signature storage configuration found for wicked-beat:5000/haruo_podman:v0.01, using built-in default file:///home/tomoyan/.local/share/containers/sigstore DEBU[0000] Looking for TLS certificates and private keys in /etc/docker/certs.d/wicked-beat:5000 DEBU[0000] GET https://wicked-beat:5000/v2/ DEBU[0000] Ping https://wicked-beat:5000/v2/ status 401 DEBU[0000] GET https://wicked-beat:5000/v2/haruo_podman/manifests/v0.01 DEBU[0000] DELETE https://wicked-beat:5000/v2/haruo_podman/manifests/sha256:f652ef85a8862285775a01c6dd279c35debd0b581c41e209875c3ab1d3ceacd7 DEBU[0000] Deleting /home/tomoyan/.local/share/containers/sigstore/haruo_podman@sha256=f652ef85a8862285775a01c6dd279c35debd0b581c41e209875c3ab1d3ceacd7/signature-1
削除しても消えないが、配布には使える🤪
$ podman search wicked-beat:5000/
NAME DESCRIPTION wicked-beat:5000/haruo_podman
プッシュしたら二度と消せない🤪
コンテナ起動時に REGISTRY_STORAGE_DELETE_ENABLED=true も指定してるし、docker v2 API で DELETE も実行している🤔
$ skopeo --debug delete docker://wicked-beat:5000/haruo_podman:v0.01
DEBU[0000] Using registries.d directory /etc/containers/registries.d DEBU[0000] Loading registries configuration "/etc/containers/registries.conf" DEBU[0000] Loading registries configuration "/etc/containers/registries.conf.d/000-shortnames.conf" DEBU[0000] Found credentials for wicked-beat:5000/haruo_podman in credential helper containers-auth.json in file /run/user/1000/containers/auth.json DEBU[0000] No signature storage configuration found for wicked-beat:5000/haruo_podman:v0.01, using built-in default file:///home/tomoyan/.local/share/containers/sigstore DEBU[0000] Looking for TLS certificates and private keys in /etc/docker/certs.d/wicked-beat:5000 DEBU[0000] GET https://wicked-beat:5000/v2/ DEBU[0000] Ping https://wicked-beat:5000/v2/ status 401 DEBU[0000] GET https://wicked-beat:5000/v2/haruo_podman/manifests/v0.01 FATA[0000] Unable to delete wicked-beat:5000/haruo_podman:v0.01. Image may not exist or is not stored with a v2 Schema in a v2 registry
参考文献
How to implement a simple personal/private Linux container image registry for internal use | Enable Sysadmin 翻訳
Tutorial: Host a Local Podman Image Registry - The New Stack 翻訳
quay/quay: Build, Store, and Distribute your Applications and Containers
quay/docs/quick-local-deployment.md at master · quay/quay
Deploy Red Hat Quay - Basic Red Hat Quay 2.9 | Red Hat Customer Portal 翻訳