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?

全部手作業でMachineConfigOperatorの代わりにノードの設定変更をしてみよう

Last updated at Posted at 2025-12-01

こんにちは、Red Hatでアーキテクトをしている石井です。
普段は主に通信の事業者様向けにOpenShiftやOpenStack、Cephなどのコンサルティングをしています。
OpenShift Advent Calendar 2025 Day2ということで、Day2といえばMCO、MCOといえばDay2ですよね。
書きたいことが多すぎてアドベントカレンダー2日目にして重めな記事を書いてしまいましたが、MCOに興味があればぜひ読んでいただければと思います!

はじめに

OpenShiftが持つOperatorの一つにMachine Config Operator (MCO) があります。
ノードのインストール時の設定からDay2での設定変更、アップグレードまでを一元的に管理し、ノード台数が多い環境下に置いても共通化された設定を一括して適用・管理することが可能となります。
様々な設定ができてとても便利なOperatorなのですが、一方でそれ故にうっかり変な設定を投入してしまうと簡単にDegraded状態に陥り、ノードがなかなか戻ってきてくれず、最悪の場合にっちもさっちもいかなくなる…
「トホホ、もうMachineConfigはこりごりだよ〜」という苦い経験をされた方もいらっしゃるのではないかと思います。

今日はそんなMCOのことをちゃんと理解するために、MCOが実施している処理を肩代わりしてこちらでMachineConfigの設定追加を行ってみましょう。AIが人間の代わりに働いてくれることが増えた昨今ですが、逆に人間がOpenShiftの代わりに働いてあげたっていいですよね。逆に。

なお、MCO/MachineConfigについては公式ドキュメントOpenShift徹底入門の11.1.6章に詳しい説明がありますので、今回の内容と重複するところもありますが、ぜひそちらも参照してみてください。
また、ソースコードが大好きな皆様におかれましてはぜひrepositoryを必要に応じて直接ご確認いただければと思います。

今回の検証環境

今回はAWS上にIPIで構築したOpenShift 4.20.4を利用します。MCOの基本的な動作はどのプラットフォームのどのバージョンでもずっと変わっていないので別のプラットフォームや以前のバージョンでも今回の内容は基本的に同一の結果になるはずです。

[lab-user@bastion machineconfig]$ oc get clusterversion
NAME      VERSION   AVAILABLE   PROGRESSING   SINCE   STATUS
version   4.20.4    True        False         43h     Cluster version is 4.20.4
[lab-user@bastion machineconfig]$ oc get node
NAME                                        STATUS                     ROLES                  AGE   VERSION
ip-10-0-10-165.us-east-2.compute.internal   Ready                      control-plane,master   43h   v1.33.5
ip-10-0-11-138.us-east-2.compute.internal   Ready                      worker                 43h   v1.33.5
ip-10-0-13-189.us-east-2.compute.internal   Ready                      control-plane,master   43h   v1.33.5
ip-10-0-44-17.us-east-2.compute.internal    Ready                      control-plane,master   43h   v1.33.5
ip-10-0-61-247.us-east-2.compute.internal   Ready                      worker                 43h   v1.33.5
ip-10-0-61-98.us-east-2.compute.internal    Ready                      worker                 43h   v1.33.5

とりあえず壊してみる

まず、正しく動かすためには正しく動かないパターンを見てなぜ正しく動かないのかを見てみることが有効ですよね。少なくとも私はそう考えています。人は壊したクラスタの数だけ成長できる、そう信じてまずはにっちもさっちもいかない状況を作ってみましょう。

下記のMachineConfigを適用してみます。

99-worker-always-degraded.yaml
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
metadata:
  labels:
    machineconfiguration.openshift.io/role: worker
  name: 99-worker-always-degraded
spec:
  config:
    ignition:
      version: 3.5.0
    storage:
      files:
        - mode: 420
          overwrite: false
          path: /tmp/tmpfile

このMCは絶対に適用できない、必ず失敗する設定です。
なぜDegradedになるかが現時点でわかる方は、かなりMachineConfigへの造詣が深いと言えます。それが嬉しいかどうかはさておき。

[lab-user@bastion machineconfig]$ oc apply -f 99-worker-always-degraded.yaml
machineconfig.machineconfiguration.openshift.io/99-worker-always-degraded created
[lab-user@bastion machineconfig]$ oc get mcp
NAME     CONFIG                                             UPDATED   UPDATING   DEGRADED   MACHINECOUNT   READYMACHINECOUNT   UPDATEDMACHINECOUNT   DEGRADEDMACHINECOUNT   AGE
master   rendered-master-d868db98f6b40ee2e6719f5226faab58   True      False      False      3              3                   3                     0                      43h
worker   rendered-worker-2bc1dfd10eba3b11a558e7b8edddd605   False     True       True       3              0                   0                     1                      43h
[lab-user@bastion machineconfig]$ oc get node
NAME                                        STATUS                     ROLES                  AGE   VERSION
ip-10-0-10-165.us-east-2.compute.internal   Ready                      control-plane,master   46h   v1.33.5
ip-10-0-11-138.us-east-2.compute.internal   Ready,SchedulingDisabled   worker                 46h   v1.33.5
ip-10-0-13-189.us-east-2.compute.internal   Ready                      control-plane,master   46h   v1.33.5
ip-10-0-44-17.us-east-2.compute.internal    Ready                      control-plane,master   46h   v1.33.5
ip-10-0-61-247.us-east-2.compute.internal   Ready                      worker                 46h   v1.33.5
ip-10-0-61-98.us-east-2.compute.internal    Ready                      worker                 46h   v1.33.5

無事(?)、Degraded状態になりましたね。
このままでは別のMachineConfigも適用できないので困ってしまいます。Degraded状態は解消せねばなりません。
applyした設定が悪さしているはずなので、一旦元のMachineConfigに切り戻しましょう。

[lab-user@bastion machineconfig]$ oc delete -f 99-worker-always-degraded.yaml
machineconfig.machineconfiguration.openshift.io "99-worker-always-degraded" deleted
[lab-user@bastion machineconfig]$ oc get mcp
NAME     CONFIG                                             UPDATED   UPDATING   DEGRADED   MACHINECOUNT   READYMACHINECOUNT   UPDATEDMACHINECOUNT   DEGRADEDMACHINECOUNT   AGE
master   rendered-master-d868db98f6b40ee2e6719f5226faab58   True      False      False      3              3                   3                     0                      44h
worker   rendered-worker-2bc1dfd10eba3b11a558e7b8edddd605   False     True       True       3              2                   2                     1                      44h

まだ変更が加えられる前のノードはupdated/ready状態にカウントされるようになりましたが、Degradedになってしまったノードはそのままです。にっちもさっちもいかない環境が生まれました。
設定内容は違えどこの状態に陥った方は少なくないのではと思います。

Degradedになった原因の調査

