前回、前々回でkube-prometheusの導入方法についてご紹介しました。
今回はカスタマイズです。
目次
設定とカスタマイズ
設定とカスタマイズについては以下に記載されていますが、たくさん項目があって英語でわかりにくいということもあると思うので、かいつまんで説明します。
オーケストレーションツールごとの設定
使用するオーケストレーションによってKubernetesクラスタの中身は微妙に違います。どのオーケストレーションツールを使っているかを設定することで、それぞれのツールに合わせてカスタマイズが行われるようですね。
Jsonnet設定ファイル(ここではbase.libsonnet)の冒頭部分を修正します。
kubeadmだとこうなります。
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + (import 'kube-prometheus/kube-prometheus-kubeadm.libsonnet') + // ここ (snip) {
EKSだとこうなるみたいです。
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + (import 'kube-prometheus/kube-prometheus-eks.libsonnet') + // ここ (snip) {
nodeport有効化
普通にやるとprometheus/alertmanager/grafanaのGUIはすべてClusterIPになり、公開するには、serviceを変更するなり、nginx-ingressを使うなりして、自分で設定しないといけません。これをnodeportにするaddonがあります。
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + (import 'kube-prometheus/kube-prometheus-kubeadm.libsonnet') + (import 'kube-prometheus/addons/node-ports.libsonnet') + // ここ (snip) {
ingressで公開する
ingressを使って公開することもできます。まず最初にnginx-ingressを入れておきます。ローカル環境なのでnodeportに変更しておきます。ついでに30080ポートに固定します。
$ kubectl create ns monitoring $ helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx $ helm install default ingress-nginx/ingress-nginx -n monitoring $ kubectl -n monitoring patch service default-ingress-nginx-controller -p '{"spec":{"type": "NodePort"}}' $ kubectl -n monitoring patch service default-ingress-nginx-controller --type='json' -p='[{"op": "replace", "path": "/spec/ports/0/nodePort", "value": 30080}]'
確認。404にはなっていますが一応応答していますね。
$ kubectl get service -n monitoring NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE default-ingress-nginx-controller NodePort 10.108.194.110 <none> 80:30080/TCP,443:30030/TCP 19s default-ingress-nginx-controller-admission ClusterIP 10.110.178.130 <none> 443/TCP 19s $ curl http://10.240.0.21:30080 <html> <head><title>404 Not Found</title></head> <body> <center><h1>404 Not Found</h1></center> <hr><center>nginx</center> </body> </html>
base.libsonnetの_config以下を修正します。以下の例はv1.18向けなので、apiVersion
は 'networking.k8s.io/v1beta1' にしていますし、backendの指定もそれに合わせてます。v1.20でも同じ書き方で行けましたが、このあたりはバージョンによって修正が必要な場合もありますね。
(snip) { _config+:: { namespace: 'monitoring', }, // 以下を追加 prometheus+:: { prometheus+: { spec+: { externalUrl: 'http://prometheus.internal', }, }, }, ingress+:: { 'prometheus-k8s': { apiVersion: 'networking.k8s.io/v1beta1', kind: 'Ingress', metadata: { name: $.prometheus.prometheus.metadata.name, namespace: $.prometheus.prometheus.metadata.namespace, annotations: { 'kubernetes.io/ingress.class': 'nginx', }, }, spec: { rules: [{ host: 'prometheus.internal', http: { paths: [{ backend: { serviceName: $.prometheus.service.metadata.name, servicePort: 'web', }, }], }, }], }, }, }, }; (snip)
あと一番最後の行を修正します。
(snip) { ['prometheus-adapter-' + name]: kp.prometheusAdapter[name] for name in std.objectFields(kp.prometheusAdapter) } + { ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) } + // "+"を追記 { ['ingress-' + name]: kp.ingress[name] for name in std.objectFields(kp.ingress) } // 追加
ビルドしてapplyするとこうなります。
$ kubectl -n monitoring get ingress NAME CLASS HOSTS ADDRESS PORTS AGE k8s <none> prometheus.internal 10.103.124.145 80 9m18s $ curl http://10.240.0.31:30080/ <html> <head><title>404 Not Found</title></head> <body> <center><h1>404 Not Found</h1></center> <hr><center>nginx</center> </body> </html> $ curl -H 'host: prometheus.internal' http://10.240.0.31:30080/ <a href="/graph">Found</a>.
hostヘッダを付けないとアクセスできないということで、ちゃんとingressが応答しているのがわかります。
同様にして、alertmanagerとgrafanaもingressで公開します。同じような記載を追加すればいいだけですが、以下を参考に少し弄ってみます。
- https://github.com/prometheus-operator/kube-prometheus/blob/master/docs/exposing-prometheus-alertmanager-grafana-ingress.md
- https://github.com/prometheus-operator/kube-prometheus/blob/master/examples/ingress.jsonnet
{ _config+:: { namespace: 'monitoring', grafana+:: { config+: { sections+: { server+: { root_url: 'http://grafana.internal/', }, }, }, }, }, prometheus+:: { prometheus+: { spec+: { externalUrl: 'http://prometheus.internal', }, }, }, alertmanager+:: { alertmanager+: { spec+: { externalUrl: 'http://alertmanager.internal', }, }, }, ingress+:: { 'prometheus-k8s': { apiVersion: 'networking.k8s.io/v1beta1', kind: 'Ingress', metadata: { name: $.prometheus.prometheus.metadata.name, namespace: $.prometheus.prometheus.metadata.namespace, annotations: { 'kubernetes.io/ingress.class': 'nginx', }, }, spec: { rules: [{ host: 'prometheus.internal', http: { paths: [{ backend: { serviceName: $.prometheus.service.metadata.name, servicePort: 'web', }, }], }, }], }, }, 'alertmanager-main': { apiVersion: 'networking.k8s.io/v1beta1', kind: 'Ingress', metadata: { name: $.alertmanager.alertmanager.metadata.name, namespace: $.alertmanager.alertmanager.metadata.namespace, annotations: { 'kubernetes.io/ingress.class': 'nginx', }, }, spec: { rules: [{ host: 'alertmanager.internal', http: { paths: [{ backend: { serviceName: $.alertmanager.service.metadata.name, servicePort: 'web', }, }], }, }], }, }, 'grafana': { apiVersion: 'networking.k8s.io/v1beta1', kind: 'Ingress', metadata: { name: 'grafana', namespace: 'monitoring', annotations: { 'kubernetes.io/ingress.class': 'nginx', }, }, spec: { rules: [{ host: 'grafana.internal', http: { paths: [{ backend: { serviceName: 'grafana', servicePort: 'http', }, }], }, }], }, }, }, };
多少冗長になっていますが、わかりやすさ優先で。alertmanagerはprometheusとほぼ同じです。クセがあるのがgrafanaで、設定を_config配下にしないといけないみたいです。で、その関係上、ingressの設定のところ、うまく変数的に指定できなかったのでとりあえず動くこと優先でハードコードしてます・・・
適用するとこんな感じです。
$ kubectl -n monitoring get ingress NAME CLASS HOSTS ADDRESS PORTS AGE grafana <none> grafana.internal 10.108.82.19 80 4m16s k8s <none> prometheus.internal 10.108.82.19 80 4m16s main <none> alertmanager.internal 10.108.82.19 80 4m16s $ curl -H 'host: prometheus.internal' http://10.240.0.31:30080/ <a href="/graph">Found</a>. $ curl -H 'host: grafana.internal' http://10.240.0.31:30080/ <a href="/login">Found</a>. $ curl -H 'host: alertmanager.internal' http://10.240.0.31:30080/ <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <title>Alertmanager</title> (snip)
OKですね。
まとめ
kube-prometheus、難しい・・・。Jsonnetもよくわかってないのですが、REPL的なものはないのかなぁ・・・
まだもう少し追いかけます。