OpenShift 4.2におけるネットワーク制限環境下でのインストール(Samples Operator設定編)

Red Hatの福岡オフィスでソリューションアーキテクトをしている田中司恩です。 早いもので今年も12月がやってきました。皆さんにとってはどんな一年だったでしょうか? 自分は3月にRed Hatに入り、その後も福岡に引っ越ししたりとあっという間の一年でした。

さてもう一つ、12月は何と言ってもアドベントカレンダーの時期ですね! ということで、今年のOpenShiftなアドベントカレンダーはコレ!

OpenShift Advent Calendar 2019 - Qiita

ということで早速開始です!こちらは1日目のエントリになります。


前回記事では、OpenShift 4.2におけるネットワーク制限環境下でのインストールについて説明しました。

rheb.hatenablog.com

前回の後半でSamples Operatorの設定に関するパートがありました。 そこで十分に説明できなかった内容について、「Samples Operator設定編」と題して説明します。 本記事中で使用する環境やファイル名は前回記事の内容をそのまま使用しています。

本記事の章立てはこのようになります。

  • Samples Operator 設定概要
  • ネットワーク制限環境下でのイメージストリームサンプルの使用
  • ミラーレジストリーを利用したアプリのデプロイ
  • 参考:全イメージミラーシェルスクリプト

Samples Operator 設定概要

ドキュメントでは詳細な記述がなく、唐突にSamples Operatorについての内容が出てくるので初めて設定を行う時は戸惑うことと思います。 本記事では「何をすればどうなるのか」という点に焦点を当てて説明します。

ネットワーク制限環境下でのインストール後、イメージストリームの各イメージの参照ができずエラーになりSamples OperatorがDegradedになります。 前回記事ではこの対処に「Samples Operatorで全てのイメージの管理を無効化する」という方法を説明しました。

[図1]

Samples Operatorで全てのイメージの管理を無効化
Samples Operatorで全てのイメージの管理を無効化

もう一つの方法として、使いたいイメージをミラーレジストリーにミラーし、それ以外を管理対象から外す、という方法があります。

[図2]

使いたいイメージをミラーレジストリーにミラー
使いたいイメージをミラーレジストリーにミラー

<参考>全てのイメージをミラーすれば管理対象から外す必要が無いのでは?という点について記事末尾の「参考:全イメージミラーシェルスクリプト」を参照ください。

Samples Operatorの設定をまとめた内容が下記の表になります。

パターン managementState skippedImagestreams Status 説明 設定難度
1 Managed なし Degraded イメージにでも一つでもエラーがあると、2時間経過後にOperatorがDegradedになる -
2 Managed 設定有り True ミラーイメージ以外の、エラーが出ているイメージを全てskipped指定する
3 Removed なし True Samples Operator管理の全てのイメージを未使用にする
4 Removed 設定有り True 利用するミラーイメージのみをskipped指定する

まず、パターン1は初期状態のことで、全てのイメージが参照できずSamples OperatorがDegradedになります。 これを回避する方法として2,3,4のパターンがあります。

パターン1に対し、パターン3では全てのイメージを未使用にします。前回の記事で説明した方法になり、設定難度も低いです。

パターン2と4は似ていますが設定方法が異なります。また、パターン4では必要最低限の設定で済むのでパターン2に比べると簡単です。

次の項目ではイメージのミラーリングと、Samples Operatorの設定について説明します。

ネットワークが制限環境下でのイメージストリームサンプルの使用

イメージをミラーして利用する方法は下記のステップで実現できます

  1. イメージのミラー
  2. 認証局証明書の登録
  3. samplesRegistryの値変更
  4. 個別イメージのスキップ設定

対象のドキュメントは下記です

第9章 ネットワークが制限されたインストール 4.2 | Red Hat Customer Portal

1. イメージのミラー

イメージのミラーに使うコマンドは下記です。オプションなどの詳細はoc image mirror -hを参照。

oc image mirror SRC DST

イメージのミラーの実行の前に、ミラーレジストリーのリポジトリーを確認してみます。

