OpenShiftでMachine Config Pool (MCP) を使用してInfra nodeを作成する


# 概要

OpenShift (OCP)のデフォルトのルーター、内部レジストリー、モニタリング、追加で導入したロギングなどの運用コンポーネントはデフォルトではworker node上で稼働します。
これらの運用コンポーネントをアプリケーションPodと分離して稼働させるため、専用のinfra nodeを構成することができます。

UPIでインストールした場合は、infra nodeを構成するには「ノードラベル」のみで設定する方法と、infra node用の「Machine Config Pool (MCP)」を作成する方法があります。

(前者の「ノードラベル」のみで設定する方法は、少し古いですが[OCP 4.2で専用のInfra nodeを作成してルーター、内部レジストリー、モニタリング、ロギングを移動する](https://qiita.com/t_sweetfish/items/fe23d0f50df3179c4b91)も参考になると思います。)


今回は、後者のinfra node用の「MCP」を作成してinfra nodeを構成した際のメモを記載しました。


この記事でのOCPクラスタの前提の構成は [Qiita / OpenShift 4.10 ベアメタルUPI (iPXE) インストール](https://qiita.com/t_sweetfish/items/81268b29a3a7ad2f3f09) でインストールしたOCP 4.10の構成となります。

- OCP 4.10をベアメタルのUPIでインストールしています。
- nodeの構成はinfra node x3台です。
- (こちらの記事ではロギングはまだ入れていませんが、ロギングはここでインストールしています。)


```bash
[root@bastion-01 ~]# oc version
Client Version: 4.10.6
Server Version: 4.10.6
Kubernetes Version: v1.23.5+b0357ed
[root@bastion-01 ~]#
[root@bastion-01 ~]# oc get node
NAME        STATUS   ROLES    AGE    VERSION
infra-01    Ready    worker   2d1h   v1.23.5+b0357ed
infra-02    Ready    worker   2d1h   v1.23.5+b0357ed
infra-03    Ready    worker   2d     v1.23.5+b0357ed
master-01   Ready    master   2d1h   v1.23.5+b0357ed
master-02   Ready    master   2d1h   v1.23.5+b0357ed
master-03   Ready    master   2d1h   v1.23.5+b0357ed
worker-01   Ready    worker   2d     v1.23.5+b0357ed
worker-02   Ready    worker   2d     v1.23.5+b0357ed
[root@bastion-01 ~]#
```


# 参考資料

infra nodeの構成方法は以下のKBが一番よくまとまっていてとても参考になります。基本的には、今回はこのKBに記載の内容でinfra node専用の「MCP」を作ってます。
- [KB / Infrastructure Nodes in OpenShift 4](https://access.redhat.com/solutions/5034771)


MCPの概要については以下のBlogがとてもわかりやすいです。
- [Red Hat Blog / OpenShift Container Platform 4: How does Machine Config Pool work?](https://www.redhat.com/en/blog/openshift-container-platform-4-how-does-machine-config-pool-work)


なお、OCPのドキュメントは以下になります。 
- [OCP 4.10 Docs / インストール後の設定 / 5. インストール後のクラスタータスク / 5.4. 実稼働環境用のインフラストラクチャーマシンセットの作成](https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.10/html-single/post-installation_configuration#post-install-creating-infrastructure-machinesets-production)
- [OCP 4.10 Docs / インストール後の設定 / 5. インストール後のクラスタータスク / 5.5. マシンセットリソースのインフラストラクチャーノードへの割り当て](https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.10/html-single/post-installation_configuration#assigning-machine-set-resources-to-infra-nodes)
- [OCP 4.10 Docs / インストール後の設定 / 5. インストール後のクラスタータスク / 5.6. リソースのインフラストラクチャーマシンセットへの移行](https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.10/html-single/post-installation_configuration#moving-resources-to-infrastructure-machinesets)



# infra node 構成の流れ

UPIの場合は、infra nodeを構成する上では、以下の流れで検討する必要があります。(KB参照)

- infra nodeの構成方法
  - (1) infra node専用の「MCP」を作成
  - (2) infra node専用の「MCP」を作成せず、infra node用のworker nodeに`infra`の「ノードラベル」を「追加」して構成

- 運用コンポーネントのinfra nodeに移動
  - ルーター
  - OCP内部レジストリー
  - モニタリング
  - ロギング

- アプリケーションPodをinfra nodeで稼働させない設定
  - (1) nodeSelectorのみを使用
  - (2) nodeSelectorとtaint/tolerationを使用


# 今回の方針

今回は以下のようにMCPを使用してinfra nodeを構成します。

- 「infra nodeの構成方法」は「(1) infra node専用の「MCP」を作成」で構成します。
- 「アプリケーションPodをinfra nodeで稼働させない設定」は「(1) nodeSelectorのみを使用」で実施します。


# 「Machine Config」と「Machine Config Pool」と「Node」

「MC」と「MCP」と「Node」の関係は以下のようになります。

- 「MC」と「MCP」との紐付けは、「MC」のラベル(`machineconfiguration.openshift.io/role=master`、`machineconfiguration.openshift.io/role=worker`)の値で紐づいています。
- 「Node」と「MCP」との紐付けは、「Node」のノードラベル(`node-role.kubernetes.io/master=""`、`node-role.kubernetes.io/worker=`)で紐づいています。


今回はinfra nodeの「MCP」を作成します。

- 「Node」にinfra node用のノードラベルを付与します。
- infra node用の「MCP」は、既存のwoker node用のラベルを持った「MC」も全部読み込めるようにします。
- 今後infra nodeだけに設定したい「MC」を作成した場合には、worker node用ののラベルを持った「MC」に加えて、infra node用のラベルを持った「MC」も両方読み込めるように「MCP」のmachineConfigSelectorの値を設定します。



# infra nodeの構成方法

## (1) infra node専用の「MCP」を作成


デフォルトの構成は以下になります。

デフォルトでは、master nodeととworker node用の「Machine Config Pool (MCP)」があります。

```bash
[root@bastion-01 mcp]# oc get mcp
NAME     CONFIG                                             UPDATED   UPDATING   DEGRADED   MACHINECOUNT   READYMACHINECOUNT   UPDATEDMACHINECOUNT   DEGRADEDMACHINECOUNT   AGE
master   rendered-master-954e86f747cb1bc813dc88a53adc068c   True      False      False      3              3                   3                     0                      40d
worker   rendered-worker-8062fb3f341ce6e926a1678cc33db7f3   True      False      False      5              5                   5                     0                      40d
[root@bastion-01 mcp]#
```

master nodeとworker node用の特定の要件の個別の設定が入っている「Machine Config (MC)」が複数あります。
上述の「MC」をmaster node、worker node毎に全てまとめたrendered-master-xxxxx、rendered-worker-xxxxという「MC」が自動で作成されており、これが上述のmaster node、worker nodeのMCPの「CONFIG」列に表示されています。

```
[root@bastion-01 mcp]# oc get mc
NAME                                               GENERATEDBYCONTROLLER                      IGNITIONVERSION   AGE
00-master                                          e6ba00b885558712d660a3704c071490d999de6f   3.2.0             40d
00-worker                                          e6ba00b885558712d660a3704c071490d999de6f   3.2.0             40d
01-master-container-runtime                        e6ba00b885558712d660a3704c071490d999de6f   3.2.0             40d
01-master-kubelet                                  e6ba00b885558712d660a3704c071490d999de6f   3.2.0             40d
01-worker-container-runtime                        e6ba00b885558712d660a3704c071490d999de6f   3.2.0             40d
01-worker-kubelet                                  e6ba00b885558712d660a3704c071490d999de6f   3.2.0             40d
99-master-chrony                                                                              3.2.0             40d
99-master-generated-registries                     e6ba00b885558712d660a3704c071490d999de6f   3.2.0             40d
99-master-ssh                                                                                 3.2.0             40d
99-worker-chrony                                                                              3.2.0             40d
99-worker-generated-registries                     e6ba00b885558712d660a3704c071490d999de6f   3.2.0             40d
99-worker-ssh                                                                                 3.2.0             40d
rendered-master-954e86f747cb1bc813dc88a53adc068c   e6ba00b885558712d660a3704c071490d999de6f   3.2.0             40d
rendered-worker-8062fb3f341ce6e926a1678cc33db7f3   e6ba00b885558712d660a3704c071490d999de6f   3.2.0             40d
[root@bastion-01 mcp]#
```

nodeは、ノードラベルでmaster node、worker node用のMCPと紐づき、それぞれのMCPに表示されたrenderedのMCが適用されています。

(デフォルトのinfra nodeの例(まだノードラベルがworkerの場合))
```bash
[root@bastion-01 ~]# oc describe node infra-01
Name:               infra-01
Roles:              worker
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
                    kubernetes.io/arch=amd64
                    kubernetes.io/hostname=infra-01
                    kubernetes.io/os=linux
                    node-role.kubernetes.io/worker=
                    node.openshift.io/os_id=rhcos
Annotations:        machineconfiguration.openshift.io/controlPlaneTopology: HighlyAvailable
                    machineconfiguration.openshift.io/currentConfig: rendered-worker-8062fb3f341ce6e926a1678cc33db7f3
                    machineconfiguration.openshift.io/desiredConfig: rendered-worker-8062fb3f341ce6e926a1678cc33db7f3
                    machineconfiguration.openshift.io/reason:
                    machineconfiguration.openshift.io/state: Done
                    volumes.kubernetes.io/controller-managed-attach-detach: true
(略)
```


ここから実際にinfra nodeのMCPを作成します。

マニフェスト保管用ディレクトリ作成します。

```bash
[root@bastion-01 ~]# mkdir -p work/manifest/mcp
[root@bastion-01 ~]# cd work/manifest/mcp/
[root@bastion-01 mcp]#
```

infra node用の「MCP」のマニフェストファイルを作成します。

- infra node専用のMCPを作成するので`.spec.metadata.name`は、`infra`という名前にします。
- infra nodeは、worker用ののMCも、infra用のMCも読み込めるように、`machineConfigSelector`を設定をします。


```bash
[root@bastion-01 mcp]# vi mcp-infra.yaml
[root@bastion-01 mcp]#
```

```yaml:mcp-infra.yaml
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfigPool
metadata:
  name: infra
spec:
  machineConfigSelector:
    matchExpressions:
      - {key: machineconfiguration.openshift.io/role, operator: In, values: [worker,infra]}
  nodeSelector:
    matchLabels:
      node-role.kubernetes.io/infra: ""
```



作成したinfra node用の「MCP」のマニフェストを適用します。

```bash
[root@bastion-01 mcp]# pwd
/root/work/manifest/mcp
[root@bastion-01 mcp]# ls -l
合計 4
-rw-r--r--. 1 root root 315  5月  9 20:33 mcp-infra.yaml
[root@bastion-01 mcp]#
[root@bastion-01 mcp]# oc apply -f mcp-infra.yaml
machineconfigpool.machineconfiguration.openshift.io/infra created
[root@bastion-01 mcp]#
```

infra node用の「MCP」が作成されたことを確認します。
```bash
[root@bastion-01 mcp]# oc get mcp
NAME     CONFIG                                             UPDATED   UPDATING   DEGRADED   MACHINECOUNT   READYMACHINECOUNT   UPDATEDMACHINECOUNT   DEGRADEDMACHINECOUNT   AGE
infra    rendered-infra-8062fb3f341ce6e926a1678cc33db7f3    True      False      False      0              0                   0                     0                      26s
master   rendered-master-954e86f747cb1bc813dc88a53adc068c   True      False      False      3              3                   3                     0                      40d
worker   rendered-worker-8062fb3f341ce6e926a1678cc33db7f3   True      False      False      5              5                   5                     0                      40d
[root@bastion-01 mcp]#
```

中身は以下のようになっています。
```bash
[root@bastion-01 mcp]# oc get mcp infra -o yaml
```
```yaml
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfigPool
spec:
  (略)
  machineConfigSelector:
    matchExpressions:
    - key: machineconfiguration.openshift.io/role
      operator: In
      values:
      - worker
      - infra
  nodeSelector:
    matchLabels:
      node-role.kubernetes.io/infra: ""
(略)
```


作成したinfra用の「MCP」と「Node」を紐づけるために、infra nodeのノードラベルからworkerを削除しinfraを追加します。

(infraのノードラベル付与)
```bash
[root@bastion-01 ~]# oc label node infra-01 node-role.kubernetes.io/infra=""
node/infra-01 labeled
[root@bastion-01 ~]# oc label node infra-02 node-role.kubernetes.io/infra=""
node/infra-02 labeled
[root@bastion-01 ~]# oc label node infra-03 node-role.kubernetes.io/infra=""
node/infra-03 labeled
[root@bastion-01 ~]#
```

(workerのノードラベル削除)
```bash
[root@bastion-01 ~]# oc label node infra-01 node-role.kubernetes.io/worker-
node/infra-01 unlabeled
[root@bastion-01 ~]#
[root@bastion-01 ~]# oc label node infra-02 node-role.kubernetes.io/worker-
node/infra-02 unlabeled
[root@bastion-01 ~]#
[root@bastion-01 ~]# oc label node infra-03 node-role.kubernetes.io/worker-
node/infra-03 unlabeled
[root@bastion-01 ~]#
```


infra nodeから、infraのノードラベルが付与され、workerのノードラベルが削除されました。

(ノードラベル付与確認)
```bash
[root@bastion-01 ~]# oc get node
NAME        STATUS   ROLES    AGE   VERSION
infra-01    Ready    infra    40d   v1.23.5+b0357ed
infra-02    Ready    infra    40d   v1.23.5+b0357ed
infra-03    Ready    infra    40d   v1.23.5+b0357ed
master-01   Ready    master   40d   v1.23.5+b0357ed
master-02   Ready    master   40d   v1.23.5+b0357ed
master-03   Ready    master   40d   v1.23.5+b0357ed
worker-01   Ready    worker   40d   v1.23.5+b0357ed
worker-02   Ready    worker   40d   v1.23.5+b0357ed
[root@bastion-01 ~]#
```

(参考)
```bash
[root@bastion-01 ~]# oc get node infra-01 -o yaml | grep -A 8 labels
  labels:
    beta.kubernetes.io/arch: amd64
    beta.kubernetes.io/os: linux
    kubernetes.io/arch: amd64
    kubernetes.io/hostname: infra-01
    kubernetes.io/os: linux
    node-role.kubernetes.io/infra: ""
    node.openshift.io/os_id: rhcos
  name: infra-01
[root@bastion-01 ~]#
```


infra用の「MCP」と「Node」が紐づいたので、infra nodeに自動でinfra node用の「MC」が適用されます。
(一般的に「MC」の変更があった場合は、自動でnodeの再起動が走り、新しい「MCP」の「MC」が反映されますが、今回はinfraもworkerも同じ「MC」しか読み込んでおらず変更はなかったのでnodeの再起動はしていないみたいでした。)

infra nodeにinfra用の「MC」適用後は、以下のように、infraの「MCP」の「MACHINECOUNT」が3になりMCが適用されていることがわかります。
```bash
[root@bastion-01 ~]# oc get mcp
NAME     CONFIG                                             UPDATED   UPDATING   DEGRADED   MACHINECOUNT   READYMACHINECOUNT   UPDATEDMACHINECOUNT   DEGRADEDMACHINECOUNT   AGE
infra    rendered-infra-8062fb3f341ce6e926a1678cc33db7f3    True      False      False      3              3                   3                     0                      10m
master   rendered-master-954e86f747cb1bc813dc88a53adc068c   True      False      False      3              3                   3                     0                      40d
worker   rendered-worker-8062fb3f341ce6e926a1678cc33db7f3   True      False      False      2              2                   2                     0                      40d
[root@bastion-01 ~]#
```



# 運用コンポーネントのinfra nodeに移動

以下の運用コンポーネントをinfra nodeに移動させます。

- ルーター
- OCP内部レジストリー
- モニタリング
- ロギング


移動は、基本的に以下のドキュメントの手順通りに実施します。

- [OCP 4.10 Docs / インストール後の設定 / 5. インストール後のクラスタータスク / 5.6. リソースのインフラストラクチャーマシンセットへの移行](https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.10/html-single/post-installation_configuration#moving-resources-to-infrastructure-machinesets)

ここでは、それぞれのカスタムリソースにinfra nodeのnodeSlectorを設定するだけになります。
(taint/toralationなどは「アプリケーションPodをinfra nodeで稼働させない設定」の箇所で検討するので、一旦このセクションではnodeSelectorの設定のみをしています。)


> (補足)モニタリング、ロギング専用のinfra nodeも作成したい場合はノードラベルの付与の仕方は以下も参考にしてください。
> - [OCP 4.2で専用のInfra nodeを作成してルーター、内部レジストリー、モニタリング、ロギングを移動する](https://qiita.com/t_sweetfish/items/fe23d0f50df3179c4b91) 


## ルーター

- [OCP 4.10 Docs / インストール後の設定 / 5. インストール後のクラスタータスク / 5.6. リソースのインフラストラクチャーマシンセットへの移行 / 5.6.1. ルーターの移動](https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.10/html-single/post-installation_configuration#infrastructure-moving-router_post-install-cluster-tasks)


初めにルータのPodがどのnode上で稼働しているかを確認します。
infra node移動の設定前は今回は、Podはたまたま最初からinfra nodeで稼働していました。
```bash
[root@bastion-01 ~]# oc get pod -n openshift-ingress -o wide
NAME                             READY   STATUS    RESTARTS   AGE   IP              NODE       NOMINATED NODE   READINESS GATES
router-default-d9585794b-4lm7z   1/1     Running   0          9d    172.16.100.18   infra-02   <none>           <none>
router-default-d9585794b-pvklp   1/1     Running   0          9d    172.16.100.17   infra-01   <none>           <none>
[root@bastion-01 ~]#
```

(補足) operator自体は、master nodeでか稼働しています。
```bash
[root@bastion-01 ~]# oc get pod -n openshift-ingress-operator -o wide
NAME                                READY   STATUS    RESTARTS   AGE   IP            NODE        NOMINATED NODE   READINESS GATES
ingress-operator-79fd869977-8clzt   2/2     Running   4          43d   10.130.0.12   master-02   <none>           <none>
[root@bastion-01 ~]#
```

設定は`ingresscontroller`リソースで行います。
```bash
[root@bastion-01 ~]# oc get ingresscontroller -n openshift-ingress-operator
NAME      AGE
default   43d
[root@bastion-01 ~]#
```

デフォルトではnodeSlectorの設定はないため、任意のworker node上で稼働しています。
```bash
[root@bastion-01 ~]# oc get ingresscontroller -n openshift-ingress-operator default -o yaml
```
```yaml
spec:
  clientTLS:
    clientCA:
      name: ""
    clientCertificatePolicy: ""
  httpCompression: {}
  httpEmptyRequestsPolicy: Respond
  httpErrorCodePages:
    name: ""
  replicas: 2
  tuningOptions: {}
  unsupportedConfigOverrides: null
status:
```

以下に示すように、`infra`ラベルを参照する`nodeSelector`を`spec`セクションに追加します。

```yaml
  spec:
    nodePlacement:
      nodeSelector:
        matchLabels:
          node-role.kubernetes.io/infra: ""
```

実際のコマンドは以下になります。
```bash
[root@bastion-01 ~]# oc edit ingresscontroller default -n openshift-ingress-operator
ingresscontroller.operator.openshift.io/default edited
[root@bastion-01 ~]#
[root@bastion-01 ~]# oc get ingresscontroller -n openshift-ingress-operator default -o yaml
```
```yaml
(略)
spec:
  clientTLS:
    clientCA:
      name: ""
    clientCertificatePolicy: ""
  httpCompression: {}
  httpEmptyRequestsPolicy: Respond
  httpErrorCodePages:
    name: ""
  nodePlacement:
    nodeSelector:
      matchLabels:
        node-role.kubernetes.io/infra: ""
  replicas: 2
  tuningOptions: {}
  unsupportedConfigOverrides: null
status:
(略)
```


Podが再作成され、nodeSelectorに従って、infra nodeで稼働するようになりました。
```bash
[root@bastion-01 ~]# oc get pod -n openshift-ingress -o wide
NAME                              READY   STATUS    RESTARTS   AGE     IP              NODE       NOMINATED NODE   READINESS GATES
router-default-77448cc55f-gbg4q   1/1     Running   0          2m44s   172.16.100.18   infra-02   <none>           <none>
router-default-77448cc55f-v2tbz   1/1     Running   0          3m22s   172.16.100.19   infra-03   <none>           <none>
[root@bastion-01 ~]#
```


## OCP内部レジストリー

- [OCP 4.10 Docs / インストール後の設定 / 5. インストール後のクラスタータスク / 5.6. リソースのインフラストラクチャーマシンセットへの移行 / 5.6.2. デフォルトレジストリーの移行](https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.10/html-single/post-installation_configuration#infrastructure-moving-registry_post-install-cluster-tasks)


初めにOCP内部レジストリーのPodがどのnode上で稼働しているかを確認します。
infra node移動の設定前は今回は、Podはたまたま最初からinfra nodeで稼働していました。

```bash
[root@bastion-01 ~]# oc get pods -n openshift-image-registry -o wide | grep image-registry
cluster-image-registry-operator-7cfd746b9b-7plxd   1/1     Running     0          23d     10.128.0.30     master-03   <none>           <none>
image-registry-646c7bdcfd-gbcnl                    1/1     Running     0          9d      10.128.2.7      infra-02    <none>           <none>
[root@bastion-01 ~]#
```

設定は`configs.imageregistry.operator.openshift.io`のリソースで行います。

修正前
```bash
[root@bastion-01 ~]# oc get configs.imageregistry.operator.openshift.io
NAME      AGE
cluster   43d
[root@bastion-01 ~]#
```

デフォルトではnodeSlectorの設定はないため、任意のworker node上で稼働しています。
```bash
[root@bastion-01 ~]# oc get configs.imageregistry.operator.openshift.io cluster -o yaml
```
```yaml
apiVersion: imageregistry.operator.openshift.io/v1
kind: Config
(略)
spec:
  defaultRoute: true
  httpSecret: ada28eb2bc1bf31d8f826769f8c15a7896215438c2976fc92f89adfdc231d264c9bf0ca1068b32fcc6b4bc080d0bb7df3666b7398016ccd7ff59e317a3cce89a
  logLevel: Normal
  managementState: Managed
  observedConfig: null
  operatorLogLevel: Normal
  proxy: {}
  replicas: 1
  requests:
    read:
      maxWaitInQueue: 0s
    write:
      maxWaitInQueue: 0s
  rolloutStrategy: RollingUpdate
  storage:
    managementState: Unmanaged
    pvc:
      claim: image-registry-storage
  unsupportedConfigOverrides: null
status:
(略)
```

以下に示すように、`infra`ラベルを参照する`nodeSelector`を`spec`セクションに追加します。

```yaml
spec:
  nodeSelector:
    node-role.kubernetes.io/infra: ""
```

実際のコマンドは以下になります。

```bash
[root@bastion-01 ~]# oc edit configs.imageregistry.operator.openshift.io cluster
config.imageregistry.operator.openshift.io/cluster edited
[root@bastion-01 ~]#
[root@bastion-01 ~]# oc get configs.imageregistry.operator.openshift.io cluster -o yaml
```
```yaml
apiVersion: imageregistry.operator.openshift.io/v1
kind: Config
metadata:
  (略)
spec:
  defaultRoute: true
  httpSecret: ada28eb2bc1bf31d8f826769f8c15a7896215438c2976fc92f89adfdc231d264c9bf0ca1068b32fcc6b4bc080d0bb7df3666b7398016ccd7ff59e317a3cce89a
  logLevel: Normal
  managementState: Managed
  nodeSelector:
    node-role.kubernetes.io/infra: ""
  observedConfig: null
  operatorLogLevel: Normal
  proxy: {}
  replicas: 1
  requests:
    read:
      maxWaitInQueue: 0s
    write:
      maxWaitInQueue: 0s
  rolloutStrategy: RollingUpdate
  storage:
    managementState: Unmanaged
    pvc:
      claim: image-registry-storage
  unsupportedConfigOverrides: null
status:
  (略)
```

Podが再作成され、nodeSelectorに従って、infra nodeで稼働するようになりました。
```bash
[root@bastion-01 ~]# oc get pods -n openshift-image-registry -o wide | grep image-registry
cluster-image-registry-operator-7cfd746b9b-7plxd   1/1     Running     0          23d     10.128.0.30     master-03   <none>           <none>
image-registry-66689994b6-tzvlb                    1/1     Running     0          103s    10.130.2.16     infra-03    <none>           <none>
[root@bastion-01 ~]#
```


## モニタリング

- [OCP 4.10 Docs / インストール後の設定 / 5. インストール後のクラスタータスク / 5.6. リソースのインフラストラクチャーマシンセットへの移行 / 5.6.3. モニタリングソリューションの移動](https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.10/html-single/post-installation_configuration#infrastructure-moving-monitoring_post-install-cluster-tasks)


デフォルトのモニタリングを構成するコンポーネント(Prometheus、Alertmanager、その他)をinfra node上で稼働させます。
今回はユーザーワークロードモニタリングのコンポーネントは記載していませんが、基本的には同様です。
(永続ボリュームは後で作成するつもりだったのでここでは移動だけです。)


初めにモニタリングのPodがどのnode上で稼働しているかを確認します。
- operatorのPodはmaster nodeで稼働しています。
- node-exporterはdaemonsetで全nodeで稼働しています。
- 移動の対象となるモニタリングのそれ以外のPodは、infra node、worker nodeとまちまちで稼働しています。

```bash
[root@bastion-01 monitoring]# oc get pod -n openshift-monitoring -o wide
NAME                                          READY   STATUS    RESTARTS   AGE   IP              NODE        NOMINATED NODE   READINESS GATES
alertmanager-main-0                           6/6     Running   12         43d   10.131.0.12     infra-01    <none>           <none>
alertmanager-main-1                           6/6     Running   0          9d    10.131.2.10     worker-01   <none>           <none>
cluster-monitoring-operator-dbcdff999-j5h79   2/2     Running   4          43d   10.130.0.9      master-02   <none>           <none>
grafana-6667f4d5bd-4rz5n                      3/3     Running   0          9d    10.128.2.9      infra-02    <none>           <none>
kube-state-metrics-6977cbc464-zrq2b           3/3     Running   6          43d   10.131.0.11     infra-01    <none>           <none>
node-exporter-2nk6f                           2/2     Running   4          43d   172.16.100.15   master-02   <none>           <none>
node-exporter-2sz27                           2/2     Running   4          43d   172.16.100.16   master-03   <none>           <none>
node-exporter-9dwjq                           2/2     Running   10         43d   172.16.100.18   infra-02    <none>           <none>
node-exporter-9ws9c                           2/2     Running   10         43d   172.16.100.19   infra-03    <none>           <none>
node-exporter-9z76z                           2/2     Running   6          43d   172.16.100.23   worker-01   <none>           <none>
node-exporter-lvl5p                           2/2     Running   6          43d   172.16.100.14   master-01   <none>           <none>
node-exporter-mjvd4                           2/2     Running   4          43d   172.16.100.17   infra-01    <none>           <none>
node-exporter-rkwmj                           2/2     Running   6          43d   172.16.100.24   worker-02   <none>           <none>
openshift-state-metrics-6b498b7995-crfll      3/3     Running   6          43d   10.131.0.7      infra-01    <none>           <none>
prometheus-adapter-7c7548d778-bq56l           1/1     Running   0          9d    10.128.2.6      infra-02    <none>           <none>
prometheus-adapter-7c7548d778-xrmwj           1/1     Running   0          11d   10.131.0.57     infra-01    <none>           <none>
prometheus-k8s-0                              6/6     Running   12         43d   10.131.0.3      infra-01    <none>           <none>
prometheus-k8s-1                              6/6     Running   0          9d    10.131.2.11     worker-01   <none>           <none>
prometheus-operator-67f5c64764-krg5s          2/2     Running   0          23d   10.130.0.53     master-02   <none>           <none>
telemeter-client-74f7d775fb-wnfhz             3/3     Running   6          43d   10.131.0.6      infra-01    <none>           <none>
thanos-querier-84ddf75d5c-29rxz               6/6     Running   0          9d    10.128.2.8      infra-02    <none>           <none>
thanos-querier-84ddf75d5c-7gt8v               6/6     Running   12         43d   10.131.0.2      infra-01    <none>           <none>
[root@bastion-01 monitoring]#
```


設定はConfigMapで行います。


マニフェストファイル作成用の作業用ディレクトリに移動し、モニタリングの設定用のConfigMapのマニフェストファイルを作成します。
ConfigMapの名前は`cluster-monitoring-config`とします。
以下に示すように、`infra`ラベルを参照する`nodeSelector`をモニタリングの全コンポーネントのセクションに追加します。

```bash
[root@bastion-01 ~]# mkdir -p work/manifest/monitoring
[root@bastion-01 ~]# cd work/manifest/monitoring/
[root@bastion-01 monitoring]#
[root@bastion-01 monitoring]# vi cluster-monitoring-configmap.yaml
[root@bastion-01 monitoring]# cat cluster-monitoring-configmap.yaml
```
```yaml:cluster-monitoring-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: cluster-monitoring-config
  namespace: openshift-monitoring
data:
  config.yaml: |+
    alertmanagerMain:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
    prometheusK8s:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
    prometheusOperator:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
    grafana:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
    k8sPrometheusAdapter:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
    kubeStateMetrics:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
    telemeterClient:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
    openshiftStateMetrics:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
    thanosQuerier:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
```

前述のConfigMapのマニフェストファイルを適用します。
```bash
[root@bastion-01 monitoring]# oc get cm -n openshift-monitoring cluster-monitoring-config
Error from server (NotFound): configmaps "cluster-monitoring-config" not found
[root@bastion-01 monitoring]#
[root@bastion-01 monitoring]#
[root@bastion-01 monitoring]# oc apply -f cluster-monitoring-configmap.yaml
configmap/cluster-monitoring-config created
[root@bastion-01 monitoring]#
[root@bastion-01 monitoring]# oc get cm -n openshift-monitoring cluster-monitoring-config
NAME                        DATA   AGE
cluster-monitoring-config   1      5s
[root@bastion-01 monitoring]#
```

Podが再作成され、モニタリング関連のPodが、nodeSelectorに従って、infra nodeで稼働するようになりました。

```bash
[root@bastion-01 monitoring]# oc get pod -n openshift-monitoring -o wide
NAME                                          READY   STATUS    RESTARTS   AGE     IP              NODE        NOMINATED NODE   READINESS GATES
alertmanager-main-0                           6/6     Running   0          2m46s   10.131.0.195    infra-01    <none>           <none>
alertmanager-main-1                           6/6     Running   0          3m18s   10.128.2.12     infra-02    <none>           <none>
cluster-monitoring-operator-dbcdff999-j5h79   2/2     Running   4          43d     10.130.0.9      master-02   <none>           <none>
grafana-d9b6fb97f-hswc9                       3/3     Running   0          3m19s   10.128.2.11     infra-02    <none>           <none>
kube-state-metrics-67784595cf-wd429           3/3     Running   0          3m21s   10.131.0.191    infra-01    <none>           <none>
node-exporter-2nk6f                           2/2     Running   4          43d     172.16.100.15   master-02   <none>           <none>
node-exporter-2sz27                           2/2     Running   4          43d     172.16.100.16   master-03   <none>           <none>
node-exporter-9dwjq                           2/2     Running   10         43d     172.16.100.18   infra-02    <none>           <none>
node-exporter-9ws9c                           2/2     Running   10         43d     172.16.100.19   infra-03    <none>           <none>
node-exporter-9z76z                           2/2     Running   6          43d     172.16.100.23   worker-01   <none>           <none>
node-exporter-lvl5p                           2/2     Running   6          43d     172.16.100.14   master-01   <none>           <none>
node-exporter-mjvd4                           2/2     Running   4          43d     172.16.100.17   infra-01    <none>           <none>
node-exporter-rkwmj                           2/2     Running   6          43d     172.16.100.24   worker-02   <none>           <none>
openshift-state-metrics-5977697c96-n8bpb      3/3     Running   0          3m21s   10.131.0.192    infra-01    <none>           <none>
prometheus-adapter-576d7d5d57-f68tw           1/1     Running   0          3m21s   10.128.2.13     infra-02    <none>           <none>
prometheus-adapter-576d7d5d57-jqf2f           1/1     Running   0          3m21s   10.130.2.17     infra-03    <none>           <none>
prometheus-k8s-0                              6/6     Running   0          2m56s   10.131.0.194    infra-01    <none>           <none>
prometheus-k8s-1                              6/6     Running   0          3m14s   10.128.2.15     infra-02    <none>           <none>
prometheus-operator-6b8cc99f77-6krtp          2/2     Running   0          3m29s   10.128.2.10     infra-02    <none>           <none>
telemeter-client-7966478b86-nz24b             3/3     Running   0          3m21s   10.131.0.193    infra-01    <none>           <none>
thanos-querier-5b4f5d7b56-lv9sh               6/6     Running   0          3m18s   10.130.2.18     infra-03    <none>           <none>
thanos-querier-5b4f5d7b56-svw8c               6/6     Running   0          3m18s   10.128.2.14     infra-02    <none>           <none>
[root@bastion-01 monitoring]#
```


## ロギング

- [OCP 4.10 Docs / インストール後の設定 / 5. インストール後のクラスタータスク / 5.6. リソースのインフラストラクチャーマシンセットへの移行 / 5.6.4. OpenShift Logging リソースの移動](https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.10/html-single/post-installation_configuration#infrastructure-moving-logging_post-install-cluster-tasks)


ロギングはまだ入れていなかったのでここで導入します。
ロギングの導入の流れは以下です。

1. OpenShift Elasticsearch Operatorの導入
2. Red Hat OpenShift Logging Operatorの導入
3. ロギングのインスタンス(`ClusterLogging`リソース)の作成(ここでelasticsearchとkibanaのnodeSlectorも設定します。)


今回はOperatorはGUIから導入しました。Operatorの導入自体は以下の手順通りですので割愛します。

- [OCP 4.10 Docs / Logging / 3. Installing the logging subsystem for Red Hat OpenShift / 3.1. Installing the logging subsystem for Red Hat OpenShift using the web console](https://access.redhat.com/documentation/en-us/openshift_container_platform/4.10/html-single/logging#cluster-logging-deploy-console_cluster-logging-deploying)


OpenShift Elasticsearch OperatorとRed Hat OpenShift Logging Operatorの導入が終わったら、ロギングのインスタンス(`ClusterLogging`リソース)を作成します。
マニフェストファイル作成用の作業用ディレクトリに移動し、マニフェストファイルを作成します。

クラスターロギンングのインスタンスを作成する際に、`elasticsearch`と`kibana`は最初からinfra nodeで稼働するようにnodeSelectorも入れておきます。

その他は以下のように設定しています。
- `redundancyPolicy`は`SingleRedundancy`とし、elasticsearchの`{nodeCount`は`3`としています。
- PVは別途local-storage operatoでelasticsarch用のlocalvolumeリソースで作成する予定ですが、ここでは一旦PVは作成せずにインスタンスを作成しています。(RHCOSの内蔵ディスクが溢れるのでPVはすぐに作成する必要があるので本当はこの時点でlocalvolumeを作成してPVの設定もしてしまった方が良いと思います。)


```bash
[root@bastion-01 ~]# mkdir -p work/manifest/logging
[root@bastion-01 ~]# cd work/manifest/logging/
[root@bastion-01 logging]#
[root@bastion-01 logging]# vi clo-instance-5.4-no-pv.yaml
[root@bastion-01 logging]# cat clo-instance-5.4-no-pv.yaml
```
```yaml:clo-instance-5.4-no-pv.yaml
apiVersion: "logging.openshift.io/v1"
kind: "ClusterLogging"
metadata:
  name: "instance"
  namespace: "openshift-logging"
spec:
  managementState: "Managed"
  logStore:
    type: "elasticsearch"
    retentionPolicy:
      application:
        maxAge: 1d
      infra:
        maxAge: 1d
      audit:
        maxAge: 1d
    elasticsearch:
      nodeCount: 3
      nodeSelector:
        node-role.kubernetes.io/infra: ''
      storage: {}
      redundancyPolicy: "SingleRedundancy"
  visualization:
    type: "kibana"
    kibana:
      replicas: 1
      nodeSelector:
        node-role.kubernetes.io/infra: ''
  collection:
    logs:
      type: "fluentd"
      fluentd: {}
```

ロギングのインスタンス(`ClusterLogging`リソース)を作成します。
```bash
[root@bastion-01 logging]# oc apply -f clo-instance-5.4-no-pv.yaml
clusterlogging.logging.openshift.io/instance created
[root@bastion-01 logging]#
[root@bastion-01 logging]# oc get clusterlogging -n openshift-logging
NAME       MANAGEMENT STATE
instance   Managed
[root@bastion-01 logging]#
```

Podがどのnodeで稼働しているか確認します。
- collector(fluentd)以外の`elasticsearch`と`kibana`のPodはinfra node上で稼働しています。
- (collector(fluentd)は、daemonsetとして、全node上で稼働しています。)

```
[root@bastion-01 logging]# oc get pod -n openshift-logging -o wide
NAME                                            READY   STATUS    RESTARTS   AGE   IP             NODE        NOMINATED NODE   READINESS GATES
cluster-logging-operator-665847fd47-4k8nk       1/1     Running   0          45m   10.131.0.105   infra-01    <none>           <none>
collector-44jz9                                 2/2     Running   0          20s   10.128.2.14    infra-02    <none>           <none>
collector-56t5f                                 2/2     Running   0          20s   10.131.2.7     worker-01   <none>           <none>
collector-75fc4                                 2/2     Running   0          20s   10.129.2.8     worker-02   <none>           <none>
collector-8xvrk                                 2/2     Running   0          26s   10.129.1.120   master-01   <none>           <none>
collector-dfg8g                                 2/2     Running   0          18s   10.130.2.15    infra-03    <none>           <none>
collector-nlg28                                 2/2     Running   0          25s   10.130.0.38    master-02   <none>           <none>
collector-qhx2x                                 2/2     Running   0          24s   10.131.0.111   infra-01    <none>           <none>
collector-tssdz                                 2/2     Running   0          27s   10.128.0.154   master-03   <none>           <none>
elasticsearch-cdm-hxg5zzyz-1-6c7cc986d5-r8vtk   1/2     Running   0          88s   10.128.2.12    infra-02    <none>           <none>
elasticsearch-cdm-hxg5zzyz-2-6c459cd687-dd8kr   1/2     Running   0          87s   10.131.0.109   infra-01    <none>           <none>
elasticsearch-cdm-hxg5zzyz-3-6c4c778db5-zttmd   1/2     Running   0          86s   10.130.2.14    infra-03    <none>           <none>
kibana-95cdccd9b-mbpvp                          2/2     Running   0          86s   10.130.2.13    infra-03    <none>           <none>
[root@bastion-01 logging]#
```

Kibanaでのindexパターンの作成や、ログストアのルートの公開などはここでは割愛します。




# アプリケーションPodをinfra nodeで稼働させない設定

infra nodeを作成し、インフラの運用コンポーネントをinfra node上で稼働させるようにしました。
この後は、アプリケーションPodをinfra nodeで稼働させない設定をする必要があります。


アプリケーションPodをinfra nodeで稼働させない設定のやり方は主に以下の2つがあります。

- (1) nodeSelectorのみを使用
- (2) nodeSelectorとtaint/tolerationを使用


どちらでも良いのですが、今回は「(1) nodeSelectorのみを使用」の方法をやっています。


## (1) nodeSelectorのみを使用

今回は、infra nodeとworker nodeはそれぞれ、「node-role.kubernetes.io/infra: ""」と「node-role.kubernetes.io/worker: ""」というノードラベルを持っており、`oc get node`の`ROLES`の値もinfra、workerと別れています。

(ノードラベル付与確認)
```bash
[root@bastion-01 ~]# oc get node
NAME        STATUS   ROLES    AGE   VERSION
infra-01    Ready    infra    40d   v1.23.5+b0357ed
infra-02    Ready    infra    40d   v1.23.5+b0357ed
infra-03    Ready    infra    40d   v1.23.5+b0357ed
master-01   Ready    master   40d   v1.23.5+b0357ed
master-02   Ready    master   40d   v1.23.5+b0357ed
master-03   Ready    master   40d   v1.23.5+b0357ed
worker-01   Ready    worker   40d   v1.23.5+b0357ed
worker-02   Ready    worker   40d   v1.23.5+b0357ed
[root@bastion-01 ~]#
```

(参考)infra node
```bash
[root@bastion-01 ~]# oc get node infra-01 -o yaml | grep -A 8 labels
  labels:
    beta.kubernetes.io/arch: amd64
    beta.kubernetes.io/os: linux
    kubernetes.io/arch: amd64
    kubernetes.io/hostname: infra-01
    kubernetes.io/os: linux
    node-role.kubernetes.io/infra: ""
    node.openshift.io/os_id: rhcos
  name: infra-01
[root@bastion-01 ~]#
```

(参考)worker node
```bash
[root@bastion-01 ~]# oc get node worker-01 -o yaml | grep -A 8 labels
  labels:
    beta.kubernetes.io/arch: amd64
    beta.kubernetes.io/os: linux
    kubernetes.io/arch: amd64
    kubernetes.io/hostname: worker-01
    kubernetes.io/os: linux
    node-role.kubernetes.io/worker: ""
    node.openshift.io/os_id: rhcos
  name: worker-01
[root@bastion-01 ~]#
```


アプリケーションPodを稼働させるProject(Namespace)にnodeSelectorとしてworker nodeのノードラベルの「node-role.kubernetes.io/worker: ""」を指定します。
この設定をすることで、このアプリケーションPod用のProject(Namespace)にPodをデプロイすると、必ずこのworker node上でPodが作成されるようになります。


アプリケーションPod用のProjectを作成します。

```bash
[root@bastion-01 ~]# oc new-project test
Now using project "test" on server "https://api.cluster-01.example.local:6443".

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

[root@bastion-01 ~]#
```

アプリケーションPod用のNamespaceの`openshift.io/node-selector`にworker nodeに付与されているノードラベルを設定します。
```bash
[root@bastion-01 ~]# oc annotate namespace test openshift.io/node-selector=node-role.kubernetes.io/worker=
namespace/test annotated
[root@bastion-01 ~]#
[root@bastion-01 ~]# oc get ns test -o yaml
apiVersion: v1
kind: Namespace
metadata:
  annotations:
    openshift.io/description: ""
    openshift.io/display-name: ""
    openshift.io/node-selector: node-role.kubernetes.io/worker=
    openshift.io/requester: admin
    openshift.io/sa.scc.mcs: s0:c26,c20
    openshift.io/sa.scc.supplemental-groups: 1000690000/10000
    openshift.io/sa.scc.uid-range: 1000690000/10000
  creationTimestamp: "2022-06-02T06:29:55Z"
  labels:
    kubernetes.io/metadata.name: test
  name: test
  resourceVersion: "33443927"
  uid: 6471fde8-6ef0-4f29-b1f5-f6b227ea566d
spec:
  finalizers:
  - kubernetes
status:
  phase: Active
[root@bastion-01 ~]#
```

こうすることで、このProject(Namespace)にPodを作成するとinfra nodeで稼働せずに、worker node上で稼働するようになります。


### (補足)infra node専用のMCPを作成していない場合

もし、「infra nodeの構成方法」で「(2) infra node専用の「MCP」を作成せず、infra node用のworker nodeに`infra`の「ノードラベル」を「追加」して構成」する方法を取っていた場合は、もう少しだけ工夫が必要です。

この場合は、MCPがmasterとworker用のものしかないため、infra nodeにworker用のMCPと紐づけるために、`worker`のノードラベルは削除はしません。
(`worker`のノードラベルを削除するとOCPアップデート時に対応するMCPがないためバージョンアップできなかったりします。)


```bash
[root@bastion-01 mcp]# oc get mcp
NAME     CONFIG                                             UPDATED   UPDATING   DEGRADED   MACHINECOUNT   READYMACHINECOUNT   UPDATEDMACHINECOUNT   DEGRADEDMACHINECOUNT   AGE
master   rendered-master-954e86f747cb1bc813dc88a53adc068c   True      False      False      3              3                   3                     0                      40d
worker   rendered-worker-8062fb3f341ce6e926a1678cc33db7f3   True      False      False      5              5                   5                     0                      40d
[root@bastion-01 mcp]#
```
```bash
[root@bastion-01 ~]# oc get node
NAME        STATUS   ROLES          AGE   VERSION
infra-01    Ready    infra,worker   63d   v1.23.5+b0357ed
infra-02    Ready    infra,worker   63d   v1.23.5+b0357ed
infra-03    Ready    infra,worker   63d   v1.23.5+b0357ed
master-01   Ready    master         63d   v1.23.5+b0357ed
master-02   Ready    master         63d   v1.23.5+b0357ed
master-03   Ready    master         63d   v1.23.5+b0357ed
worker-01   Ready    worker         63d   v1.23.5+b0357ed
worker-02   Ready    worker         63d   v1.23.5+b0357ed
[root@bastion-01 ~]#
```

この場合はアプリケーションPod用のProject(Namespace)に「`node-role.kubernetes.io/worker: ""`」を指定すると、infra nodeでも稼働してしまう可能性があるので、アプリケーションPod用の任意のノードラベルを付与します。
実際には「app="app-1"」とかなんでも良いのですが、KBのように「`node-role.kubernetes.io/app: ""`」としておくと、`oc get node`の`ROLES`列に`app`と表示されて、どこがアプリケーションPod用のnodeかが分かりやすくなります。



アプリケーションPodを稼働させたいworker nodeに`node-role.kubernetes.io/app=""`のノードラベルを付与します。

```bash
[root@bastion-01 ~]# oc label node worker-01 node-role.kubernetes.io/app=""
node/worker-01 labeled
[root@bastion-01 ~]# oc label node worker-02 node-role.kubernetes.io/app=""
node/worker-02 labeled
[root@bastion-01 ~]#
```
(worker-01)
```bash
[root@bastion-01 ~]# oc get node worker-01 -o yaml | grep -A 9 labels
  labels:
    beta.kubernetes.io/arch: amd64
    beta.kubernetes.io/os: linux
    kubernetes.io/arch: amd64
    kubernetes.io/hostname: worker-01
    kubernetes.io/os: linux
    node-role.kubernetes.io/app: ""
    node-role.kubernetes.io/worker: ""
    node.openshift.io/os_id: rhcos
  name: worker-01
[root@bastion-01 ~]#
```

`oc get node`でも`ROLES`列に`app`が表示されます。

```bash
[root@bastion-01 ~]# oc get node
NAME        STATUS   ROLES          AGE   VERSION
infra-01    Ready    infra,worker   63d   v1.23.5+b0357ed
infra-02    Ready    infra,worker   63d   v1.23.5+b0357ed
infra-03    Ready    infra,worker   63d   v1.23.5+b0357ed
master-01   Ready    master         63d   v1.23.5+b0357ed
master-02   Ready    master         63d   v1.23.5+b0357ed
master-03   Ready    master         63d   v1.23.5+b0357ed
worker-01   Ready    app,worker     63d   v1.23.5+b0357ed
worker-02   Ready    app,worker     63d   v1.23.5+b0357ed
[root@bastion-01 ~]#
```

あとはアプリケーションPodを稼働させるProject(Namespace)にnodeSlectoreとして先ほどworker nodeに付与したノードラベルを指定します。
これでこのProject(Namespace)にPodを作成すると、指定したworker nodeで稼働するようになります。

```bash
[root@bastion-01 ~]# oc new-project test
Now using project "test" on server "https://api.cluster-01.example.local:6443".

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

[root@bastion-01 ~]#
[root@bastion-01 ~]# oc annotate namespace test openshift.io/node-selector=node-role.kubernetes.io/app=
namespace/test annotated
[root@bastion-01 ~]#
[root@bastion-01 ~]# oc get ns test -o yaml
apiVersion: v1
kind: Namespace
metadata:
  annotations:
    openshift.io/description: ""
    openshift.io/display-name: ""
    openshift.io/node-selector: node-role.kubernetes.io/app=
    openshift.io/requester: admin
    openshift.io/sa.scc.mcs: s0:c26,c5
    openshift.io/sa.scc.supplemental-groups: 1000660000/10000
    openshift.io/sa.scc.uid-range: 1000660000/10000
  creationTimestamp: "2022-05-09T12:10:37Z"
  labels:
    kubernetes.io/metadata.name: test
  name: test
  resourceVersion: "19316925"
  uid: 7de494d4-4974-4b69-8bbb-ab36b8c69b4c
spec:
  finalizers:
  - kubernetes
status:
  phase: Active
[root@bastion-01 ~]#
```

この方法の考慮点としては、新しくworker nodeを追加する場合や、node障害でRHCOSを入れ直す場合などに、忘れずにアプリケーションPod用のノードラベルを付与する必要があります。



## (補足)(2) nodeSelectorとtaint/tolerationを使用

今回はやっていませんが、アプリケーションPodをworker nodeで稼働させる方法としてinfra nodeにtaintを付ける方法があります。
infra nodeにtaintを付与するため、アプリケーションPodを作成すると、taintのついていないworker node上で稼働することになります。
その代わり、インフラの運用コンポーネント(ルーター、OCP内部レジストリ、モニタリング、ロギング)側でtolerationを指定してinfra nodeで稼働させるように構成する必要があります。

詳細は以下のKBに載っています。

- [KB / Infrastructure Nodes in OpenShift 4](https://access.redhat.com/solutions/5034771)

OCPのドキュメントでは以下のあたりかなと思います。

- [OCP 4.10 Docs / インストール後の設定 / 5. インストール後のクラスタータスク / 5.5. マシンセットリソースのインフラストラクチャーノードへの割り当て / 5.5.1. テイントおよび容認を使用したインフラストラクチャーノードのワークロードのバインディング](https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.10/html-single/post-installation_configuration/index#binding-infra-node-workloads-using-taints-tolerations_post-install-cluster-tasks)
- [OCP 4.10 Docs / ネットワーク / 5. OPENSHIFT CONTAINER PLATFORM の INGRESS OPERATOR / 5.3. Ingress コントローラー設定パラメーター](https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.10/html-single/networking/index#nw-ingress-controller-configuration-parameters_configuring-ingress)
- [OCP 4.10 Docs / モニタリング / 2. モニタリングスタックの設定 / 2.7. モニタリングコンポーネントへの容認 (toleration) の割り当て](https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.10/html-single/monitoring/index#assigning-tolerations-to-monitoring-components_configuring-the-monitoring-stack)
- [OCP 4.10 Docs / ロギング / 22. ロギングデプロイメントの設定 / 22.7. 容認を使用した OpenShift Logging Pod 配置の制御](https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.10/html-single/logging/index#cluster-logging-tolerations)



大体どれも以下のような流れですが、モニタリングで少し例を記載します。

infra nodeにTaintの設定を入れます。

```bash
[root@bastion-01 ~]# oc label node <infra node> node-role.kubernetes.io/infra=
[root@bastion-01 ~]# oc adm taint nodes -l node-role.kubernetes.io/infra infra=reserved:NoSchedule infra=reserved:NoExecute
```

インフラの運用コンポーネントは、infra nodeのnodeSelectorとTolerationの設定を入れます。

(例) モニタリング(cluster-monitoring-configmap.yaml)
```yaml:cluster-monitoring-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: cluster-monitoring-config
  namespace: openshift-monitoring
data:
  config.yaml: |+
    alertmanagerMain:
      nodeSelector:
        node-role.kubernetes.io/infra: ""
      tolerations:
      - key: infra
        value: reserved
        effect: NoSchedule
      - key: infra
        value: reserved
        effect: NoExecute
    prometheusK8s:
      (以下同様)
```

こうすることでアプリケーションPodは、何も設定しなくてもinfra nodeのTaintの設定でworker nodeで稼働するようになります。



「(1) nodeSelectorのみを使用」でも「(2) nodeSelectorとtaint/tolerationを使用」でもどちらでも良いのですが、個人的には「(1) nodeSelectorのみを使用」の方が簡単かなと思います。