Amazon Web Services ブログ
AWS Fargate で Amazon EKS を使用するときにアプリケーションログをキャプチャする方法
Amazon Elastic Kubernetes Service (Amazon EKS) が、AWS Fargate でアプリケーションを実行可能にKubernetes ポッドは EC2 インスタンスをプロビジョニングして管理することなく、実行できます。Fargate は すべてのポッドを VM 分離環境で実行するため、daemonsets
の概念は現在 Fargate には存在しません。したがって、Fargate を使用しているときにアプリケーションログをキャプチャするには、アプリケーションがログを出力する方法と場所を再検討する必要があります。このチュートリアルでは、Fargate で実行されているポッドのアプリケーションログをキャプチャして出荷する方法を示します。
Kubernetes ログ記録アーキテクチャ
最新のアプリケーションを構築するためのゴールドスタンダードを示す Twelve-Factor App マニフェストによると、コンテナ化されたアプリケーションは、ログを stdout
および stderr
に出力する必要があります。これはまた、Kubernetes のベストプラクティスと見なされ、クラスターレベルのログ収集システムはこの前提で構築されています。
Kubernetes ログ記録アーキテクチャは、次の 3 つの異なるレベルを定義します。
- 基本レベルのログ記録: kubectl を使用してポッドログを取得する機能 (例:
kubectl logs myapp
–myapp
はこのクラスターで実行されているポッドです) - ノードレベルのログ記録: コンテナエンジンは、アプリケーションの
stdout
とstderr
からログをキャプチャし、ログファイルに書き込みます。 - クラスターレベルのログ記録: ノードレベルのログ記録に基づく。ログキャプチャエージェントは各ノードで実行されます。エージェントはローカルファイルシステムのログを収集し、Elasticsearch や CloudWatch などの一元化ログの宛先に送信します。エージェントは次の 2 種類のログを収集します。
- ノードのコンテナエンジンによってキャプチャされたコンテナログ。
- システムログ。
Kubernetes 自体は、ログを収集して保存するためのネイティブソリューションを提供していません。ローカルファイルシステムに JSON 形式でログを保存するようにコンテナランタイムを設定します。Docker のようなコンテナランタイムは、コンテナの stdout
と stderr
ストリームをログ記録ドライバーにリダイレクトします。Kubernetes では、コンテナログはノードの /var/log/pods/*.log
に書き込まれます。Kubelet とコンテナランタイムは、systemd のオペレーティングシステムで、独自のログを /var/logs
または journald に書き込みます。次に、Fluentd のようなクラスター全体のログコレクターシステムは、これらのログファイルをノード上でテール
し、ログを出荷して保持できます。このようなログコレクターシステムは通常、ワーカーノードで DaemonSets として実行されます。ただし、DaemonSets を実行することが、Kubernetes でログを集計する唯一の方法ではありません。
一元化されたログ集約システムへのコンテナログの出荷
Kubernetes でログをキャプチャする一般的な方法は 3 つあります。
- Fluentd daemonset のようなノードレベルエージェント。これが推奨パターンです。
- サイドカーコンテナ、Fluentd サイドカーコンテナと同様。
- ログ収集システムに直接書き込む方法。 このアプローチでは、アプリケーションがログの出荷を担当します。Fluentd などのコミュニティビルドソリューションを再利用するのではなく、アプリケーションコードにログ集計システムの SDK を含める必要があるため、これは最も推奨されないオプションです。このパターンは、懸念の分離の原則にも従わないため、ログ記録の実装はアプリケーションから独立している必要があります。そうすることで、アプリケーションに影響を与えたり変更したりすることなく、ログ記録インフラストラクチャを変更できます。
Fargate で実行されているポッドの場合、サイドカーパターンを使用する必要があります。Fluentd (または Fluent Bit) サイドカーコンテナを実行して、アプリケーションによって生成されたログをキャプチャできます。このオプションでは、アプリケーションがログを stdout
または stderr
ではなく、ファイルシステムに書き込む必要があります。このアプローチの結果、kubectl
ログを使用してコンテナログを表示できなくなります。ログを kubectl logs
に表示するには、アプリケーションログを stdout
とファイルシステムの両方に同時に書き込むことができます。以下のチュートリアルでは、ファイルへの tee
書き込みと stdout
を使用しています。
アプリケーションが stdout/stderr にログを記録する場合、Fargate の EKS でクラスターレベルのログをキャプチャするために、アプリケーションに変更を加える必要があるかもしれません。これは望ましくないというお客様からの声があり、アプリケーションのリファクタリングを必要としないソリューションの作成に取り組んでいます。それまでは、EC2 インスタンスを管理せずにワークロードを実行する場合は、サイドカーパターンを使用してクラスターレベルのアプリケーションログをキャプチャできます。基本的なログ記録をポッドレベルでのみキャプチャする必要がある場合、kubectl logs
はアプリケーションのリファクタリングなしで実行できます。
Fargate のポッドは 20GB の一時ストレージを取得します。これは、ポッドに属するすべてのコンテナで使用できます。ローカルファイルシステムにログを書き込むようにアプリケーションを設定し、ログディレクトリ (またはファイル) を監視するように Fluentd に指示できます。Fluentd はログファイルの末尾からイベントを読み取り、CloudWatch などの宛先にイベントを送信して保存します。ログがボリューム全体を占有しないように、ログを定期的にローテーションしてください。
チュートリアル
デモコンテナは、/var/log/containers/application.log
へのログを生成します。Fluentd は、/var/log/containers
を監視し、CloudWatch にログイベントを送信するように設定されています。ポッドは、logrotate サイドカーコンテナも実行して、コンテナログがディスク領域を使い果たしないようにします。この例では、cron は 15 分ごとに logrotate
をトリガーします。環境変数を使用して logrotate の動作をカスタマイズできます。
クラスターと Fargate プロファイルを作成するには、最新バージョンの eksctl が必要です。
以下のコマンドは、EKS クラスターを作成します。kube-system
および default
名前空間のすべてのポッドが Fargate で実行されます。このクラスターには EC2 ノードはありません。
デモアプリケーションを実行する新しい名前空間を作成します。
logdemo
名前空間の新しい Fargate プロファイルを作成します。これにより、Fargate の logdemo
名前空間でポッドを実行するよう EKS に指示します。
クラスターの IAM OIDC ID プロバイダーを作成します。
Fluentd 用の IAM ロールと Kubernetes サービスアカウントを作成します。このロールは、Fluentd コンテナがログイベントを CloudWatch に書き込むことを許可します。
前のステップで作成したサービスアカウントを確認できます。
Fluentd ClusterRole
、RoleBinding
、および ConfigMap
のマニフェストを作成します。
マニフェストを適用します。
結果は次のようになります。
サンプルアプリケーションのマニフェストを作成します。ポッドには、Fluentd ConfigMap
をコピーして fluentd/etc/
にコピーする initContainer
が含まれています。このディレクトリは、Fluentd コンテナにマウントされます。
� REGION、AWS_REGION、CLUSTER_NAME の値を環境に合わせて編集します。
コマンドを使用してサンプルアプリケーションをデプロイします。
AWS CLI または CloudWatch コンソールを使用して、書き込まれたログを表示できます。AWS CLI を使用する場合:
デモコンテナによって生成されたログイベントが表示されます。
CloudWatch コンソールで表示するには、ロググループ “/aws/containerinsights/eksfargate-logging-demo/springapp” を検索します。
まとめ
Fargate を使用してポッドを実行する場合は、サイドカーパターンを使用してアプリケーションログをキャプチャする必要があります。kubectl
を使用してログを表示できるように、stdout
とファイルに同時に書き込むことを検討してください。EC2 ノードで実行されているアプリケーションには、daemonset パターンを引き続き使用できます。
Fargate の EKS 向けのアプリケーションログ記録にネイティブソリューションを提供することに取り組んでいます。AWS コンテナロードマップの EKS Fargate 上の FireLens の問題には、検討中の提案が含まれています。コメントをお待ちしております。ご感想をぜひお聞かせください。