$ curl -u user:user -k https://registry.test.example.local:5000/v2/_catalog
{"repositories":["ocp4/openshift4"]}

クラスタのインストール(場合によってはアップグレードも)直後だと、インストール(アップグレード)に使用したものしか登録されていません。

registry.redhat.ioのイメージを、ミラーレジストリーにミラーを実行します。対象はnginx-110-rhel7を指定した例です。

$ oc image mirror registry.redhat.io/rhscl/nginx-110-rhel7:latest registry.test.example.local:5000/rhscl/nginx-110-rhel7:latest -a pull-secret-2.txt

実行結果

registry.test.example.local:5000/
  rhscl/nginx-110-rhel7
    blobs:

〜省略〜

registry.test.example.local:5000/rhscl/nginx-110-rhel7:latest
info: Mirroring completed in 27.91s (3.887MB/s)

再度ミラーレジストリーのリポジトリーを確認してみます。

 curl -u user:user -k https://registry.test.example.local:5000/v2/_catalog
{"repositories":["ocp4/openshift4","rhscl/nginx-110-rhel7"]}

ミラーしたイメージが追加されているのが確認できます。

この時点でGUIを確認すると、証明書が登録されていないためエラーが出ています

例)Builds > Image Streams > nginx

[図3]

証明書のエラー
証明書のエラー

次の手順で証明書の登録を行います

2. 認証局証明書の登録

クラスターのイメージ設定オブジェクトに、レジストリーホストで作成した自己署名証明書を信頼されたCAとして登録します。

$ oc create configmap registry-config --from-file=/opt/registry/certs/domain.crt -n openshift-config

実行結果

configmap/registry-config created

3. samplesRegistryの値変更

<2019/12/4追記>samplesRegistryについてはこちらを参照

イメージのインポート元のURLを、ミラーレジストリーのURLで上書きします。*1

$ oc patch configs.samples.operator.openshift.io/cluster --type merge --patch '{"spec":{"samplesRegistry":"registry.test.example.local:5000"}}'

実行結果

config.samples.operator.openshift.io/cluster patched

GUIでは下記のように変更されます

例)Builds > Image Streams > nginx

samplesRegistryの値変更前

[図4]

samplesRegistryの値変更前
samplesRegistryの値変更前

TagsのFromのURLがregistry.redhat.io となっています

samplesRegistryの値変更後

[図5]

samplesRegistryの値変更後
samplesRegistryの値変更後

TagsのFromのURLがregistry.test.example.local:5000 に変わりました イメージをミラーしたnginx:1.10はイメージの参照ができるのでエラーが消えています。 まだミラーしていないnginx:1.12はエラーのままです。

4. 個別イメージのスキップ設定

ここで行うことはSamples Operatorの管理配下から、指定のイメージを除外する設定です。 先の項目では、まだミラーしていないnginx:1.12にはエラーが出ていました。 このエラーをこのままにしておくと、2時間後にSamples OperatorはDegradedになります。

省略されないミラーリングされないイメージがあるか、または Samples Operator が Removed に変更されない場合、 Samples Operator はイメージストリームのインポートが失敗し始めてから 2 時間後に Degraded ステータスを報告します。

こうした場合に指定のイメージストリームを除外設定することで、Degradedになることを回避できます。

下記のコマンドを実行します

$ oc edit configs.samples.operator.openshift.io

spec:skippedImagestreams:を追加し、除外するイメージストリーム名(今回はnginx)を指定します

〜省略〜

  spec:
    architectures:
    - x86_64
    managementState: Managed
    samplesRegistry: registry.test.example.local:5000
    skippedImagestreams:
    - nginx

〜省略〜

GUIでは下記のように変更されます

例)Builds > Image Streams > nginx

[図6]

skippedImagestreamsの追加前
skippedImagestreamsの追加前

nginxのラベルはmanaged=trueです

[図7]

skippedImagestreamsの追加後
skippedImagestreamsの追加後

nginxのラベルがmanaged=falseに変わりました

さらに除外するイメージストリームを追加します。 今回はyamlファイルを用意して、oc applyで実行してみます。

  • image.yaml
