はじめに
インフラストラクチャーグループの @mom0tomo です。普段はマッハバイトのクラウド移行に取り組んだり、コーポレートサイトのCSS/JSと格闘したりしています。最近、少しずつ転職会議のKubernetes運用にも関わるようになりました。
転職会議では、KubernetesクラスターへのCI/CDツールとしてArgoCDを利用しています。
ArgoCDにはGUIがあるためアプリケーション開発者も親しみやすいなど利点が多いのですが、デフォルトで出力されるログが多く、必要以上にログデータを生成してしまうと言う問題がありました。とくにDatadogのようなログ分析ツールを使っている場合は、多すぎるログはコストが嵩む要因になります。
本記事では、ArgoCDのログ量の問題に直面した背景と、ログ量を削減する方法について紹介します。
ArgoCDを構成するコンポーネントについて
ArgoCD は、Kubernetes クラスタ内のアプリケーションを管理するために使用されるツールであり、以下のコンポーネント群で構成されています。
$ kubectl argocd get pods NAME READY STATUS RESTARTS AGE argocd-application-controller-0 1/1 Running 0 12d argocd-applicationset-controller-6c55c7554-d7mcj 1/1 Running 0 11d argocd-dex-server-6c65ff6b54-v2mhn 1/1 Running 0 12d argocd-image-updater-74ccf74659-pgcsh 1/1 Running 0 16s argocd-notifications-controller-68946488f8-lq6nn 1/1 Running 0 11d argocd-redis-598df7976-kv8j7 1/1 Running 0 11d argocd-repo-server-d8dfbffd4-4k9lb 1/1 Running 0 12d argocd-repo-server-d8dfbffd4-mqh69 1/1 Running 0 12d argocd-repo-server-d8dfbffd4-mv8st 1/1 Running 0 12d argocd-server-ddfd47d99-j5nz7 1/1 Running 0 12d
- argocd-application-controller
- Kubernetes クラスタ内のリソースの状態を監視し、必要に応じてアプリケーションを更新する機能を持ちます。
- argocd-applicationset-controller
- 大量のアプリケーションを一元管理するための機能を持ちます。
- argocd-dex-server
- ArgoCD と連携して外部 ID プロバイダー(たとえばGitHub)からの認証を可能にします。
- argocd-image-updater
- Argo CDアプリケーション内の使用されるコンテナイメージの更新を自動化します。
- argocd-notifications-controller
- Argo CDアプリケーションの変更を監視し、指定された通知方法を使用して通知を送信します。
- argocd-redis
- Argo CDのバックエンドに使用されるキャッシュとステートストアのためのインメモリデータストアを提供します。
- argocd-repo-server
- Argo CDの内部リポジトリを管理し、Gitリポジトリへの同期を行います。
- argocd-server
- ArgoCD の中央管理サーバーで、Kubernetes クラスタ内のアプリケーションを管理し、GitOps ワークフローをサポートします。
これらのコンポーネントごとにログ量を調査し、ログレベルを設定する必要がありました。
ArgoCDのログ量問題に直面した背景
転職会議ではログの分析ツールとしてDatadogを利用しています。ArgoCDを導入した後にDatadogの契約プランを見直す機会があり、改めてログ量を確認したところ、ArgoCD関連のログが毎日300万件以上送られていることがわかりました。
従来のCIOpsではCI実行時のみログが出ますが、GitOpsであるArgoCDでは定期的にGitHub上のコードとの同期が走り、その際にログが出力されるのでログ量が多くなります。
DatadogのようなSaaS型のログ管理サービスは、一般的にログ量に応じてコストがかかります。そのため、できる限り不要なログは送信しないようにしてコストを抑えたいのが心情です。
ログのフォーマットが揃っている場合はDatadog側でフィルターすることも可能ですが、今回のケースでは後述するロギングライブラリが複数ある問題もあり、うまくフィルターすることができませんでした。
このため、ArgoCDのログレベルをデフォルトの info
から warn
に引き下げ、どの程度ログ量が減るか確認することにしました。
ロギングライブラリが複数あることによる苦労
ArgoCDは、デフォルトではログレベル info
でログを出力します。しかし、実際にはクリティカルでない情報も出力され、ログ量が増大してしまいます。そのため、ログレベルを warn
に変更することで、必要な情報だけを出力することにしました。
ログレベルの調整にあたって課題となったのは、ArgoCDが内部的にlogrusとklog/glogという別のロギングライブラリを利用していることです。
logrusは、Goで書かれたソフトウェアで広く使われているロギングライブラリです。一方で、klog/glogは、Kubernetesのコントローラーなど、Kubernetesのコアコンポーネントでも利用されているロギングライブラリです。
この2つのライブラリは、それぞれ異なる方法でログを出力するため、ArgoCDでログを制御する場合には注意する必要があります。
ロギングライブラリとしてlogrusを利用しているコンポーネントは、リソースのspecのコンテナを定義している部分で、コンテナに環境変数 ARGOCD_LOG_LEVEL
を追加することでログレベルが制御できます。
例: apiVersion: apps/v1 kind: Deployment metadata: name: argocd-notifications-controller spec: template: spec: containers: - name: argocd-notifications-controller (~省略~) env: - name: ARGOCD_LOG_LEVEL value: warn
一方、klog/glog を使っているコンポーネントの場合は、起動時の引数としてログレベルを渡す必要があります。転職会議ではKustomizeでArgoCDのYAMLを管理しているので、Kustomizeのパッチを利用してログのレベルを指定する引数を追加します。
例: - op: add path: /spec/template/spec/containers/0/command/- value: --loglevel=warn
できれば環境変数で制御したいところですが、起動時の引数を設定するようドキュメントに書かれているコンポーネントもあり、統一的に効くかわかりませんでした。そこで、まず環境変数を追加してみてログ出力に変化があるか確認し、うまくいかなかったコンポーネントは引数を設定するようにしました。
※ 参考として、各コンポーネントに対し環境変数と起動時の引数とのどちらが有効だったかをまとめておきます。
- 環境変数が有効だったもの
- argocd-applicationset
- argocd-server
- 起動時の引数の指定が有効だったもの
- argocd-application-controller
- argocd-dex-server
- argocd-notifications
- argocd-redis
- argocd-repo-server
- どちらも有効でなかったもの(ログレベルの制御がうまくできなかったもの)
- argocd-image-updater
ログレベルを調整した結果
3回ほど試行錯誤を繰り返しながらログレベルの設定を行いましたが、最終的に1つのコンポーネントは info
のログを制限できないまま終わりました。
すべてのコンポーネントのログを制御することはできませんでしたが、全体で見ると劇的にログを減らすことができました。
Datadogのコストにはログ量以外の要素も関わるため、最終的に大幅なDatadogのコスト削減には至りませんでしたが、今回はログ量を再確認し見直すには良いタイミングだったと思います。
おわりに
実はArgoCDのログレベル制御は苦労が多いと言う問題は、過去に別のグループも直面しており、今回の調査に際してはあらかじめ助言を受けていました。当時はログレベルを制御する環境変数がなく、すべてのコンポーネントに対しKustomizeで起動時の引数を更新する必要があったため、手間がかかっていました。
しかしKubernetes周りのエコシステムの変化は早く、ArgoCDも例外ではありません。より楽な方法でログレベルを制御できるのではないかという期待のもと調査を始め、新たに追加された環境変数を見つけるなど発見はありました。
ロギングライブラリが統一されておらず環境変数だけでは制御できなかったため、最終的にはあまり楽ではありませんでしたが、今回の調査を通じて、Kubernetesのエコシステムは常に進化していることを再認識しました。
今回の試行錯誤の結果として、すべてのArgoCDコンポーネントのログを制御することはできませんでしたが、当初の目的どおり大幅にログを減らすことができました。この記事が同じ悩みを持つどなたかの役に立てば幸いです。