Azure のマネージド Kubernetes サービスである AKS には、Azure Monitor for Containers という監視機能があります。 ノードのパフォーマンス情報や Pod の標準出力ログ等を統合的に確認できるので非常に便利です。
今回はこの AKS と Azure Monitor for Containers がどのように連携しているかを見ていきます。
# ちなみに、ConfigMaps で一部設定をチューニングできますが今回の前提は既定値としています。
この記事に書いてあること
- Azure Monitor for Containers を有効にすると、DaemonSet と Deployment が展開される
- Pod のインベントリやノード情報等クラスタ全体の情報は Deployment が情報を取得
- Pod ごとの情報は DaemonSet が情報を取得
- Pod の標準出力は、DaemonSet がノードのログディレクトリをマウントして td-agent-bit で取得
そもそも Azure Monitor for Containers って?
Azure には、Azure Monitor というブランドでさまざまなリソースの監視が出来るような統合的な監視サービスが提供されています。
AKS に関してもこれで監視をすることになるのですが、特に AKS(コンテナ) 向けのものと位置づけられているのが、Azure Monitor for Containers です。
その開発コンセプトについては、US の開発チームの原田さんの記事が非常にわかりやすいのでぜひご参照ください。
qiita.com
こちらにも引用しておきます。
• Azureと言う広範囲な場所にAKSなどのサービス群を発見し、簡単に監視できること。
• 監視されていないAKSはあるのか?
• クラウドサービスの傍らに監視がないといけない。監視ツールを探す手間が面倒。
• 簡単に問題が発見でき、監視ツールを覚える必要のないユーザー体験(UX)が必要。
• 監視ツールの管理や監視をしなくても良く、手間いらずで、自動的にメンテナンスやアップグレードをしてくれる。つまり、監視ツールにでなく、自社のビジネス向上だけに人件費をかけることが出来る。
原田さんの記事にもありますが、 Azure Monitor for Containers を使うと、次のような情報が取得できます。
- API サーバーの正常性
- ノードごとの CPU 使用率、メモリ使用状況
- ノード数、Pod 数
- Deployment の Ready や Up to date、Available の情報
- コンテナの標準出力
さて、この監視機能の中身ですが、Log Analytics という Azure のエージェント型の SaaS 監視ソリューションが使われています。
Log Analytics と AKS の連携
この Log Analytics ですがどのようにコンテナの情報を集め、Azure Monitor for Containers にデータを送信しているのか、を調べてみます。
ノードに展開されているリソース
おもむろに kube-system に展開されているリソースを見てみると、こんなリソースがありました。
以下抜粋です。
$ k get all NAME READY STATUS RESTARTS AGE pod/omsagent-62kxc 1/1 Running 1 2d3h pod/omsagent-rs-66964c9f75-wn5hg 1/1 Running 1 2d3h NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE daemonset.apps/omsagent 5 5 5 5 5 beta.kubernetes.io/os=linux 4d18h NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/omsagent-rs 1/1 1 1 2d3h NAME DESIRED CURRENT READY AGE replicaset.apps/omsagent-rs-66964c9f75 1 1 1 2d3h
以前から Azure を使っていると、この oms というキーワードにピンときます。OMS というのは、Azure Monitor の前身の様なものです。
というところで、恐らくこの Deployment と DaemonSet が何かしてるんだろうというあたりがつきます。
omsagent-rs の役割
まず、Deployment の omsagent-rs のシェルでプロセスを見てみましょう。
# ps auxwwww USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 18508 3008 ? Ss 02:49 0:00 /bin/bash /opt/main.sh root 29 0.0 0.0 6704 120 ? S 02:49 0:00 inotifywait /etc/config/settings --daemon --recursive --outfile /opt/inotifyoutput.txt --event create,delete --format %e : %T --timefmt +%s syslog 225 0.0 0.0 129672 2776 ? Ssl 02:49 0:00 /usr/sbin/rsyslogd omsagent 266 0.8 0.8 396948 63648 ? Sl 02:49 2:02 /opt/microsoft/omsagent/ruby/bin/ruby /opt/microsoft/omsagent/bin/omsagent-6408bb34-6b60-4a40-b218-3ad8d671bd15 -d /var/opt/microsoft/omsagent/6408bb34-6b60-4a40-b218-3ad8d671bd15/run/omsagent.pid --no-supervisor -o /var/opt/microsoft/omsagent/6408bb34-6b60-4a40-b218-3ad8d671bd15/log/omsagent.log -c /etc/opt/microsoft/omsagent/6408bb34-6b60-4a40-b218-3ad8d671bd15/conf/omsagent.conf root 314 0.0 0.0 28356 2636 ? Ss 02:49 0:00 /usr/sbin/cron root 340 0.0 0.5 148080 42300 ? Sl 02:50 0:01 /opt/td-agent-bit/bin/td-agent-bit -c /etc/opt/microsoft/docker-cimprov/td-agent-bit-rs.conf -e /opt/td-agent-bit/bin/out_oms.so root 346 0.0 0.5 215480 39520 ? Sl 02:50 0:05 /opt/telegraf --config /etc/opt/microsoft/docker-cimprov/telegraf-rs.conf root 440 0.0 0.0 4536 764 ? S 02:50 0:00 sleep inf root 11637 0.0 0.0 18624 3548 pts/0 Ss 06:15 0:00 bash
そうすると、2つの td-agent が立ち上がっています。
/opt/microsoft/omsagent/ruby/bin/ruby /opt/microsoft/omsagent/bin/omsagent-6408bb34-6b60-4a40-b218-3ad8d671bd15 /opt/td-agent-bit/bin/td-agent-bit
※1 つ目のプロセスって td-agent なの?と思われるかもしれませんが、実は、Azure の Log Analytics のエージェントの実態は、td-agent だったりします。そしてプロセス名の後ろの GUID は、omsagent を識別するための ID になっています。
ちなみに、td-agent-bit では、CPU 使用率を stdout に吐いているだけの様なので割愛します。
td-agent の1つ目: omsagent-**
では、omsagent-** の設定を見てみます。設定は、/etc/opt/microsoft/omsagent/
とりあえず、source の type だけ見てみるとこんな感じでした。(これも Linux AKS に関係ありそうなものに絞ってます)
kubepodinventory kubeevents kubenodeinventory kubehealth
このキーワードどこかで見たことないでしょうか?
実はこちら、Log Analytics のログから確認できる、テーブルの名前と同じものがあります。
※上記4つのtype以外に存在するテーブルとして、KubeServices、ContainerNodeInventory、KubeMonAgentEvents がありますが、KubeServices に関しては、kubepodinventory と同じスクリプト、ContainerNodeInventoryに関しては kubenodeinventory で取得されています。KubeMonAgentEvents は出所が分かりませんでしたが、恐らく omsagent-rs から送信されているものと思われます。
さらに、これらのソースとなるものがどのように定義されているのかを見てみます。おもむろに、 /opt/microsoft/omsagent/plugin/* を grep してみます。
# egrep -Ir "kubepodinventory|kubeevents|kubenodeinventory|kubehealth" /opt/microsoft/omsagent/plugin/* | grep Plugin.reg /opt/microsoft/omsagent/plugin/in_kube_events.rb: Plugin.register_input("kubeevents", self) /opt/microsoft/omsagent/plugin/in_kube_health.rb: Plugin.register_input("kubehealth", self) /opt/microsoft/omsagent/plugin/in_kube_nodes.rb: Plugin.register_input("kubenodeinventory", self) /opt/microsoft/omsagent/plugin/in_kube_podinventory.rb: Plugin.register_input("kubepodinventory", self)
この中の一つ、in_kube_podinventory.rb を見てみましょう。
# Initializing continuation token to nil continuationToken = nil $log.info("in_kube_podinventory::enumerate : Getting pods from Kube API @ #{Time.now.utc.iso8601}") continuationToken, podInventory = KubernetesApiClient.getResourcesAndContinuationToken("pods?limit=#{@PODS_CHUNK_SIZE}") $log.info("in_kube_podinventory::enumerate : Done getting pods from Kube API @ #{Time.now.utc.iso8601}")
雰囲気ですがなんとなくこの in_kube_podinventory.rb の中で Pod 周りの情報を取得している、ということが分かりました。
最後に、もう一度設定ファイルに戻って、これらのログをどこに送っているか見てみましょう。
<match oms.containerinsights.KubeNodeInventory**> type out_oms log_level debug num_threads 5 buffer_chunk_limit 4m buffer_type file buffer_path /var/opt/microsoft/omsagent/6408bb34-6b60-4a40-b218-3ad8d671bd15/state/state/out_oms_kubenodes*.buffer buffer_queue_limit 20 buffer_queue_full_action drop_oldest_chunk flush_interval 20s retry_limit 10 retry_wait 5s max_retry_wait 5m </match>
大体想像がつきますが、out_oms プラグインを使って Log Analytics にデータを送り付けていそうですね。
プラグインの実態はこちら。
/opt/microsoft/omsagent/plugin/out_oms.rb
プラグインから参照している設定ファイルはこちら。なんかそれっぽい設定がありますね。
root@omsagent-rs-66964c9f75-wn5hg:/etc/opt/microsoft/omsagent/conf/omsagent.d# cat /etc/opt/microsoft/omsagent/conf/omsadmin.conf WORKSPACE_ID=6408bb34-6b60-4a40-b218-3ad8d671bd15 AGENT_GUID=e5fe9077-2ee1-4483-87ca-be35a694bd2e LOG_FACILITY=local0 CERTIFICATE_UPDATE_ENDPOINT=https://6408bb34-6b60-4a40-b218-3ad8d671bd15.oms.opinsights.azure.com/ConfigurationService.Svc/RenewCertificate URL_TLD=opinsights.azure.com DSC_ENDPOINT=https://6408bb34-6b60-4a40-b218-3ad8d671bd15.agentsvc.azure-automation.net/Accounts/6408bb34-6b60-4a40-b218-3ad8d671bd15/Nodes\(AgentId='e5fe9077-2ee1-4483-87ca-be35a694bd2e'\) OMS_ENDPOINT=https://6408bb34-6b60-4a40-b218-3ad8d671bd15.ods.opinsights.azure.com/OperationalData.svc/PostJsonDataItems AZURE_RESOURCE_ID= OMSCLOUD_ID=7783-7084-3265-9085-8269-3286-77 UUID=0255E095-271E-9F4A-A4A1-D1C3EDC4B0AF root@omsagent-rs-66964c9f75-wn5hg:/etc/opt/microsoft/omsagent/conf/omsagent.d# fg view /opt/microsoft/omsagent/plugin/out_oms.rb
ひとまずここまで omsagent-rs が何をやっているか、ということをまとめると、Pod や ノードのインベントリー、イベント、正常性を取得して、Log Analytics へ送信していることが分かりました。
omsagent の役割
では続いて同じようなステップで DaemonSet である omsagent を見てみましょう。同じように ps してみます。
# ps auxwwww USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 18504 3140 ? Ss 02:49 0:00 /bin/bash /opt/main.sh root 29 0.0 0.0 6704 124 ? S 02:49 0:00 inotifywait /etc/config/settings --daemon --recursive --outfile /opt/inotifyoutput.txt --event create,delete --format %e : %T --timefmt +%s syslog 227 0.0 0.0 129672 3124 ? Ssl 02:50 0:00 /usr/sbin/rsyslogd omsagent 268 0.4 0.6 317832 46796 ? Sl 02:50 1:43 /opt/microsoft/omsagent/ruby/bin/ruby /opt/microsoft/omsagent/bin/omsagent-6408bb34-6b60-4a40-b218-3ad8d671bd15 -d /var/opt/microsoft/omsagent/6408bb34-6b60-4a40-b218-3ad8d671bd15/run/omsagent.pid --no-supervisor -o /var/opt/microsoft/omsagent/6408bb34-6b60-4a40-b218-3ad8d671bd15/log/omsagent.log -c /etc/opt/microsoft/omsagent/6408bb34-6b60-4a40-b218-3ad8d671bd15/conf/omsagent.conf root 297 0.0 0.0 28356 2632 ? Ss 02:50 0:00 /usr/sbin/cron root 339 0.0 0.6 160440 49044 ? Sl 02:50 0:03 /opt/td-agent-bit/bin/td-agent-bit -c /etc/opt/microsoft/docker-cimprov/td-agent-bit.conf -e /opt/td-agent-bit/bin/out_oms.so root 361 0.0 0.6 203316 48108 ? Sl 02:50 0:12 /opt/telegraf --config /etc/opt/microsoft/docker-cimprov/telegraf.conf root 409 0.0 0.0 4536 784 ? S 02:50 0:00 sleep inf root 15617 0.0 0.0 18624 3448 pts/0 Ss 04:54 0:00 bash root 46957 0.0 0.0 34408 2800 pts/0 R+ 09:05 0:00 ps auxwwww
こちらでも、2つの td-agent が動いてますね。
/opt/microsoft/omsagent/ruby/bin/ruby /opt/microsoft/omsagent/bin/omsagent-6408bb34-6b60-4a40-b218-3ad8d671bd15 /opt/td-agent-bit/bin/td-agent-bit
td-agent の1つ目: omsagent-**
設定ファイルのパスは同じなので、source の type から見ていきます。
containerinventory cadvisorperf
Deployment の omsagent-rs と違ってますね。
これも名前から大体想像がつきますが、コンテナのインベントリと、cAdvisor によるパフォーマンスを取得しているようです。
先ほどと同じように、Log Analytics のテーブルと照らし合わせてみます。
まず、containerinventory はそのまま、td-agent の source です。
次に、cadvisorperf がどこに行ってしまったかというと、LogManagement の Perf テーブルに送信されているようです。これは、プラグインの in_cadvisor_perf.rb を見てみると、以下の様なコードがありました。
record["DataType"] = "LINUX_PERF_BLOB" record["IPName"] = "LogManagement" eventStream.add(time, record) if record
恐らくですが、LINUX_PERF_BLOB というのはコンテナに関係なく、Linux のパフォーマンス情報を格納するための LogManagement 配下の Perf のことを指していると思われます。このテーブルは、Windows / Linux 共通で、Log Analytics から取得されてきたパフォーマンス情報を格納するテーブルになるので、同じ仕組みを AKS のコンテナに対しても使っているようです。
そして実はこの Perf テーブルですが、omsagent-rs から、ノードレベルの情報を取得しているようです。そういう意味で、色を紫にしています。
また、InsightsMetrics も同様にコンテナ個々の情報、ノード情報をそれぞれ omsaget、omsagent-rs から情報を取得しているようです。
次に、ContainerImageInventory は、filter_container.rb というフィルタープラグインの中で識別されていました。
dataType = case r["ClassName"] when "Container_ImageInventory" then "CONTAINER_IMAGE_INVENTORY_BLOB" when "Container_ContainerInventory" then "CONTAINER_INVENTORY_BLOB" when "Container_DaemonEvent" then "CONTAINER_SERVICE_LOG_BLOB" when "Container_ContainerLog" then "CONTAINER_LOG_BLOB" end
一旦ここまででまとめると、DaemonSet で展開されている omsagent は、ノード上にあるコンテナ特有の情報を取得して、Log Analytics へ送信していることが分かりました。
コンテナの標準出力は?
さて、ここで、Azure Monitor for Containers では、コンテナの標準出力も収集されると最初に書きました。
それはどのように収集されてるのでしょうか?
答えは、この DaemonSet の omsagent の td-agent-bit です。設定ファイルを見てみましょう。
# cat /etc/opt/microsoft/docker-cimprov/td-agent-bit.conf [INPUT] Name tail Tag oms.container.log.la.* Path ${AZMON_LOG_TAIL_PATH} # env | grep AZMON_LOG_TAIL_PATH AZMON_LOG_TAIL_PATH=/var/log/containers/*.log
td-agent-bit の INPUT を見ると、AZMON_LOG_TAIL_PATH にあるファイルを tail しているようです。そして、/var/log は、ノードのディレクトリをマウントしていることで、各ノードのコンテナの標準出力をキャッチできる、というわけです。
volumeMounts: - mountPath: /var/log name: host-log volumes: - hostPath: path: /var/log type: "" name: host-log
まとめ
今回は Log Analytics に関する Pod がどのような動きをしているのかをざっと調べてみました。
今回かいていない内容として、それぞれのプラグインの処理の詳細、omsagent の ConfigMaps によるカスタマイズの方法、telegraf によるメトリクスの取得など、Deep Dive するとどこまでも行けそうなので引き続き Azure Monitor for Container ネタを書いていきたいと思います。