$ cat image.yaml 
apiVersion: samples.operator.openshift.io/v1
kind: Config
metadata:
  name: cluster
spec:
  skippedImagestreams:
  - nginx
  - nodejs

コマンド実行

$ oc apply -f image.yaml
config.samples.operator.openshift.io/cluster configured

skippedImagestreamsにさらに追加後

[図8]

skippedImagestreamsにさらに追加後
skippedImagestreamsにさらに追加後

nginxとnodejsのラベルがmanaged=falseになっています

このように、エラーが出ているイメージを除外指定する方法が、設定概要で説明したパターン2の方法になります。

さて、この状態でSamples Operatorのイメージ管理を無効化するとどうなるでしょうか? やってみます。

$ oc patch configs.samples.operator.openshift.io/cluster --type merge --patch '{"spec":{"managementState":"Removed"}}'
config.samples.operator.openshift.io/cluster patched

結果はこのようになります。

[図9]

Samples Operatorのイメージ管理を無効化
Samples Operatorのイメージ管理を無効化

元々Samples Operator管理対象外のイメージと、除外指定をしたイメージが残ります。 このように使用したいイメージを除外設定とし、全体のイメージ管理をオフにすることで、必要最低限の設定で済ませることができます。 この方法がパターン4の方法になります。

(参考)例で紹介したnginxとnodejsですが、どちらものGitのソースを利用したS2Iビルドを行います。 今回のようなネットワーク制限環境下ではそもそもクラスタからインターネットへのアクセスができず、Githubを利用するような用途には実際には利用できません。

ミラーレジストリーを利用したアプリのデプロイ

ミラーしたイメージストリームを利用してアプリのデプロイを行ってみます。 今回はS2Iを利用しないredisを使用します。oc new-appを使う手順は通常通りです。 前提としてrhscl/redis-32-rhel7:latestがすでにミラー済みとします。

  • プロジェクトtestにredisをデプロイ
$ oc new-project test
Now using project "test" on server "https://api.test.example.local:6443".

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

    oc new-app django-psql-example

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

    kubectl create deployment hello-node --image=gcr.io/hello-minikube-zero-install/hello-node

$ oc new-app redis
--> Found image a00c397 (7 weeks old) in image stream "openshift/redis" under tag "3.2" for "redis"

    Redis 3.2 
    --------- 
    Redis 3.2 available as container, is an advanced key-value store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets and sorted sets. You can run atomic operations on these types, like appending to a string; incrementing the value in a hash; pushing to a list; computing set intersection, union and difference; or getting the member with highest ranking in a sorted set. In order to achieve its outstanding performance, Redis works with an in-memory dataset. Depending on your use case, you can persist it either by dumping the dataset to disk every once in a while, or by appending each command to a log.

    Tags: database, redis, redis32, rh-redis32

    * This image will be deployed in deployment config "redis"
    * Port 6379/tcp will be load balanced by service "redis"
      * Other containers can access this service through the hostname "redis"
    * This image declares volumes and will default to use non-persistent, host-local storage.
      You can add persistent volumes later by running 'oc set volume dc/redis --add ...'

--> Creating resources ...
    imagestreamtag.image.openshift.io "redis:3.2" created
    deploymentconfig.apps.openshift.io "redis" created
    service "redis" created
--> Success
    Application is not exposed. You can expose services to the outside world by executing one or more of the commands below:
     'oc expose svc/redis' 
    Run 'oc status' to view your app.

$ oc status
In project test on server https://api.test.example.local:6443

svc/redis - 172.30.207.125:6379
  dc/redis deploys openshift/redis:3.2 
    deployment #1 deployed 50 seconds ago - 1 pod


3 infos identified, use 'oc status --suggest' to see details.

$ oc get pods
NAME             READY   STATUS      RESTARTS   AGE
redis-1-deploy   0/1     Completed   0          63s
redis-1-wp9mj    1/1     Running     0          55s

