OpenShiftの『よくわからないPod』を調べる

Red Hatの織です。「RHELの『よくわからないサービス』を調べる」にインスパイアされて、OpenShift版を書いてみました。

OpenShiftをインストールすると、構築直後からたくさんのPodが動いています。 手元の構築直後のOpenShiftクラスター(AWS上のv4.11)を見てみると、Namespaceが67個あり、その中でPodが200個動いていました (ノード数によって多少変わります、DaemonSet等がいるので)。

$ oc get ns --no-headers | wc -l
67
$ oc get pod -A --no-headers | grep Running | wc -l
200

名前を見ただけで何をするPodかだいたいわかるものもあれば、何をしているのかよくわからないPodもいます。本記事では、こういった、OpenShiftにおける『よくわからないPod (もしくはコンテナ)』を調べる方法をまとめました。

公式ドキュメントで探す

Podや、関連するワークロードリソース (Deployment、DaemonSet等) の名前でドキュメントを検索すると、情報が載っている場合があります。 Red Hat製品としてのOpenShiftのドキュメントは access.redhat.com もしくは docs.openshift.com にあります。

前者のURLには、日本語版もありますのでご活用ください。 後者のURLは英語版のみですが、複数のドキュメントにわたって串刺し検索ができます。

英語版のドキュメントは、ソースをGitHubで公開しています。手元でgrepしたい人は、git cloneしておくとよいかもしれません。 github.com 検索する際は、適切なブランチをチェックアウトするようにしてください (例えばv4.11の場合は enterprise-4.11 というブランチになります)。

Enhancementsドキュメントがあるか探す

OpenShiftの機能拡張の多くは、https://github.com/openshift/enhancements にドキュメントがあります。 KEPと同じ形式でデザインドキュメントが書かれており、Motivation, Goals, Non-Goals等がまとまっています。 「Podが何をしているか」という観点だと、記載の粒度が細かすぎるかもしれませんが、参考になる場合も多いです。

例えば openshift-ingress-canary というnamespaceで稼動する ingress-canary というPodについて、Enhancementsに情報がないか調べてみましょう。

$ grep -l -ri 'ingress[- ]canary' enhancements/
enhancements/ingress/ingress-fault-detection.md
enhancements/network/dpu/smart-nic-ovn-offload.md

検索結果から、https://github.com/openshift/enhancements/blob/master/enhancements/ingress/ingress-fault-detection.md を見てみると、参考になる情報が載っていることがわかります。

具体的には、ingress-operatorからcanary Podに対して定期的にRouter経由でアクセスすることで、Routeの稼動確認を行っていることがわかりました。

コンテナで稼動するコマンドのヘルプを見る

ソースコードを見るのはちょっと...というときは、コンテナ内で動くプロセスを見て、そのコマンドに --help をつけて実行してみると、何をするPodかがわかる場合があります。 例えば、openshift-network-diagnostics というnamespaceには network-check-source というPodがひとつと network-check-target というPodがノード数分動いています。

$ oc -n openshift-network-diagnostics get pod
NAME                                    READY   STATUS    RESTARTS   AGE
network-check-source-57b4967df6-w6gft   1/1     Running   0          17d
network-check-target-7flvl              1/1     Running   0          17d
network-check-target-8sh2v              1/1     Running   0          17d
network-check-target-kgjzl              1/1     Running   0          17d
network-check-target-psjdg              1/1     Running   0          17d
network-check-target-sclmm              1/1     Running   0          17d
network-check-target-zxrgm              1/1     Running   0          17d

network-check-source に入って、動いているコマンドに --help をつけて実行してみます。

$ oc -n openshift-network-diagnostics exec network-check-source-57b4967df6-w6gft -- ps ax
    PID TTY      STAT   TIME COMMAND
      1 ?        Ssl   65:29 cluster-network-check-endpoints --listen 0.0.0.0:17698 --namespace openshift-network-diagnostics
     59 ?        Rs     0:00 ps ax