とりあえず何が問題なのか、ログを見てみましょう。
pod一覧を取得、適当にあたりをつけてログを見ることにします。

[lab-user@bastion machineconfig]$ oc get pod -n openshift-machine-config-operator -o wide
NAME                                                             READY   STATUS      RESTARTS   AGE   IP            NODE                                        NOMINATED NODE   READINESS GATES
kube-rbac-proxy-crio-ip-10-0-10-165.us-east-2.compute.internal   1/1     Running     5          47h   10.0.10.165   ip-10-0-10-165.us-east-2.compute.internal   <none>           <none>
kube-rbac-proxy-crio-ip-10-0-11-138.us-east-2.compute.internal   1/1     Running     7          47h   10.0.11.138   ip-10-0-11-138.us-east-2.compute.internal   <none>           <none>
kube-rbac-proxy-crio-ip-10-0-13-189.us-east-2.compute.internal   1/1     Running     5          47h   10.0.13.189   ip-10-0-13-189.us-east-2.compute.internal   <none>           <none>
kube-rbac-proxy-crio-ip-10-0-44-17.us-east-2.compute.internal    1/1     Running     5          47h   10.0.44.17    ip-10-0-44-17.us-east-2.compute.internal    <none>           <none>
kube-rbac-proxy-crio-ip-10-0-61-247.us-east-2.compute.internal   1/1     Running     10         47h   10.0.61.247   ip-10-0-61-247.us-east-2.compute.internal   <none>           <none>
kube-rbac-proxy-crio-ip-10-0-61-98.us-east-2.compute.internal    1/1     Running     2          47h   10.0.61.98    ip-10-0-61-98.us-east-2.compute.internal    <none>           <none>
machine-config-controller-587ff89599-pjcj5                       2/2     Running     4          47h   10.128.0.24   ip-10-0-13-189.us-east-2.compute.internal   <none>           <none>
machine-config-daemon-2xh79                                      2/2     Running     13         41m   10.0.11.138   ip-10-0-11-138.us-east-2.compute.internal   <none>           <none>
machine-config-daemon-62kgp                                      2/2     Running     4          47h   10.0.44.17    ip-10-0-44-17.us-east-2.compute.internal    <none>           <none>
machine-config-daemon-hh9q9                                      2/2     Running     47         47h   10.0.61.247   ip-10-0-61-247.us-east-2.compute.internal   <none>           <none>
machine-config-daemon-ktgw5                                      2/2     Running     4          47h   10.0.10.165   ip-10-0-10-165.us-east-2.compute.internal   <none>           <none>
machine-config-daemon-w95fz                                      2/2     Running     4          47h   10.0.13.189   ip-10-0-13-189.us-east-2.compute.internal   <none>           <none>
machine-config-daemon-zzdjq                                      2/2     Running     4          47h   10.0.61.98    ip-10-0-61-98.us-east-2.compute.internal    <none>           <none>
machine-config-nodes-crd-cleanup-29402346-4wgrx                  0/1     Completed   0          47h   <none>        ip-10-0-44-17.us-east-2.compute.internal    <none>           <none>
machine-config-operator-5b66b667d4-mtmdm                         2/2     Running     4          47h   10.130.0.29   ip-10-0-44-17.us-east-2.compute.internal    <none>           <none>
machine-config-server-bp7tj                                      1/1     Running     2          47h   10.0.13.189   ip-10-0-13-189.us-east-2.compute.internal   <none>           <none>
machine-config-server-dc7ph                                      1/1     Running     2          47h   10.0.44.17    ip-10-0-44-17.us-east-2.compute.internal    <none>           <none>
machine-config-server-fq2jm                                      1/1     Running     2          47h   10.0.10.165   ip-10-0-10-165.us-east-2.compute.internal   <none>           <none>

Degradedになっているノード上の動作が怪しいので、ip-10-0-11-138.us-east-2.compute.internalで動作しているmachine-config-daemon-2xh79のログを見てみることにします。

[lab-user@bastion machineconfig]$ oc logs -n openshift-machine-config-operator machine-config-daemon-2xh79 --tail 20
Defaulted container "machine-config-daemon" out of: machine-config-daemon, kube-rbac-proxy
I1128 06:52:26.340960    5494 update.go:2685] "Disk currentConfig \"rendered-worker-54bfb1db8c9874ddc358422b48d57485\" overrides node's currentConfig annotation \"rendered-worker-2bc1dfd10eba3b11a558e7b8edddd605\""
I1128 06:52:26.343826    5494 daemon.go:2264] Validating against current config rendered-worker-54bfb1db8c9874ddc358422b48d57485
I1128 06:52:26.343888    5494 daemon.go:2176] SSH key location ("/home/core/.ssh/authorized_keys.d/ignition") up-to-date!
I1128 06:52:26.343900    5494 command_runner.go:24] Running captured: rpm-ostree kargs
E1128 06:52:26.411981    5494 writer.go:231] Marking Degraded due to: "unexpected on-disk state validating against rendered-worker-54bfb1db8c9874ddc358422b48d57485: could not stat file \"/tmp/tmpfile\": lstat /tmp/tmpfile: no such file or directory"
I1128 06:53:26.416849    5494 daemon.go:2066] Running: /run/machine-config-daemon-bin/nmstatectl persist-nic-names --root / --kargs-out /tmp/nmstate-kargs1434092388 --cleanup
[2025-11-28T06:53:26Z INFO  nmstatectl] Nmstate version: 2.2.54

[2025-11-28T06:53:26Z INFO  nmstatectl::persist_nic] /etc/systemd/network/.nmstate-persist.stamp does not exist, no need to clean up
I1128 06:53:26.427723    5494 daemon.go:1654] Previous boot ostree-finalize-staged.service appears successful
I1128 06:53:26.427752    5494 daemon.go:1795] Current config: rendered-worker-2bc1dfd10eba3b11a558e7b8edddd605
I1128 06:53:26.427761    5494 daemon.go:1796] Desired config: rendered-worker-54bfb1db8c9874ddc358422b48d57485
I1128 06:53:26.427768    5494 daemon.go:1804] state: Degraded
I1128 06:53:26.427789    5494 update.go:2640] Running: rpm-ostree cleanup -r
Deployments unchanged.
I1128 06:53:26.486520    5494 update.go:2685] "Disk currentConfig \"rendered-worker-54bfb1db8c9874ddc358422b48d57485\" overrides node's currentConfig annotation \"rendered-worker-2bc1dfd10eba3b11a558e7b8edddd605\""
I1128 06:53:26.489342    5494 daemon.go:2264] Validating against current config rendered-worker-54bfb1db8c9874ddc358422b48d57485
I1128 06:53:26.489404    5494 daemon.go:2176] SSH key location ("/home/core/.ssh/authorized_keys.d/ignition") up-to-date!
I1128 06:53:26.489423    5494 command_runner.go:24] Running captured: rpm-ostree kargs
E1128 06:53:26.556733    5494 writer.go:231] Marking Degraded due to: "unexpected on-disk state validating against rendered-worker-54bfb1db8c9874ddc358422b48d57485: could not stat file \"/tmp/tmpfile\": lstat /tmp/tmpfile: no such file or directory"
[lab-user@bastion machineconfig]$

