0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Red Hat OpenShift on IBM Cloudで、内部レジストリに外部からアクセスする

Last updated at Posted at 2022-08-09

はじめに

Red Hat OpenShift on IBM Cloudでは、コンテナレジストリとしてIBM Cloud Container Registryを使用するケースが多いと思います。ただ、Container Registryを使用できないケースでは、OpenShift内でデフォルトでセットアップされているOpenShift Container Registry(OCR)を使用することになります。

OCRは内部からのアクセスが可能であるものの、例えばローカルの端末でビルドしたイメージをpushするといったような外部からのアクセスができない状態になっています。

この記事では、OCRに外部からアクセス(push)できるように設定し、さらに、クラスター内でOCRからイメージをpullできるように設定する手順を紹介します。この記事の内容は、基本的に「IBM Cloudドキュメント:内部レジストリーのためのセキュアな外部経路のセットアップ」に基づいています。

前提環境

・Red Hat OpenShift on IBM Cloud (OpenShiftバージョン:4.10.22_1528)
・OpenShiftクラスターに対して、IBM Cloud IAMの「マネージャ」サービス役割を保持していること

内部レジストリに外部からpushできるようにする

openshift-image-registry プロジェクトに、image-registryサービスが存在することを確認します。

❯ oc get svc -n openshift-image-registry
NAME                      TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)     AGE
image-registry            ClusterIP   xxx.xxx.xx.xxx   <none>        5000/TCP    6h33m
image-registry-operator   ClusterIP   None             <none>        60000/TCP   6h50m

image-registryサービスに対して、暗号化されたrouteを作成します。ここではreencrypt(クライアント - route間で暗号化を一旦終端し、再度暗号化してroute - 内部レジストリ間もセキュアにする)を指定してrouteを作成します。

❯ oc create route reencrypt --service=image-registry -n openshift-image-registry
route.route.openshift.io/image-registry created

作成されたrouteに割り当てられたホスト名、ポートを確認します。

❯ oc get route image-registry -n openshift-image-registry
NAME             HOST/PORT                                                                                                                                   PATH   SERVICES         PORT       TERMINATION   WILDCARD
image-registry   image-registry-openshift-image-registry.xxxxx.jp-tok.containers.appdomain.cloud          image-registry   5000-tcp   reencrypt     None

作成したrouteをoc editで編集し、ロードバランスの方式をsourceに変更します。これにより、同じIPアドレスからのアクセスは同じPodに到達するようになります。

oc edit route image-registry -n openshift-image-registry

編集箇所は(コメントを含めて)10行目あたりで、metadata.annotationshaproxy.router.openshift.io/balance: sourceの行を追加して保存します。

# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: route.openshift.io/v1
kind: Route
metadata:
  annotations:
    openshift.io/host.generated: "true"
    haproxy.router.openshift.io/balance: source    # 左記の内容を追加する

以上により外部から内部レジストリにアクセスできるようになったので、docker loginによりログインします。ホスト名・ポートは、上記のrouteで確認したホスト名・ポートを使用します。ユーザ名、パスワードは、OpenShiftへのログインユーザ、パスワードを使用します。

❯ docker login -u $(oc whoami) -p $(oc whoami -t) image-registry-openshift-image-registry.xxxxxxxxxxx.jp-tok.containers.appdomain.cloud
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Login Succeeded

ここでは、イメージをpushし、デプロイして稼働させるためのサンプルプロジェクトをsampleという名前で作成します。

❯ oc new-project sample                                                                                          
Now using project "sample" on server "https://c115-e.jp-tok.containers.cloud.ibm.com:30645".

You can add applications to this project with the 'new-app' command. For example, try:

    oc new-app rails-postgresql-example

to build a new example application in Ruby. Or use kubectl to deploy a simple Kubernetes application:

    kubectl create deployment hello-node --image=k8s.gcr.io/e2e-test-images/agnhost:2.33 -- /agnhost serve-hostname

pushするイメージとしてnginxを使用します(--platformオプションは、ローカル端末がM1 Mac(arm64)のために付けています。amd64のCPUの場合は不要です)。

❯ docker pull --platform linux/x86_64 nginx:latest
latest: Pulling from library/nginx
Digest: sha256:ecc068890de55a75f1a32cc8063e79f90f0b043d70c5fcf28f1713395a4b3d49
Status: Image is up to date for nginx:latest
docker.io/library/nginx:latest

OCRにpushするための準備として、docker tagコマンドでタグを付けます。ホスト名の部分は作成したrouteで確認したホスト名です。ホスト名に続けて、/<プロジェクト名>(この例ではsample)/nginx:latest を指定します。