$ oc -n openshift-network-diagnostics exec network-check-source-57b4967df6-w6gft -- cluster-network-check-endpoints --help
Checks that a tcp connection can be opened to one or more endpoints.

Usage:
  check-endpoints [flags]

Flags:
      --config string                    Location of the master configuration file to run from.
  -h, --help                             help for check-endpoints
      --kubeconfig string                Location of the master configuration file to run from.
      --listen string                    The ip:port to serve on.
      --namespace string                 Namespace where the controller is running. Auto-detected if run in cluster.
      --terminate-on-files stringArray   A list of files. If one of them changes, the process will terminate.

ヘルプメッセージから、複数のエンドポイントに対してTCPのコネクションが張れるかをチェックするPodだとわかります。

ソースコードのREADMEを見る

GitHubのおかげで、ソースコードリポジトリのトップディレクトリに置かれたREADME.mdには、そのリポジトリに関する情報がまとまっていることが多いです。

問題は、「対象となるPodのソースコードがどこにあるか」をどうやって知るかですが、実はOpenShiftのPodは、ほとんどの場合 SOURCE_GIT_URL という環境変数にソースコードのGitリポジトリのURLが設定されています。

また追加の豆知識として、コンテナイメージの /root/buildinfo には、そのコンテナイメージのビルドに使用したDockerfileが置かれています。 先ほどの環境変数 SOURCE_GIT_URL もDockerfileの中で設定されています。コンテナのエントリーポイントの周辺情報も含めて調査する場合は、Dockerfileを見るのもよいでしょう。

Cluster Version Operatorの場合

例として、openshift-cluster-version Namespaceの cluster-version-operator PodのGitリポジトリを調べてみましょう。まず、該当NamespaceのPodを確認します。

$ oc -n openshift-cluster-version get pod
NAME                                        READY   STATUS    RESTARTS   AGE
cluster-version-operator-678f49cffd-4rxpl   1/1     Running   0          17d

次に、該当Operatorの /root/buildinfo を見ます。Pod内に複数のコンテナが動いている場合は、目的のコンテナ名を -c オプションで指定してください。

$ oc -n openshift-cluster-version exec cluster-version-operator-678f49cffd-4rxpl -- ls -F /root/buildinfo
Dockerfile-openshift-base-rhel8-v4.11.0-202209130958.p0.gf020942.assembly.stream
Dockerfile-openshift-ose-base-v4.11.0-202209130958.p0.gf1330f6.assembly.stream
Dockerfile-openshift-ose-cluster-version-operator-v4.11.0-202209130958.p0.gbd8aa51.assembly.stream
Dockerfile-ubi8-8.6-754
content_manifests/

いくつかのDockerfileがあることがわかります。通常コンテナイメージはレイヤー化されていますが、今回の調査目的からすると、一番上の層の該当アプリが入っていると思われるDockerfileを見たいです。ほとんどの場合、どれが一番上の層のDockerfileかは、ファイル名を見るとだいたいわかると思います。

今回の場合は、Dockerfile-openshift-ose-cluster-version-operator-v4.11.0-202209130958.p0.gbd8aa51.assembly.stream が該当します。

$ oc -n openshift-cluster-version exec cluster-version-operator-678f49cffd-4rxpl -- cat /root/buildinfo/Dockerfile-openshift-ose-cluster-version-operator-v4.11.0-202209130958.p0.gbd8aa51.assembly.stream | grep SOURCE_GIT_URL | head -n 1
ENV __doozer=merge OS_GIT_COMMIT=bd8aa51 OS_GIT_VERSION=4.11.0-202209130958.p0.gbd8aa51.assembly.stream-bd8aa51 SOURCE_DATE_EPOCH=1661361071 SOURCE_GIT_COMMIT=bd8aa51be5d4e5cc92462cd066742291ac86786b SOURCE_GIT_TAG=v1.0.0-850-gbd8aa51b SOURCE_GIT_URL=https://github.com/openshift/cluster-version-operator 