$ oc get is/redis -n test
NAME    IMAGE REPOSITORY                                              TAGS   UPDATED
redis   image-registry.openshift-image-registry.svc:5000/test/redis   3.2    

問題無くアプリのデプロイができました。

まとめ

前回の記事から引き続き、ネットワーク制限環境下での内容について解説しました。 クラスタのインストール後にエラーを回避し、適切な設定を行うためには、Samples Operatorやイメージに関する内容についても理解する必要があります。 ここまで行っても全ての機能が完全に使える訳ではありませんので、やはり何らかの手段でクラスタをインターネットへ接続する環境を整えることを推奨します。

Let's get Big Ideas!

参考:全イメージミラーシェルスクリプト

本記事のイメージのミラー手順では、個別のイメージタグを指定してミラーする方法を紹介しました。 Samples Operatorに登録されているミラーが必要なイメージストリーム数は211あります。*2 流石に手作業で全てをミラーするのは手間なので、全てをミラーするサンプルスクリプトを作成しました。

※ 注意 下記のスクリプトは検証用に作成したものです。本番環境で実行することは推奨しません。

  • mirror.sh
#!/bin/bash

KUBECONFIG="kubeconfig"
SRC_URL="registry.redhat.io"
DST_URL="registry.test.example.local:5000"
SECRET="pull-secret-2.txt"

### MAIN ###
export KUBECONFIG

IMAGE_LIST=`oc get imagestreams -n openshift -o json |jq -r '.items[]?.spec.tags[]?.from.name | select(startswith("registry"))'`


for image in $IMAGE_LIST; do
    IMAGE_NAME=`echo $image | sed -e "s/registry\.test.example\.local\:5000//"`
    
    # Dry-run
    #oc image mirror $SRC_URL$IMAGE_NAME $DST_URL$IMAGE_NAME -a $SECRET --dry-run

    # Exec
    oc image mirror $SRC_URL$IMAGE_NAME $DST_URL$IMAGE_NAME -a $SECRET

done

全てのミラーの完了に要する時間は、ネットワークの環境にもよりますが数時間はかかります。 また、/opt/registryの容量が47GB増大します。 さらに、これで全てのイメージタグがミラーできる訳ではなく、どうしてもエラーが出てミラーできないものがいくつかあります(イメージストリーム内の一部のタグのみミラーできない、等も含む)。

検証環境でミラー後にダウンロードが完了しなかったイメージストリームは下記の通りです。

  • エラーが出ているイメージのみを取得しリスト化*3
$ oc get configs.samples.operator.openshift.io -o json | jq -r .items[].status.conditions[].reason | grep -v 'null' | tr ' ' '\n' | sort

apicast-gateway
httpd
jboss-amq-62
jboss-amq-63
jboss-datagrid65-client-openshift
jboss-datagrid65-openshift
jboss-datagrid71-openshift
jboss-decisionserver64-openshift
jboss-eap64-openshift
jboss-eap70-openshift
jboss-eap71-openshift
jboss-processserver64-openshift
jboss-webserver30-tomcat7-openshift
jboss-webserver30-tomcat8-openshift
jboss-webserver31-tomcat7-openshift
jboss-webserver31-tomcat8-openshift
jenkins
jenkins-agent-maven
jenkins-agent-nodejs
modern-webapp
nodejs
redhat-openjdk18-openshift
redhat-sso70-openshift
redhat-sso71-openshift
redhat-sso72-openshift
rhpam73-businesscentral-indexing-openshift

このように、全てのイメージをミラーをすることは難しく、Samples OperatorをManagedで実行するためには パターン2となりskippedImagestreamsを組み合わせる必要があります。

*1:ドキュメントの 9.1.6 手順3 では oc get のコマンドが載っていますが、間違いというよりは情報不足です。

*2:cli、cli-artifacts、installer、installer-artifacts、must-gather、tests、jenkins、jenkins-agent-maven、jenkins-agent-nodejs を除く

*3:jenkinsはインストール時にquay.ioからミラーするので本来は対象外

* 各記事は著者の見解によるものでありその所属組織を代表する公式なものではありません。その内容については非公式見解を含みます。