kubernetesでのモニタリングはprometheusが定番と思いますが、grafana等を自前で用意する必要がある為、運用負荷となると思います。このあたりを楽したいので私はmackerelを利用しています。
k8s環境で各ノードのメトリクスをmackerelに集約するためには、mackerel-agentをDaemonSetで起動しました。DaemonSetで起動するまでは良かったのですが、ホスト名の自由がなく、使いづらかったので共有したいと思います。
ホスト名がDaemonSetのnameに連動する
DaemonSetでmackerel-agentをdeployするk8s manifestを単純に作成すると、以下のようになります。
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: mackerel-agent
namespace: kube-system
labels:
app: mackerel-agent
spec:
tolerations: # masterにもmackerel-agentをdeployする設定
- operator: Exists
effect: NoSchedule
- operator: Exists
effect: NoExecute
- operator: Exists
selector:
matchLabels:
name: mackerel-agent
template:
metadata:
labels:
name: mackerel-agent
spec:
containers:
- name: mackerel-agent
image: mackerel/mackerel-agent:latest
...
このmanifestでDaemonSetを起動して、podを確認します。
$ kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
mackerel-agent-jqp9n 1/1 Running 0 5s
mackerel-agent-kqf7d 1/1 Running 0 5s
mackerel-agent-xcqdc 1/1 Running 0 5s
...
上記の通り、pod名は、DaemonSetのnameをprefixとした mackerel-agent-*
という名前になっていると思います。
そしてこのとき、mackerelでHostsを確認すると、HOST NAMEにpod名が付与されていることが確認できます。
これでは、どのホストのことなのかサッパリで、運用する上で不便だと思います。
ただ、ホスト名を設定するために、DaemonSetのメタデータであるnameを変えるのはちょっと。。
hostnameをつける
manifestでhostnameをつけることができます。
...
spec:
tolerations: # masterにもmackerel-agentをdeployする設定
- operator: Exists
effect: NoSchedule
- operator: Exists
effect: NoExecute
- operator: Exists
selector:
matchLabels:
name: mackerel-agent
template:
metadata:
labels:
name: mackerel-agent
spec:
hostname: hogehoge # **ホスト名をつける**
containers:
- name: mackerel-agent
image: mackerel/mackerel-agent:latest
...
このときpod名の命名規則は変更ありません。
$ kubectl -n kube-system get pods
NAME READY STATUS RESTARTS AGE
mackerel-agent-5pmv5 1/1 Running 0 8s
mackerel-agent-hwgn6 1/1 Running 0 8s
mackerel-agent-shcnv 1/1 Running 0 8s
hostnameを与えた場合でmackerelをみると、ホスト名が設定されています。
hostnameを使えば任意のホスト名を付与できました。
テンプレート化する
hostnameを使えば、任意のホスト名を付与できることが分かったのですが、stagingやproductionといった異なる環境で、mackerelのservice/roleを使いまわす場合に hogehoge-production
, hogehoge-staging
みたいなホスト名にしたいです。
このため、helmを使ってテンプレート化し、パラメータとして与えるようにします。
(このためだけにhelmを使うのがなんとなく嫌ですが、manifestでは変数をかけないので。。)
...
hostname: hogehoge-{{ .Values.env }}
...
helm template
でmanifestを作成
$ helm template --set env=staging mackerel-agent > mackerel-agent.yaml
出力されたmanifestでは hostname: hogehoge-staging
となっています。
更にやりたいこと
ホスト名をもっと色々表示してほしいので整理します。
- service名をprefixとしてつけたい(できた)
- hogehoge-*
- 環境名(production/staging)をホスト名に含めたい (できた)
- 環境間はservice/roleを共有したい
- masterかnodeかをホスト名に含めたい (できてない)
- kubernetesのロールをホスト名で見分けたい
- pod毎のsuffixをつけてほしい (できてない)
- どのnodeなのかをホスト名に付与したい
1~4を総合すると、 hogehoge-production-master-<node名>
みたいなホスト名にしたいです。
今回できてない3・4は、deploy時に確定する情報なので、manifestやhelmで頑張るのは厳しそうです。
こうなってくると、deploy後にホスト名を設定するように変更して、mkrするscriptを書くしかないかもしれません。
mackerelへの期待
mackerelとkubectlで得られる情報を付き合わせるの運用はやめたいです。mackerel-agentからkube-apiserver叩いて勝手にノードの情報とってきてくれないかな?(あとslack通知にもその情報出したい)