環境変数からも確認してみます。

$ oc -n openshift-cluster-version exec cluster-version-operator-678f49cffd-4rxpl -- bash -c 'echo $SOURCE_GIT_URL'
https://github.com/openshift/cluster-version-operator

cluster-version-operatorのGitリポジトリは https://github.com/openshift/cluster-version-operator であることがわかりました。

上記URLを開くと、トップディレクトリのREADME.mdには残念ながらあまり情報は載っていませんでしたが、トップディレクトリ直下に docs というディレクトリがあり、ここにも情報がありそうです。ちょっとたどると結局Enhancementsに飛ばされてこの辺りを読むとcluster-version-operatorの動きがわかってきます。

Node Tuning Operatorの場合

もうひとつの例として、openshift-cluster-node-tuning-operator Namespaceの cluster-node-tuning-operator Podを調べてみます。まず、Dockerfileを確認します。

$ oc -n openshift-cluster-node-tuning-operator exec cluster-node-tuning-operator-7cb5cd8666-9755h -- ls /root/buildinfo
ls: cannot access '/root/buildinfo': Permission denied
command terminated with exit code 2

Permission denied で怒られてしまいました。実はこのOperatorは、Security Contextとして runAsNonRoot: true が設定されており、root以外のユーザーで起動するため、/root/buildinfo を見ることができません。

$ oc -n openshift-cluster-node-tuning-operator get pod cluster-node-tuning-operator-7cb5cd8666-9755h -o json | jq .spec.securityContext
{
  "runAsNonRoot": true,
  "runAsUser": 499,
  "seLinuxOptions": {
    "level": "s0:c14,c4"
  }
}

このような場合は、oc debug pod --as-root=1 コマンドを使って、rootユーザーでコンテナに入ります。

$ oc -n openshift-cluster-node-tuning-operator debug pod/cluster-node-tuning-operator-7cb5cd8666-9755h --as-root=1 -- ls -F /root/buildinfo 2> /dev/null
Dockerfile-openshift-base-rhel8-v4.11.0-202209130958.p0.gf020942.assembly.stream
Dockerfile-openshift-ose-base-v4.11.0-202209130958.p0.gf1330f6.assembly.stream
Dockerfile-openshift-ose-cluster-node-tuning-operator-v4.11.0-202209131448.p0.g8b73bd5.assembly.stream
Dockerfile-ubi8-8.6-754
content_manifests/

Dockerfileが確認できたので、中を見てみましょう。

$ oc -n openshift-cluster-node-tuning-operator debug pod/cluster-node-tuning-operator-7cb5cd8666-9755h --as-root=1 -- cat /root/buildinfo/Dockerfile-openshift-ose-cluster-node-tuning-operator-v4.11.0-202209131448.p0.g8b73bd5.assembly.stream 2> /dev/null | grep SOURCE_GIT_URL | head -n 1
ENV __doozer=merge OS_GIT_COMMIT=8b73bd5 OS_GIT_VERSION=4.11.0-202209131448.p0.g8b73bd5.assembly.stream-8b73bd5 SOURCE_DATE_EPOCH=1663062448 SOURCE_GIT_COMMIT=8b73bd580a780daa44fabc1986e9ff4ed0bce33f SOURCE_GIT_TAG=8b73bd58 SOURCE_GIT_URL=https://github.com/openshift/cluster-node-tuning-operator 

ソースコードのリポジトリが https://github.com/openshift/cluster-node-tuning-operator であることがわかりました。今回はトップディレクトリのREADME.mdに有用な情報が載っており、cluster-node-tuning-operatorはカスタムリソースTunedを経由して、各ノードのtunedの設定を宣言的に管理するためのOperatorであることがわかりました。

最後に

v4.11のPodについて、スプレッドシートに情報をまとめてみました。

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