Red HatでOpenShiftのサポートをしているid:nekopです。OpenShift 全部俺 Advent Calendar 2018 - Qiitaの8日目のエントリです。昨日の以下のエントリの続きです。
OpenShiftのPrometheus Cluster Monitoringのドキュメントをさらっと読むと、以下の注意書きがあったり、Supported ConfigurationsのところにConfiguring OpenShift Container Platform cluster monitoringに書いてあるパラメータによる設定変更しかサポートしないよ、ということが書いてあります。
In order to be able to deliver updates with guaranteed compatibility, configurability of the OpenShift Container Platform Monitoring stack is limited to the explicitly available options.
openshift_cluster_monitoring_operator_alertmanager_config
というAlertManagerの設定以外はほぼPVの設定なので、ほとんど何も設定ができない、ということになります。ちょっとびっくりします。
変更するとどうなるのでしょうか。まずはStatefulSetを削除してみましょう。
$ oc get statefulset NAME DESIRED CURRENT AGE alertmanager-main 3 3 1h prometheus-k8s 2 2 1h $ oc delete statefulset --all statefulset.apps "alertmanager-main" deleted statefulset.apps "prometheus-k8s" deleted $ oc get statefulset NAME DESIRED CURRENT AGE alertmanager-main 3 1 3s prometheus-k8s 2 0 3s
一瞬で復活しました。
他にも変更をやってみましょう。たとえばPrometheusが2 pods, AlertManagerが3 podsでデフォルトHA構成なのですが、シングルノードでテストするときなどにこのpod数は必要ないので、変更してみましょう。
$ oc get statefulset NAME DESIRED CURRENT AGE alertmanager-main 3 3 1h prometheus-k8s 2 2 1h $ oc scale statefulset --all --replicas=1 statefulset.apps/alertmanager-main scaled statefulset.apps/prometheus-k8s scaled $ oc get statefulset NAME DESIRED CURRENT AGE alertmanager-main 3 3 1h prometheus-k8s 1 1 1h
AlertManagerは3 podsのまま、Prometheusは1 podsになりました。この差はなんでしょうか。Operatorをデバッグしてみましょう。prometheus-operatorのソースツリーをさらっと見るとdebugレベルでログがいろいろ出力されるようになっているようなので、オプション指定を調べます。
$ oc rsh deploy/prometheus-operator $ ps -eaf | cat UID PID PPID C STIME TTY TIME CMD 1000180+ 1 0 0 08:26 ? 00:00:00 /usr/bin/operator --kubelet-service=kube-system/kubelet --logtostderr=true --config-reloader-image=registry.redhat.io/openshift3/ose-configmap-reloader:v3.11.16 --prometheus-config-reloader=registry.redhat.io/openshift3/ose-prometheus-config-reloader:v3.11.16 --namespace=openshift-monitoring 1000180+ 10 0 0 08:32 ? 00:00:00 /bin/sh 1000180+ 25 10 0 08:33 ? 00:00:00 ps -eaf 1000180+ 26 10 0 08:33 ? 00:00:00 cat $ operator --help (省略) -log-level string Log level to use. Possible values: all, debug, info, warn, error, none (default "info")
-log-level=debug
を指定すれば良さそうです。deploy/prometheus-operator
のargsに指定します。
$ oc edit deploy/prometheus-operator
ログを見ると、StatefulSetの更新は認識しているが、更新する条件に当てはまっていない、というような出力があります。
level=debug ts=2018-12-10T08:24:21.944926624Z caller=operator.go:871 component=prometheusoperator msg="StatefulSet updated" level=debug ts=2018-12-10T08:24:22.034088665Z caller=operator.go:959 component=prometheusoperator msg="new statefulset generation inputs match current, skipping any actions"
ソースコードを見ると、prometheus-operator-input-hash
というannotationの値を比較しています。
https://github.com/coreos/prometheus-operator/blob/v0.26.0/pkg/prometheus/operator.go#L1030-L1034
$ oc get statefulset prometheus-k8s -o yaml | grep prometheus-operator-input-hash prometheus-operator-input-hash: "7438763470836378780"
処理がなんとなく意図的であるところまではわかりました。
追記: statefulset/prometheus-k8sはscaling対応していたので、正常な動作でした。
そんなこんなしているうちに、debugログを有効化していたdeploy/prometheus-operator
が再デプロイされました。これもOperatorによる自己修復でしょう。
PrometheusのStatefulSetの元となる情報はCRDのPrometheusというリソースに記述されています。こちらを変更すればStatefulSetも合わせて変更されるでしょうか。Prometheusリソースにreplicasが定義されていたので変更してみましょう。
$ oc scale statefulset prometheus-k8s --replicas=2 $ oc get statefulset NAME DESIRED CURRENT AGE alertmanager-main 3 3 6m prometheus-k8s 2 2 6m $ oc get prometheus k8s -o yaml replicas: 2 $ oc edit prometheus k8s # replicas: 1へ変更 $ oc get prometheus -o yaml | grep replica replicas: 1 $ oc delete statefulset prometheus-k8s statefulset.apps "prometheus-k8s" deleted $ oc get statefulset NAME DESIRED CURRENT AGE alertmanager-main 3 3 6m prometheus-k8s 1 0 5s
replicaが1になりました。
5分待ってもう一度実行するとどうでしょうか。
$ oc get prometheus -o yaml | grep replica replicas: 2 $ oc get statefulset NAME DESIRED CURRENT AGE alertmanager-main 3 3 10m prometheus-k8s 2 2 3m
インストール時のあるべき状態に自己修復されていました。
CRDを変更したのに元に戻ったということはさらに元となる定義がどこかにある、ということになります。
あまり長くなるのもアレなので答えを書きますが、以下のファイルが修復元の定義です。
このassetsファイルの中身はbindata.go
というコードに変換されていて、CMOはこの定義を利用しています。
というわけでOperatorでは意図しない変更は基本的にすべて自己修復される、という動作をすることがわかりました。