ベアメタル環境など、共有可能なオブジェクトストレージを提供しないプラットフォーム上に OpenShift/OKD クラスタを構築した場合、デフォルトでは Image Registry が無効になっている。本記事では、OKD4 で Image Registry を有効化する手順を説明する。
前提条件
- Container CLI:
docker
,podman
,nerdctl
, etc. - OKD4 cluster
- OpenShift Data Foundation
手順
手順は次の公式ドキュメントに従う:
Image Registry の有効化
Image Registry Operator が稼働していることを確認する:
$ oc get clusteroperator image-registry
NAME VERSION AVAILABLE PROGRESSING DEGRADED SINCE MESSAGE
image-registry 4.15.0-0.okd-2024-03-10-010116 True False False 16h
次に、spec.managementState
を Removed
から Managed
に編集する。
次のコマンドを実行し、Image Registry を有効化する:
oc patch configs.imageregistry.operator.openshift.io cluster --type merge --patch '{"spec":{"managementState":"Managed"}}'
ここで再度 Image Registry Operator を検索する:
$ oc get clusteroperator image-registry
NAME VERSION AVAILABLE PROGRESSING DEGRADED SINCE MESSAGE
image-registry 4.15.0-0.okd-2024-03-10-010116 False False True 14m Available: Error: storage backend not configured...
今度は Available
カラムが False
になり、MESSAGE
カラムが Available: Error: storage backend not configured...
が表示されている。
これは、Image Registry は有効化されたものの、まだストレージバックエンドがまだ用意されておらず、エラーを吐いている状態である。
ストレージバックエンドの作成
各種クラウドサービスで構築した S3 bucket や、ベアメタル環境で構築した PV などを指定することができる。
(公式ドキュメンテーションにさまざまなプラットフォームにおける設定例があるので、詳しくはそちらを参照:Image Registry Operator in OKD | Registry | OKD 4.15)
本節では、OpenShift 上のストレージ統合基盤 ODF 上に S3 bucket を作成し、それを Image Registry のストレージバックエンドに指定する方法を説明する。
ODF の導入が済んでいない場合は次の Qiita 記事も参照:
namespace の切り替え
Image Regsitry 用の project openshift-image-registry
に切り替える:
$ oc project openshift-image-registry
Now using project "openshift-image-registry" on server "https://api.ocp4.example.com:6443".
# 確認
$ oc project openshift-image-registry
Already on project "openshift-image-registry" on server "https://api.sno.example.com:6443".
S3 bucket の作成
次の Object Bucket Claim を発行し、openshift-storage
namespace 内に S3 bucket を作成する:
$ cat <<EOF | oc apply -f -
apiVersion: objectbucket.io/v1alpha1
kind: ObjectBucketClaim
metadata:
name: noobaatest
namespace: openshift-storage
spec:
storageClassName: openshift-storage.noobaa.io
generateBucketName: noobaatest
EOF
bucket が作成されたことを確認する:
$ oc get objectbucket
NAME STORAGE-CLASS CLAIM-NAMESPACE CLAIM-NAME RECLAIM-POLICY PHASE AGE
obc-openshift-storage-noobaatest openshift-storage.noobaa.io Delete Bound 11s
bucket 名を取得する:
bucket_name=$(oc get obc -n openshift-storage noobaatest -o jsonpath='{.spec.bucketName}')
bucket の AWS credential keys を取得する:
AWS_ACCESS_KEY_ID=$(oc get secret -n openshift-storage noobaatest -o yaml | grep -w "AWS_ACCESS_KEY_ID:" | head -n1 | awk '{print $2}' | base64 --decode)
AWS_SECRET_ACCESS_KEY=$(oc get secret -n openshift-storage noobaatest -o yaml | grep -w "AWS_SECRET_ACCESS_KEY:" | head -n1 | awk '{print $2}' | base64 --decode)
bucket の AWS credential keys を Secret に登録する:
oc create secret generic image-registry-private-configuration-user --from-literal=REGISTRY_STORAGE_S3_ACCESSKEY=${AWS_ACCESS_KEY_ID} --from-literal=REGISTRY_STORAGE_S3_SECRETKEY=${AWS_SECRET_ACCESS_KEY} --namespace openshift-image-registry
bucket のエンドポイントを取得する。
BUCKET_URL=$(oc get route s3 -n openshift-storage -o=jsonpath='{.spec.host}')
確認:
$ echo $BUCKET_URL
s3-openshift-storage.apps.ocp4.example.com
Ingress に TLS アクセスするための certification をダウンロードする:
oc extract secret/$(oc get ingresscontroller -n openshift-ingress-operator default -o json | jq '.spec.defaultCertificate.name // "router-certs-default"' -r) -n openshift-ingress --confirm
確認:
$ ls
tls.crt tls.key
tls.crt
を Config Map に入れる:
oc create configmap image-registry-s3-bundle --from-file=ca-bundle.crt=./tls.crt -n openshift-config
上記手順で準備した bucket の URLを、Image Registry のストレージバックエンドに設定する:
oc patch config.image/cluster -p '{"spec":{"managementState":"Managed","replicas":2,"storage":{"managementState":"Unmanaged","s3":{"bucket":'\"${bucket_name}\"',"region":"us-east-1","regionEndpoint":'\"https://${BUCKET_URL}\"',"virtualHostedStyle":false,"encrypt":false,"trustedCA":{"name":"image-registry-s3-bundle"}}}}}' --type=merge
1分ほど待つと、Imager Registry Operator の AVAILABLE
カラムが再び True
になる。
$ oc get clusteroperator image-registry
NAME VERSION AVAILABLE PROGRESSING DEGRADED SINCE MESSAGE
image-registry 4.15.0-0.okd-2024-03-10-010116 True False False 94s
Image Registry の公開
今の状態だと、OKD node 上に直接入らないとレジストリにアクセスできない。
外部から利用可能にするには TLS を用いたアクセスを有効にする。
Image Registry への Route の作成
defaultRoute
を true
に設定する:
oc patch configs.imageregistry.operator.openshift.io/cluster --patch '{"spec":{"defaultRoute":true}}' --type=merge
しばらく待つと Image Registry のエンドポイントが作成される:
REGISTRY_URL=$(oc get route default-route -n openshift-image-registry --template='{{ .spec.host }}')
確認:
$ echo $REGISTRY_URL
default-route-openshift-image-registry.apps.ocp4.example.com
TLS 設定
docker, podman などのコンテナ CLI から、TLS 経由で Image Registry アクセスできるようにする。
この設定方法はクライアント側の OS に依存する。例として Fedora系 OS, Debian 系 OS における設定方法をあげる。
Fedora 系 OS の場合
CA_DIR=/etc/pki/ca-trust/source/anchors/
oc get secret -n openshift-ingress router-certs-default -o go-template='{{index .data "tls.crt"}}' | base64 -d | sudo tee ${CA_DIR}/${REGISTRY_URL}.crt > /dev/null
sudo update-ca-trust enable
Debian 系 OS の場合
CA_DIR=/etc/ssl/certs/
oc get secret -n openshift-ingress router-certs-default -o go-template='{{index .data "tls.crt"}}' | base64 -d | sudo tee ${CA_DIR}/${REGISTRY_URL}.crt > /dev/null
sudo update-ca-certificates
レジストリの動作確認
OpenShift の kubeadmin
ユーザの認証情報を利用して Image Registry にアクセスする。
Image Registry のエンドポイントにアクセスできることを確認する:
oc login -u kubeadmin -p <password_from_install_log>
REGISTRY_URL=$(oc get route default-route -n openshift-image-registry --template='{{ .spec.host }}')
REGISTRY_CA=${CA_DIR}/${REGISTRY_URL}.crt
curl -ks --cacert $REGISTRY_CA -u kubeadmin:$(oc whoami -t) https://$REGISTRY_URL/v2/_catalog | jq
出力例:
$ curl -ks --cacert $REGISTRY_CA -u kubeadmin:$(oc whoami -t)
https://$REGISTRY_URL/v2/_catalog | jq
{
"repositories": [
"openshift/cli",
"openshift/cli-artifacts",
"openshift/dotnet",
"openshift/dotnet-runtime",
"openshift/driver-toolkit",
"openshift/golang",
"openshift/httpd",
"openshift/installer",
"openshift/installer-artifacts",
"openshift/java",
"openshift/java-runtime",
"openshift/jenkins",
"openshift/jenkins-agent-base",
"openshift/mariadb",
"openshift/must-gather",
"openshift/mysql",
"openshift/network-tools",
"openshift/nginx",
"openshift/nodejs",
"openshift/oauth-proxy",
"openshift/openliberty",
"openshift/perl",
"openshift/php",
"openshift/postgresql",
"openshift/python",
"openshift/redis",
"openshift/ruby",
"openshift/tests",
"openshift/tools",
"openshift/ubi8-openjdk-11-runtime",
"openshift/ubi8-openjdk-17-runtime",
"openshift/ubi8-openjdk-8-runtime",
"openshift/wildfly-runtime",
"openshift/wildfly-s2i"
]
}
コンテナイメージの push/pull
Image Registry にログインする
$ podman login -u kubeadmin -p $(oc whoami -t) $REGISTRY_URL
Login Succeeded!
$ podman login --get-login $REGISTRY_URL
kubeadmin
テスト用にプロジェクト test-project
を作成する。
$ oc new-project test-project
次に、テスト用に push するコンテナイメージを適当に用意する。
なんでもいいのだが、例として ubuntu
を引っ張ってくる:
$ podman pull docker.io/library/ubuntu
これを Image Registry にpush する。
push の際、イメージ名は <project-name>/<image-name>:<tag>
のフォーマットに従う必要がある。OpenShift クラスタ 上に存在しないプロジェクト名を <project-name>
に指定した場合はエラーになるので注意。
$ podman push ubuntu ${REGISTRY_URL}/test-project/ubuntu:latest
Getting image source signatures
Copying blob 42d3f8788282 done
Copying config 17c0145030 done
Writing manifest to image destination
Error: writing manifest "{\"schemaVersion\":2,\"mediaType\":\"application/vnd.oci.image.manifest.v1+json\",\"config\":{\"mediaType\":\"application/vnd.oci.image.config.v1+json\",\"digest\":\"sha256:17c0145030df106e60e5d99149d69810db23b869ff0d3c9d236279a5a7bbb6b3\",\"size\":2295},\"layers\":[{\"mediaType\":\"application/vnd.oci.image.layer.v1.tar+gzip\",\"digest\":\"sha256:cbd3aad7b8c34bcdfbb02d9ff325c3f75dde860a88eccb7b9def49535b729911\",\"size\":30937352}]}": uploading manifest latest to default-route-openshift-image-registry.apps.ocp4.example.com/my_project/ubuntu: denied
push したイメージがレジストリに登録されていることを確認する:
$ oc get is -n test-project ubuntu
NAMESPACE NAME IMAGE REPOSITORY TAGS UPDATED
test-project ubuntu default-route-openshift-image-registry.apps.ocp4.example.com/test-project/ubuntu latest 20 seconds ago
最後に、test-project
を削除する:
oc delete project test-project
project が消えると、コンテナイメージもレジストリから自動的に削除される。
次のコマンドで、Image Registry から test-project/ubuntu
イメージが消えていることを確認する:
oc get is -n test-project ubuntu
参考資料