最終行にちょうどDegradedになった理由が書いてありました。 /tmp/tmpfile: no such file or directoryとのことです。

[lab-user@bastion machineconfig]$ oc debug node/ip-10-0-11-138.us-east-2.compute.internal -- chroot /host ls -lah /tmp/
Starting pod/ip-10-0-11-138us-east-2computeinternal-debug-n254s ...
To use host binaries, run `chroot /host`. Instead, if you need to access host namespaces, run `nsenter -a -t 1`.
total 4.0K
drwxrwxrwt. 11 root root  220 Nov 28 07:03 .
drwxr-xr-x. 12 root root 4.0K Jan  1  1970 ..
drwxrwxrwt.  2 root root   40 Nov 28 06:47 .ICE-unix
drwxrwxrwt.  2 root root   40 Nov 28 06:47 .X11-unix
drwxrwxrwt.  2 root root   40 Nov 28 06:47 .XIM-unix
drwxrwxrwt.  2 root root   40 Nov 28 06:47 .font-unix
drwx------.  3 root root   60 Nov 28 06:47 systemd-private-aaaf68eaa82747e08ca87549ac9732cb-chronyd.service-u7yTRz
drwx------.  3 root root   60 Nov 28 06:47 systemd-private-aaaf68eaa82747e08ca87549ac9732cb-dbus-broker.service-PMxhsC
drwx------.  3 root root   60 Nov 28 06:47 systemd-private-aaaf68eaa82747e08ca87549ac9732cb-irqbalance.service-VKrVQr
drwx------.  3 root root   60 Nov 28 06:48 systemd-private-aaaf68eaa82747e08ca87549ac9732cb-rpm-ostreed.service-mjDkMZ
drwx------.  3 root root   60 Nov 28 06:47 systemd-private-aaaf68eaa82747e08ca87549ac9732cb-systemd-logind.service-hjezOT

Removing debug pod ...

MachineConfigは新たな設定の適用時に、特定の条件の変更を除いて変更適用のためのリブート処理を行います。
今回追加したいファイルは/tmp/配下なのでmachine-config-daemonによって一度ファイルが配置されるものの、リブートのタイミングでファイルが消えてしまい、再起動後のmachine-config-daemonから見るとあるべき姿と一致しない、という状態が発生していることがDegradedの原因でした。

復旧させてみる

さて、切り戻しをしようとして投入したMachineConfigをdeleteしたので、現在のあるべき姿としては/tmp/tmpfileは別に無くても良いはずです。
しかしながら上記のログを見る限り、ノードから見たあるべき姿は/tmp/tmpfileがノードに存在している状態、ということになります。ノード、厳密に言えばノード上で動作するmachine-config-daemonはどこを参照してあるべき姿を定義しているのでしょうか。

ドキュメントを見てもそれらしい情報がなかったのでソースコードを直接確認したところ、/etc/machine-config-daemon/currentconfigであることが確認できました。

さっそく中身を確認してみましょう。