❯ docker tag nginx:latest image-registry-openshift-image-registry.xxxxxxx.jp-tok.containers.appdomain.cloud/sample/nginx:latest

タグを付けたイメージをpushします。

❯ docker push image-registry-openshift-image-registry.xxxxxxx.jp-tok.containers.appdomain.cloud/sample/nginx:latest 
The push refers to repository [image-registry-openshift-image-registry.xxxxxxx.jp-tok.containers.appdomain.cloud/sample/nginx]
b539cf60d7bb: Pushed 
bdc7a32279cc: Pushed 
f91d0987b144: Pushed 
3a89c8160a43: Pushed 
e3257a399753: Pushed 
92a4e8a3140f: Pushed 
latest: digest: sha256:f26fbadb0acab4a21ecb4e337a326907e61fbec36c9a9b52e725669d99ed1261 size: 1570

イメージをpushすると、sampleプロジェクトにImageStreamが作成されるため、それを確認します。

❯ oc get imagestream                                     
NAME    IMAGE REPOSITORY                                                TAGS     UPDATED
nginx   image-registry.openshift-image-registry.svc:5000/sample/nginx   latest   29 seconds ago

クラスターが内部レジストリからイメージをpullできるようにする

次に、pushしたイメージをpullできるように設定します。

現在のプロジェクトが先ほど作成したsampleであることを確認します。

❯ oc project        
Using project "sample" on server "https://c115-e.jp-tok.containers.cloud.ibm.com:xxxxx".

defaultサービスアカウントの詳細を表示し、Image pull secretsで指定されているSecretを確認します。

❯ oc describe sa default            
Name:                default
Namespace:           sample
Labels:              <none>
Annotations:         <none>
Image pull secrets:  default-dockercfg-zzjd4
Mountable secrets:   default-token-bqklv
                     default-dockercfg-zzjd4
Tokens:              default-token-bqklv
                     default-token-wx8n9
Events:              <none>

上記で確認したSecretをYAML形式で出力し、.dockercfgの値を確認します。

❯ oc get secret default-dockercfg-zzjd4 -o yaml                                                                  
apiVersion: v1
data:
  .dockercfg:xxxxx

.dockercfgの値はBase64でエンコードされているため、それをデコードします(echoコマンドに渡しているのが.dockercfgの値です)。デコードすることで、イメージをpullするために必要なusername、passwordを得ることができます。

echo "<ey...=>" | base64 -D


{"172.xx.xxx.xxx:5000":{"username":"serviceaccount","password":"ey......

上記で取得した「routeのホスト名」、「username」、「password」の値を用いて、内部レジストリ用の新たなImage Pull Secretを作成します。ここではinternal-registryという名前のSecretを作成します。各オプションではそれぞれ以下を指定します。

  • --docker-server  : routeのホスト名+:5000(ポート番号)
  • --docker-username : 上記のusernameの値
  • --docker-password : 上記のpasswordの値
  • --docker-email : 適当なメールアドレス(例:a@b.c
oc create secret image-registry internal-registry --namespace sample --docker-server image-registry-openshift-image-registry.xxxxxxx.jp-tok.containers.appdomain.cloud:5000 --docker-username serviceaccount --docker-password <eyJ...> --docker-email a@b.c

defaultサービスアカウントに、上記で作成したImage Pull Secretを追加します。

❯ oc patch -n sample serviceaccount/default --type='json' -p='[{"op":"add","path":"/imagePullSecrets/-","value":{"name":"internal-registry"}}]'
serviceaccount/default patched

nginxのイメージでは、ポート80を使用するためにroot権限が必要になります。しかし、OpenShiftはセキュリティ上の理由からコンテナで設定されているユーザではなく、ランダムなUIDで実行するため、ポート80が使用できません。それを回避するため、anyuidSCCをdefaultサービスアカウントに付与し、コンテナで設定したユーザでの実行を許可します。

❯ oc adm policy add-scc-to-user anyuid -z default
clusterrole.rbac.authorization.k8s.io/system:openshift:scc:anyuid added: "default"

nginxコンテナのデプロイ

それではnginxコンテナをデプロイしてみます。

OpenShiftのWebコンソールにアクセスし、「Developer」パースペクティブを選択し、「追加」→「コンテナイメージ」をクリックします。
image.png

「内部レジストリーからのイメージストリームタグ」を選択し、プロジェクト、イメージストリーム、タグに、それぞれ「sample」、「nginx」、「latest」を指定します。
image.png

画面を下にスクロールし、他の項目はデフォルト値のままで「作成」ボタンをクリックします。
image.png

しばらくするとデプロイが完了するので、「トポロジー」のアイコンの右上部分をクリックします。
image.png

nginxのWelcomページが表示されることを確認します。
image.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?