[lab-user@bastion machineconfig]$ oc debug node/ip-10-0-11-138.us-east-2.compute.internal -- chroot /host cat /etc/machine-config-daemon/currentconfig
Starting pod/ip-10-0-11-138us-east-2computeinternal-debug-m97lt ...
To use host binaries, run `chroot /host`. Instead, if you need to access host namespaces, run `nsenter -a -t 1`.
{"kind":"MachineConfig","apiVersion":"machineconfiguration.openshift.io/v1","metadata":{"name":"rendered-worker-54bfb1db8c9874ddc358422b48d57485","uid":"d1106696-4db9-4651-838b-58fc9102247a","resourceVersion":"233700","generation":1,"creationTimestamp":"2025-11-28T02:37:40Z","annotations":{"machineconfiguration.openshift.io/generated-by-controller-version":"0c58628362f7471071da6d0263fa65766691f28c","machineconfiguration.openshift.io/release-image-version":"4.20.4"},"ownerReferences":[{"apiVersion":"machineconfiguration.openshift.io/v1","kind":"MachineConfigPool","name":"worker","uid":"10f15d2b-342a-4406-8573-3306f397b211","controller":true,"blockOwnerDeletion":true}],"managedFields":[{"manager":"machine-config-controller","operation":"Update","apiVersion":"machineconfiguration.openshift.io/v1","time":"2025-11-28T02:37:40Z",
...snip...
Removing debug pod ...

無邪気にcatすると長大な1行のファイルが出てきますが、json形式のようなのでjqで整形して見てみましょう。

[lab-user@bastion machineconfig]$ oc debug node/ip-10-0-11-138.us-east-2.compute.internal -- chroot /host cat /etc/machine-config-daemon/currentconfig | jq . | head -n 10
Starting pod/ip-10-0-11-138us-east-2computeinternal-debug-9vlpc ...
To use host binaries, run `chroot /host`. Instead, if you need to access host namespaces, run `nsenter -a -t 1`.

Removing debug pod ...
{
  "kind": "MachineConfig",
  "apiVersion": "machineconfiguration.openshift.io/v1",
  "metadata": {
    "name": "rendered-worker-54bfb1db8c9874ddc358422b48d57485",
    "uid": "d1106696-4db9-4651-838b-58fc9102247a",
    "resourceVersion": "233700",
    "generation": 1,
    "creationTimestamp": "2025-11-28T02:37:40Z",
    "annotations": {

なんだか見覚えがあるな…?

[lab-user@bastion machineconfig]$ oc get mc rendered-worker-54bfb1db8c9874ddc358422b48d57485 -o json | head -n 9
{
    "apiVersion": "machineconfiguration.openshift.io/v1",
    "kind": "MachineConfig",
    "metadata": {
        "annotations": {
            "machineconfiguration.openshift.io/generated-by-controller-version": "0c58628362f7471071da6d0263fa65766691f28c",
            "machineconfiguration.openshift.io/release-image-version": "4.20.4"
        },
        "creationTimestamp": "2025-11-28T02:37:40Z",
        "generation": 1,
        "name": "rendered-worker-54bfb1db8c9874ddc358422b48d57485",
        "ownerReferences": [
            {
                "apiVersion": "machineconfiguration.openshift.io/v1",
                "blockOwnerDeletion": true,
[lab-user@bastion machineconfig]$

そう、順番の違いと.metadata.managedFieldsの追加はありますがこれはほぼoc get mcで出力されるレンダリングされたrenderedファイルです。

ということはどうにかしてこれを元の設定に戻してあげたいですね。
今しがたさらっと述べた.metadata.managedFieldsを見てみると、このような設定が見えます。

[lab-user@bastion machineconfig]$ oc debug node/ip-10-0-11-138.us-east-2.compute.internal -- chroot /host cat /etc/machine-config-daemon/currentconfig | jq .metadata.managedFields
Starting pod/ip-10-0-11-138us-east-2computeinternal-debug-zb5rz ...
To use host binaries, run `chroot /host`. Instead, if you need to access host namespaces, run `nsenter -a -t 1`.

Removing debug pod ...
[
  {
    "manager": "machine-config-controller",
    "operation": "Update",
    "apiVersion": "machineconfiguration.openshift.io/v1",
    "time": "2025-11-28T02:37:40Z",
    "fieldsType": "FieldsV1",
    "fieldsV1": {
      "f:metadata": {
        "f:annotations": {
          ".": {},
          "f:machineconfiguration.openshift.io/generated-by-controller-version": {},
          "f:machineconfiguration.openshift.io/release-image-version": {}
        },
        "f:ownerReferences": {
          ".": {},
          "k:{\"uid\":\"10f15d2b-342a-4406-8573-3306f397b211\"}": {}
        }
      },
      "f:spec": {
        ".": {},
...snip...

どうやらmachine-config-controllerがこのファイルを配っているようなのでログをちょっと見てみます。

[lab-user@bastion machineconfig]$ oc logs -n openshift-machine-config-operator machine-config-controller-587ff89599-pjcj5
...snip...
I1129 05:23:45.009999       1 event.go:377] Event(v1.ObjectReference{Kind:"MachineConfigPool", Namespace:"openshift-machine-config-operator", Name:"worker", UID:"10f15d2b-342a-4406-8573-3306f397b211", APIVersion:"machineconfiguration.openshift.io/v1", ResourceVersion:"373714", FieldPath:""}): type: 'Normal' reason: 'SetDesiredConfig' Targeted node ip-10-0-11-138.us-east-2.compute.internal to MachineConfig: rendered-worker-54bfb1db8c9874ddc358422b48d57485
...snip...

対象ノードのDesiredConfigを変更した、というようなログが出ていますが、ノードのDesiredConfigがどこに定義されているかというと、ここです。ノードのannotationに含まれているんですね。

[lab-user@bastion machineconfig]$ oc get node ip-10-0-11-138.us-east-2.compute.internal -o json | jq .metadata.annotations
{
  ...snip...
  "machineconfiguration.openshift.io/currentConfig": "rendered-worker-2bc1dfd10eba3b11a558e7b8edddd605",
  "machineconfiguration.openshift.io/desiredConfig": "rendered-worker-54bfb1db8c9874ddc358422b48d57485",
  "machineconfiguration.openshift.io/desiredDrain": "drain-rendered-worker-54bfb1db8c9874ddc358422b48d57485",
  "machineconfiguration.openshift.io/lastAppliedDrain": "drain-rendered-worker-54bfb1db8c9874ddc358422b48d57485",
  ...snip...
  "machineconfiguration.openshift.io/reason": "unexpected on-disk state validating against rendered-worker-54bfb1db8c9874ddc358422b48d57485: could not stat file \"/tmp/tmpfile\": lstat /tmp/tmpfile: no such file or directory",
  "machineconfiguration.openshift.io/state": "Degraded",
  "volumes.kubernetes.io/controller-managed-attach-detach": "true"
}

ということは、このdesiredConfigを一旦editしちゃえばいいんじゃない?という雑な考えで書き換えてみましょう。エイヤ。

[lab-user@bastion machineconfig]$ oc get node ip-10-0-11-138.us-east-2.compute.internal -o yaml | grep -i config
    cloud.network.openshift.io/egress-ipconfig: '[{"interface":"eni-0b33c94a6428cad5d","ifaddr":{"ipv4":"10.0.0.0/18"},"capacity":{"ipv4":29,"ipv6":30}}]'
    k8s.ovn.org/l3-gateway-config: '{"default":{"mode":"shared","bridge-id":"br-ex","interface-id":"br-ex_ip-10-0-11-138.us-east-2.compute.internal","mac-address":"02:26:31:89:fa:c7","ip-addresses":["10.0.11.138/18"],"ip-address":"10.0.11.138/18","next-hops":["10.0.0.1"],"next-hop":"10.0.0.1","node-port-enable":"true","vlan-id":"0"}}'
    machineconfiguration.openshift.io/controlPlaneTopology: HighlyAvailable
    machineconfiguration.openshift.io/currentConfig: rendered-worker-2bc1dfd10eba3b11a558e7b8edddd605
    machineconfiguration.openshift.io/desiredConfig: rendered-worker-2bc1dfd10eba3b11a558e7b8edddd605
    machineconfiguration.openshift.io/desiredDrain: drain-rendered-worker-54bfb1db8c9874ddc358422b48d57485
    machineconfiguration.openshift.io/lastAppliedDrain: drain-rendered-worker-54bfb1db8c9874ddc358422b48d57485
    machineconfiguration.openshift.io/lastObservedServerCAAnnotation: "false"
    machineconfiguration.openshift.io/lastSyncedControllerConfigResourceVersion: "370770"
    machineconfiguration.openshift.io/post-config-action: ""
    machineconfiguration.openshift.io/reason: 'unexpected on-disk state validating'
    machineconfiguration.openshift.io/state: Degraded
[lab-user@bastion machineconfig]$ oc get node,mcp
NAME                                             STATUS                     ROLES                  AGE     VERSION
node/ip-10-0-10-165.us-east-2.compute.internal   Ready                      control-plane,master   2d22h   v1.33.5
node/ip-10-0-11-138.us-east-2.compute.internal   Ready,SchedulingDisabled   worker                 2d22h   v1.33.5
node/ip-10-0-13-189.us-east-2.compute.internal   Ready                      control-plane,master   2d22h   v1.33.5
node/ip-10-0-44-17.us-east-2.compute.internal    Ready                      control-plane,master   2d22h   v1.33.5
node/ip-10-0-61-247.us-east-2.compute.internal   Ready                      worker                 2d22h   v1.33.5
node/ip-10-0-61-98.us-east-2.compute.internal    Ready                      worker                 2d22h   v1.33.5

NAME                                                         CONFIG                                             UPDATED   UPDATING   DEGRADED   MACHINECOUNT   READYMACHINECOUNT   UPDATEDMACHINECOUNT   DEGRADEDMACHINECOUNT   AGE
machineconfigpool.machineconfiguration.openshift.io/master   rendered-master-d868db98f6b40ee2e6719f5226faab58   True      False      False      3              3                   3                     0                      2d22h
machineconfigpool.machineconfiguration.openshift.io/worker   rendered-worker-2bc1dfd10eba3b11a558e7b8edddd605   False     True       True       3              2                   2                     1                      2d22h

どうやらまだDegradedは解消されないようです。

再びmachine-config-daemonのログを見ると理由が書いてありました。

[lab-user@bastion machineconfig]$ oc logs -n openshift-machine-config-operator machine-config-daemon-2xh79
...snip...
I1129 05:40:21.935420    9699 update.go:2685] "Disk currentConfig \"rendered-worker-54bfb1db8c9874ddc358422b48d57485\" overrides node's currentConfig annotation \"rendered-worker-2bc1dfd10eba3b11a558e7b8edddd605\""
...snip...

ふむふむ、先程の/etc/machine-config-daemon/currentconfigの設定がnodeのannotationに記載されたcurrentConfigよりも優先されて状態が不一致になって止まっているため、その先のDesiredConfigを定義してももはや意味が無いそうです。万事休す。

じゃあどうすればよいの、という答えはこちらのKCSにあります。
How to skip validation of failing / stuck MachineConfig in OCP 4?
https://access.redhat.com/solutions/5414371

currentconfigを消して空にしてしまうか、/run/machine-config-daemon-forceをtouchすることで自動的に現状のconfigを一回適用済みとみなしてその先に進めるようになります。

ということで、/run/machine-config-daemon-forceを適用してみましょう。

[lab-user@bastion machineconfig]$ oc debug node/ip-10-0-11-138.us-east-2.compute.internal -- chroot /host touch /run/machine-config-daemon-force
Starting pod/ip-10-0-11-138us-east-2computeinternal-debug-vt79k ...
To use host binaries, run `chroot /host`. Instead, if you need to access host namespaces, run `nsenter -a -t 1`

Removing debug pod ...

なお、このタイミングでノードがSchedulingDisabledのままだとmachine-config-daemon podが再起動できずにCrashLoopBackOffに陥ります。oc adm uncordonを実施しましょう。

[lab-user@bastion machineconfig]$ oc adm uncordon ip-10-0-11-138.us-east-2.compute.internal
node/ip-10-0-11-138.us-east-2.compute.internal uncordoned

なんとか最終的に元の状態に戻すことができました。

[lab-user@bastion machineconfig]$ oc get mcp
NAME     CONFIG                                             UPDATED   UPDATING   DEGRADED   MACHINECOUNT   READYMACHINECOUNT   UPDATEDMACHINECOUNT   DEGRADEDMACHINECOUNT   AGE
master   rendered-master-d868db98f6b40ee2e6719f5226faab58   True      False      False      3              3                   3                     0                      2d22h
worker   rendered-worker-2bc1dfd10eba3b11a558e7b8edddd605   True      False      False      3              3                   3                     0                      2d22h

ちなみに今回の場合は変更後の変更内容が存在せず、実質的なノードの状態としては以前のMachineConfigと同一の状態となっているためこの方法で切り戻しても問題ありませんが、変更した内容によってはノードの状態が既に書き換えられている可能性があるので、変更された内容が把握できていない場合にこのような切り戻しをすることはあまりオススメしません。

目指せ人間MCO

長過ぎる前置きを終えて長過ぎる本題に入りたいと思います。

先の例で使ったMachineConfigの代わりに、今度は下記のMacineConfigを適用することを考えます。
ファイルの生成先パスを変えただけです。

99-worker-add-mc-test.yaml
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
metadata:
  labels:
    machineconfiguration.openshift.io/role: worker
  name: 99-worker-add-mc-test
spec:
  config:
    ignition:
      version: 3.5.0
    storage:
      files:
        - mode: 420
          overwrite: false
          path: /usr/local/bin/mc-test

このMachineConfigを人力で適用して、MCOに気付かれなければ成功です。

MachineConfigOperator上のmachine-config-controller/machine-config-server/machine-config-daemonにはお休みしてもらいましょう。

[lab-user@bastion humanmco-test]$ oc scale -n openshift-machine-config-operator deployment.apps/machine-config-controller --replicas=0
Warning: spec.template.spec.nodeSelector[node-role.kubernetes.io/master]: use "node-role.kubernetes.io/control-plane" instead
deployment.apps/machine-config-controller scaled
[lab-user@bastion humanmco-test]$  oc -n openshift-machine-config-operator patch daemonset machine-config-server -p '{"spec": {"template": {"spec": {"nodeSelector": {"non-existing": "true"}}}}}'
Warning: spec.template.spec.nodeSelector[node-role.kubernetes.io/master]: use "node-role.kubernetes.io/control-plane" instead
daemonset.apps/machine-config-server patched
[lab-user@bastion humanmco-test]$ oc -n openshift-machine-config-operator patch daemonset machine-config-daemon -p '{"spec": {"template": {"spec": {"nodeSelector": {"non-existing": "true"}}}}}'
daemonset.apps/machine-config-daemon patched
[lab-user@bastion humanmco-test]$  oc get pod -n openshift-machine-config-operator
NAME                                                             READY   STATUS      RESTARTS   AGE
kube-rbac-proxy-crio-ip-10-0-10-165.us-east-2.compute.internal   1/1     Running     9          4d21h
kube-rbac-proxy-crio-ip-10-0-13-189.us-east-2.compute.internal   1/1     Running     9          4d21h
kube-rbac-proxy-crio-ip-10-0-14-22.us-east-2.compute.internal    1/1     Running     7          12h
kube-rbac-proxy-crio-ip-10-0-40-69.us-east-2.compute.internal    1/1     Running     6          12h
kube-rbac-proxy-crio-ip-10-0-44-17.us-east-2.compute.internal    1/1     Running     9          4d21h
kube-rbac-proxy-crio-ip-10-0-61-98.us-east-2.compute.internal    1/1     Running     16         4d20h
machine-config-nodes-crd-cleanup-29402346-4wgrx                  0/1     Completed   0          4d21h
machine-config-operator-5b66b667d4-mtmdm                         2/2     Running     12         4d21h

まず、今回のMachineConfigを適用することで新たに生成されるはずのrenderedファイルを作成します。普段は自動で生成されるCRです。
適用するMachineConfigはworkerが対象なので、workerのMachineConfigPoolに現在適用されているrenderedファイルを確認します。

[lab-user@bastion humanmco-test]$ oc get mcp worker
NAME     CONFIG                                             UPDATED   UPDATING   DEGRADED   MACHINECOUNT   READYMACHINECOUNT   UPDATEDMACHINECOUNT   DEGRADEDMACHINECOUNT   AGE
worker   rendered-worker-2bc1dfd10eba3b11a558e7b8edddd605   True      False      False      3              3                   3                     0                      4d21h

renderedファイルをyaml形式で取得します。

[lab-user@bastion humanmco-test]$ oc get mc rendered-worker-2bc1dfd10eba3b11a558e7b8edddd605 -o yaml > rendered-worker-2bc1dfd10eba3b11a558e7b8edddd605.yaml

コピーして編集します。

[lab-user@bastion humanmco-test]$ cp rendered-worker-2bc1dfd10eba3b11a558e7b8edddd605.yaml new-rendered-mc.yaml
[lab-user@bastion humanmco-test]$ vi new-rendered-mc.yaml
[lab-user@bastion humanmco-test]$ diff rendered-worker-2bc1dfd10eba3b11a558e7b8edddd605.yaml new-rendered-mc.yaml
9c9
<   name: rendered-worker-2bc1dfd10eba3b11a558e7b8edddd605
---
>   name: rendered-worker-b13c0797871dd0befef5e24d34172a31
267a268,270
>       - mode: 420
>         overwrite: false
>         path: /usr/local/bin/mc-test

変更箇所は2点、新たに追加するMachineConfigの設定内容を追加し、CRの名前を変更しました。
なんかいきなりハッシュ値出てきたな、とお思いかもしれませんが、CRの名前に使うハッシュ値は下記で計算されます。
https://github.com/openshift/machine-config-operator/blob/release-4.20/pkg/controller/render/hash.go

config内のspec部分にmachineconfigのsalt文字列を加えてmd5のハッシュを計算すればよいのですが、configの形式がgoのオブジェクト形式にデシリアライズされたものなので容易に計算できるものではないです。やる必要も無いですしやる人はいないと思いますが、上記のソースコードを元に別途yamlからハッシュ値を計算するgoスクリプトを書くことで今回は対応しました。

main.go
// main.go
package main

import (
	//nolint:gosec
	"crypto/md5"
	"fmt"
	"os"
	"github.com/ghodss/yaml"
	"k8s.io/apimachinery/pkg/runtime/serializer/json"
	"k8s.io/apimachinery/pkg/runtime/schema"
	mcfgv1 "github.com/openshift/api/machineconfiguration/v1"
	"k8s.io/client-go/kubernetes/scheme"
	yamlutil "k8s.io/apimachinery/pkg/runtime/serializer/yaml"
)

var (
	// salt is 80 random bytes.
	// The salt was generated by `od -vAn -N80 -tu1 < /dev/urandom`. Do not change it.
	salt = []byte{
		16, 124, 206, 228, 139, 56, 175, 175, 79, 229, 134, 118, 157, 154, 211, 110,
		25, 93, 47, 253, 172, 106, 37, 7, 174, 13, 160, 185, 110, 17, 87, 52,
		219, 131, 12, 206, 218, 141, 116, 135, 188, 181, 192, 151, 233, 62, 126, 165,
		64, 83, 179, 119, 15, 168, 208, 197, 146, 107, 58, 227, 133, 188, 238, 26,
		33, 26, 235, 202, 32, 173, 31, 234, 41, 144, 148, 79, 6, 206, 23, 22,
	}
)

func hashData(data []byte) ([]byte, error) {
	//nolint:gosec
	hasher := md5.New()
	if _, err := hasher.Write(salt); err != nil {
		return nil, fmt.Errorf("error computing hash: %w", err)
	}
	if _, err := hasher.Write(data); err != nil {
		return nil, fmt.Errorf("error computing hash: %w", err)
	}
	return hasher.Sum(nil), nil
}

// Given a config from a pool, generate a name for the config
// of the form rendered-<poolname>-<hash>
func main() {
	mcfgv1.AddToScheme(scheme.Scheme)
	jsonSerializer := json.NewSerializerWithOptions(
		json.SimpleMetaFactory{},
		nil,
		scheme.Scheme,
		json.SerializerOptions{},
	)
	yamlDecoder := yamlutil.NewDecodingSerializer(jsonSerializer)
	yamlFile := os.Args[1]

	config, err := os.ReadFile(yamlFile)
	if err != nil {
		fmt.Fprintf(os.Stderr, "error: %v\n", err)
		os.Exit(1)
	}

        gvk := schema.GroupVersionKind{
		Group:   "machineconfiguration.openshift.io",
		Version: "v1",
		Kind:    "MachineConfig",
	}

	obj := &mcfgv1.MachineConfig{}
	_, _, err = yamlDecoder.Decode(config, &gvk, obj)
	if err != nil {
		fmt.Printf("Error decoding YAML to MachineConfig: %v\n", err)
		os.Exit(1)
	}

	data, err := yaml.Marshal(obj.Spec)
	if err != nil {
		fmt.Fprintf(os.Stderr, "error: %v\n", err)
		os.Exit(1)
	}

	h, err := hashData(data)
	if err != nil {
		fmt.Fprintf(os.Stderr, "error: %v\n", err)
		os.Exit(1)
	}
	fmt.Printf("rendered-worker-%x\n", h)
}
[lab-user@bastion mco-hasher]$ go build -o machine-hasher main.go
[lab-user@bastion mco-hasher]$ ./machine-hasher ../humanmco-test/new-rendered-mc.yaml
rendered-worker-b13c0797871dd0befef5e24d34172a31

生成したrenderedファイルと元のMachineConfigファイルを適用します。MCOがお休み中なのでCRを生成してもMCPなどに変化は発生しません。

[lab-user@bastion humanmco-test]$ oc apply -f 99-worker-add-mc-test.yaml
machineconfig.machineconfiguration.openshift.io/99-worker-add-mc-test created
[lab-user@bastion humanmco-test]$ oc apply -f new-rendered-mc.yaml
machineconfig.machineconfiguration.openshift.io/rendered-worker-b13c0797871dd0befef5e24d34172a31 created
[lab-user@bastion humanmco-test]$ oc get mc
NAME                                               GENERATEDBYCONTROLLER                      IGNITIONVERSION   AGE
00-master                                          0c58628362f7471071da6d0263fa65766691f28c   3.5.0             4d21h
00-worker                                          0c58628362f7471071da6d0263fa65766691f28c   3.5.0             4d21h
01-master-container-runtime                        0c58628362f7471071da6d0263fa65766691f28c   3.5.0             4d21h
01-master-kubelet                                  0c58628362f7471071da6d0263fa65766691f28c   3.5.0             4d21h
01-worker-container-runtime                        0c58628362f7471071da6d0263fa65766691f28c   3.5.0             4d21h
01-worker-kubelet                                  0c58628362f7471071da6d0263fa65766691f28c   3.5.0             4d21h
97-master-generated-kubelet                        0c58628362f7471071da6d0263fa65766691f28c   3.5.0             4d21h
97-worker-generated-kubelet                        0c58628362f7471071da6d0263fa65766691f28c   3.5.0             4d21h
98-master-generated-kubelet                        0c58628362f7471071da6d0263fa65766691f28c   3.5.0             4d21h
98-worker-generated-kubelet                        0c58628362f7471071da6d0263fa65766691f28c   3.5.0             4d21h
99-master-generated-registries                     0c58628362f7471071da6d0263fa65766691f28c   3.5.0             4d21h
99-master-ssh                                                                                 3.2.0             4d21h
99-worker-add-mc-test                                                                         3.5.0             13s
99-worker-generated-registries                     0c58628362f7471071da6d0263fa65766691f28c   3.5.0             4d21h
99-worker-ssh                                                                                 3.2.0             4d21h
rendered-master-d868db98f6b40ee2e6719f5226faab58   0c58628362f7471071da6d0263fa65766691f28c   3.5.0             4d21h
rendered-worker-2bc1dfd10eba3b11a558e7b8edddd605   0c58628362f7471071da6d0263fa65766691f28c   3.5.0             3d2h
rendered-worker-3185bc599fe45dfa55589eb49fb732a5   0c58628362f7471071da6d0263fa65766691f28c   3.5.0             4d21h
rendered-worker-54bfb1db8c9874ddc358422b48d57485   0c58628362f7471071da6d0263fa65766691f28c   3.5.0             37h
rendered-worker-b13c0797871dd0befef5e24d34172a31   0c58628362f7471071da6d0263fa65766691f28c   3.5.0             8s
[lab-user@bastion humanmco-test]$ oc get mcp
NAME     CONFIG                                             UPDATED   UPDATING   DEGRADED   MACHINECOUNT   READYMACHINECOUNT   UPDATEDMACHINECOUNT   DEGRADEDMACHINECOUNT   AGE
master   rendered-master-d868db98f6b40ee2e6719f5226faab58   True      False      False      3              3                   3                     0                      4d21h
worker   rendered-worker-2bc1dfd10eba3b11a558e7b8edddd605   True      False      False      3              3                   3                     0                      4d21h

ノード上のcurrentconfigを置き換えるためのファイルも作っておきます。
差分となる.metadata.managedFieldsの情報も元のcurrentconfigから流用してしまいましょう。新規のrenderedのjsonファイルが持つ値があればそれで上書きを行いますが、kubectl.kubernetes.io/last-applied-configurationのannotationだけは不要なので消しておきます。また、.metadata.managedFields[0].timeの項目は元のcurrentconfig側にしかありませんが、ここはrendered machineconfig CRの時刻情報と一致させたいのでここも別途上書きしておきます。

[lab-user@bastion humanmco-test]$ oc debug node/ip-10-0-14-22.us-east-2.compute.internal -- chroot /host cat /etc/machine-config-daemon/currentconfig > currentconfig.json
Starting pod/ip-10-0-14-22us-east-2computeinternal-debug-c69fm ...
To use host binaries, run `chroot /host`. Instead, if you need to access host namespaces, run `nsenter -a -t 1`.

Removing debug pod ...
[lab-user@bastion humanmco-test]$ oc get mc rendered-worker-b13c0797871dd0befef5e24d34172a31 -o json > rendered-worker-b13c0797871dd0befef5e24d34172a31.json
[lab-user@bastion humanmco-test]$ jq -s '.[0] * .[1]' currentconfig.json rendered-worker-b13c0797871dd0befef5e24d34172a31.json | jq 'del(.metadata.annotations["kubectl.kubernetes.io/last-applied-configuration"])' | jq '.metadata.managedFields[0].time = .metadata.creationTimestamp' > new-currentconfig.json
[lab-user@bastion humanmco-test]$ cat new-currentconfig.json | jq . -c > new-currentconfig.txt

次に3台のwoker node側を手作業で変更しましょう。

[lab-user@bastion humanmco-test]$ oc debug node/ip-10-0-14-22.us-east-2.compute.internal
Starting pod/ip-10-0-14-22us-east-2computeinternal-debug-j4r4r ...
To use host binaries, run `chroot /host`. Instead, if you need to access host namespaces, run `nsenter -a -t 1`.
Pod IP: 10.0.14.22
If you don\'t see a command prompt, try pressing enter. 
sh-5.1# chroot /host
sh-5.1# touch /usr/local/bin/mc-test
sh-5.1# ls -lah /usr/local/bin/mc-test
-rw-r--r--. 1 root root 0 Dec  1 04:31 /usr/local/bin/mc-test
sh-5.1# cd /etc/machine-config-daemon/
sh-5.1# mv currentconfig currentconfig.bak

debugセッションを維持したまま別画面でcurrentconfigを転送します。

[lab-user@bastion humanmco-test]$ oc get pod
NAME                                                 READY   STATUS    RESTARTS   AGE
ip-10-0-11-138us-east-2computeinternal-debug-sqs8h   1/1     Running   0          41s
[lab-user@bastion humanmco-test]$ oc cp ./new-currentconfig.txt ip-10-0-11-138us-east-2computeinternal-debug-sqs8h:/host/etc/machine-config-daemon/currentconfig -c container-00
[lab-user@bastion humanmco-test]$ oc debug node/ip-10-0-11-138.us-east-2.compute.internal -- chroot /host chown root:root /etc/machine-config-daemon/currentconfig
Starting pod/ip-10-0-11-138us-east-2computeinternal-debug-68shh ...
To use host binaries, run `chroot /host`. Instead, if you need to access host namespaces, run `nsenter -a -t 1`.

Removing debug pod ...

残り2台のノードも同様に実施します。

最後に、各ノードのannotationのcurrentConfigdesiredConfig、MachineConfigPoolの.spec.configuration.nameを新しいMachineConfigに変更しておきます。

[lab-user@bastion humanmco-test]$  oc get node --no-headers | grep worker | awk '{print $1}' | while read node; do oc annotate node ${node} --overwrite machineconfiguration.openshift.io/currentConfig=rendered-worker-b13c0797871dd0befef5e24d34172a31; oc annotate node ${node} --overwrite machineconfiguration.openshift.io/desiredConfig=rendered-worker-b13c0797871dd0befef5e24d34172a31; done
node/ip-10-0-14-22.us-east-2.compute.internal annotated
node/ip-10-0-14-22.us-east-2.compute.internal annotated
node/ip-10-0-40-69.us-east-2.compute.internal annotated
node/ip-10-0-40-69.us-east-2.compute.internal annotated
node/ip-10-0-61-98.us-east-2.compute.internal annotated
node/ip-10-0-61-98.us-east-2.compute.internal annotated
[lab-user@bastion humanmco-test]$ oc patch mcp worker  -p '{"spec":{"configuration":{"name":"rendered-worker-b13c0797871dd0befef5e24d34172a31"}}}' --type merge
machineconfigpool.machineconfiguration.openshift.io/worker patched

これで全ての変更は実施したはずです。

まだMCPの状態に変化は見えていません。

[lab-user@bastion humanmco-test]$ oc get node,mcp
NAME                                             STATUS   ROLES                  AGE     VERSION
node/ip-10-0-10-165.us-east-2.compute.internal   Ready    control-plane,master   4d21h   v1.33.5
node/ip-10-0-13-189.us-east-2.compute.internal   Ready    control-plane,master   4d21h   v1.33.5
node/ip-10-0-14-22.us-east-2.compute.internal    Ready    worker                 13h     v1.33.5
node/ip-10-0-40-69.us-east-2.compute.internal    Ready    worker                 13h     v1.33.5
node/ip-10-0-44-17.us-east-2.compute.internal    Ready    control-plane,master   4d21h   v1.33.5
node/ip-10-0-61-98.us-east-2.compute.internal    Ready    worker                 4d21h   v1.33.5

NAME                                                         CONFIG                                             UPDATED   UPDATING   DEGRADED   MACHINECOUNT   READYMACHINECOUNT   UPDATEDMACHINECOUNT   DEGRADEDMACHINECOUNT   AGE
machineconfigpool.machineconfiguration.openshift.io/master   rendered-master-d868db98f6b40ee2e6719f5226faab58   True      False      False      3              3                   3                     0                      4d21h
machineconfigpool.machineconfiguration.openshift.io/worker   rendered-worker-2bc1dfd10eba3b11a558e7b8edddd605   True      False      False      3              3                   3                     0                      4d21h

machine-config-controller/machine-config-server/machine-config-daemonに戻ってきてもらいましょう。

[lab-user@bastion humanmco-test]$ oc -n openshift-machine-config-operator patch daemonset machine-config-daemon --type json -p='[{"op": "remove", "path": "/spec/template/spec/nodeSelector/non-existing"}]'
[lab-user@bastion humanmco-test]$ oc -n openshift-machine-config-operator patch daemonset machine-config-server --type json -p='[{"op": "remove", "path": "/spec/template/spec/nodeSelector/non-existing"}]'
[lab-user@bastion humanmco-test]$ oc scale -n openshift-machine-config-operator deployment.apps/machine-config-controller --replicas=1
[lab-user@bastion humanmco-test]$  oc get pod -n openshift-machine-config-operator
NAME                                                             READY   STATUS      RESTARTS   AGE
kube-rbac-proxy-crio-ip-10-0-10-165.us-east-2.compute.internal   1/1     Running     9          4d21h
kube-rbac-proxy-crio-ip-10-0-13-189.us-east-2.compute.internal   1/1     Running     9          4d21h
kube-rbac-proxy-crio-ip-10-0-14-22.us-east-2.compute.internal    1/1     Running     7          13h
kube-rbac-proxy-crio-ip-10-0-40-69.us-east-2.compute.internal    1/1     Running     6          13h
kube-rbac-proxy-crio-ip-10-0-44-17.us-east-2.compute.internal    1/1     Running     9          4d21h
kube-rbac-proxy-crio-ip-10-0-61-98.us-east-2.compute.internal    1/1     Running     16         4d21h
machine-config-controller-587ff89599-ghht4                       2/2     Running     0          85s
machine-config-daemon-4dnsw                                      2/2     Running     0          108s
machine-config-daemon-5cwhm                                      2/2     Running     0          108s
machine-config-daemon-qwsjg                                      2/2     Running     0          108s
machine-config-daemon-rstzn                                      2/2     Running     0          108s
machine-config-daemon-ss4sk                                      2/2     Running     0          108s
machine-config-daemon-xcs5c                                      2/2     Running     0          108s
machine-config-nodes-crd-cleanup-29402346-4wgrx                  0/1     Completed   0          4d21h
machine-config-operator-5b66b667d4-mtmdm                         2/2     Running     12         4d21h
machine-config-server-8m4m2                                      1/1     Running     0          94s
machine-config-server-gps56                                      1/1     Running     0          94s
machine-config-server-kw46d                                      1/1     Running     0          94s

すると無事、rebootすることなくMachineConfigPoolのCONFIG列が新しいMachineConfigに切り替わりました。

[lab-user@bastion humanmco-test]$ oc get node,mcp
NAME                                             STATUS   ROLES                  AGE     VERSION
node/ip-10-0-10-165.us-east-2.compute.internal   Ready    control-plane,master   4d21h   v1.33.5
node/ip-10-0-13-189.us-east-2.compute.internal   Ready    control-plane,master   4d21h   v1.33.5
node/ip-10-0-14-22.us-east-2.compute.internal    Ready    worker                 13h     v1.33.5
node/ip-10-0-40-69.us-east-2.compute.internal    Ready    worker                 13h     v1.33.5
node/ip-10-0-44-17.us-east-2.compute.internal    Ready    control-plane,master   4d21h   v1.33.5
node/ip-10-0-61-98.us-east-2.compute.internal    Ready    worker                 4d21h   v1.33.5

NAME                                                         CONFIG                                             UPDATED   UPDATING   DEGRADED   MACHINECOUNT   READYMACHINECOUNT   UPDATEDMACHINECOUNT   DEGRADEDMACHINECOUNT   AGE
machineconfigpool.machineconfiguration.openshift.io/master   rendered-master-d868db98f6b40ee2e6719f5226faab58   True      False      False      3              3                   3                     0                      4d21h
machineconfigpool.machineconfiguration.openshift.io/worker   rendered-worker-b13c0797871dd0befef5e24d34172a31   True      False      False      3              3                   3                     0                      4d21h

machine-config-controllerのログにもUpdateが完了した旨が記録されています。

[lab-user@bastion humanmco-test]$ oc logs -n openshift-machine-config-operator machine-config-controller-587ff89599-ghht4 | grep rendered-worker-b13c0797871dd0befef5e24d34172a31
Defaulted container "machine-config-controller" out of: machine-config-controller, kube-rbac-proxy
I1201 04:36:55.732802       1 status.go:273] Pool worker: All nodes are updated with MachineConfig rendered-worker-b13c0797871dd0befef5e24d34172a31
I1201 04:36:55.744285       1 event.go:377] Event(v1.ObjectReference{Kind:"MachineConfigPool", Namespace:"openshift-machine-config-operator", Name:"worker", UID:"10f15d2b-342a-4406-8573-3306f397b211", APIVersion:"machineconfiguration.openshift.io/v1", ResourceVersion:"779354", FieldPath:""}): type: 'Normal' reason: 'Completed' Pool worker has completed update to MachineConfig rendered-worker-b13c0797871dd0befef5e24d34172a31
I1201 04:37:00.756062       1 status.go:273] Pool worker: All nodes are updated with MachineConfig rendered-worker-b13c0797871dd0befef5e24d34172a31

まとめ

ということで、今回はOpenShiftの根幹機能の一つであるMachineConfigOperatorがどのように設定を管理し、変更を投入していくのかを自分の手で確認してみました。
なお、手作業と言うからにはgoは使わずにbashだけで頑張るつもりだったんですが、ハッシュの計算だけはどう頑張ってもできませんでした…
コンテナだけでなくそれをホストするノードやクラスタ自身もこのような形でk8sの宣言的な設定を利用して自動的に管理してくれるのがOpenShiftのいいところの一つですね。

明日のOpenShift Advent Calendar 2025 三日目は@tawatanaさんの"1サーバでOpenShiftの構築検証をする(Virtもできるよ)"話です、お楽しみに!

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?