Amazon Web Services ブログ
Fluent Bit for Amazon EKS on AWS Fargate をリリース
本投稿は、Akshay Ram, Prithvi Ramesh, Michael Hausenblas による寄稿を翻訳したものです。
Container roadmap 上の issue 701 では、 EKS on Fargate 利用時の CNCF Fluent Bit を利用したログルーターのサポートについて議論していました。このブログ記事では、EKS on Fargete利用時におけるいくつかの設定ステップによってCloudWatch へ直接ログを送信する事が出来る新しい機能とそれを利用する流れをみていきましょう。
以前は、AWS Fargate 上で動くAmazon EKS の Pod から コンテナログを送信するためには サイドカーコンテナを動かす必要がありましたが、組み込みのログルーターを利用出来るようになりました。これはサイドカーをインストールしたり維持する必要が無いという事を意味しています。ユーザーはデータの送信先を選択するだけで、ログは選択した送信先にルーティングされます。
私たちは、2つの設計原則を維持しながらこの機能を構成しました。
- 一貫性:必要に応じて、ネイティブの Kubernetes オブジェクトを利用して、コンピューティングタイプ(EC2、マネージドノードグループ、Fargate)に渡った一貫したインターフェイスをお客様に提供する
- シンプル:お客様のインフラストラクチャーや add-ons をさらに管理する
この設計原則に従う事で、Fluent Bit 設定言語と Kubernetes Config Map を、プライマリインターフェイスとして選択し、 Kubernetes クラスターにおける標準的な方法としてロギングを設定する様にしました。Fluent Bit をプラットフォームの中に含める事で、Fluent Bit のライフサイクル管理をシンプルにしました。ログを何処に送るかを指定するだけで、後はAWSによって管理されます。
新しい組み込みロギングのサポートにより、ユーザはデータの送信先を選択するだけで、ログは選択した送信先にルーティングされます。その裏側では、EKS on Fargateは Fluent Bit for AWSを利用しています。Flunet Bit for AWS は AWSによって管理されている Fluent Bit でアップストリームに準拠したディストリビューションです。
EKS on Fargate上でFluent Bit を利用したロギングを行うためには、Fluent Bit の設定を記述した ConfigMap を Amazon EKS クラスターに対して適用します。
このロギング用 ConfigMap は、aws-observability
という固定の namespaceを利用していて、 クラスター全体に適用されます。つまり、任意のnamespaceにある任意のアプリケーションのログを送信する事が出来る事を意味しています。選択したログ送信先の定義には Fluent Bit 設定言語が利用できます。 CloudWatch 、ElasticSearch 、 Kinesis Firehose、Kinesis Streams を output として選択可能です。
CloudWatch へのログ送信
下の図では、cloudwatch_logs (C言語で書かれたFluentBit output plugin) を使って、 EKS on Fargate クラスター上で動いているワークロードから CloudWatchにログを送る方法を示しています。
以下の様に、最初にEKS on Fargate クラスターを作成します。eksctl
設定ファイルとして、以下の内容をeks-cluster-config.yaml
として保存してください。
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: fluentbit
region: eu-west-1
version: '1.18'
iam:
withOIDC: true
fargateProfiles:
- name: defaultfp
selectors:
- namespace: demo
- namespace: kube-system
cloudWatch:
clusterLogging:
enableTypes: ["*"]
続いて、次のコマンドでEKS クラスターを作成します。
eksctl create cluster -f eks-cluster-config.yaml
EKS コントロールプレーンと Fargate プロファイルの作成が完了するまでに、15-20分の時間がかかることに注意してください。
続いて、以下の内容を保存した fluent-config.yaml
を利用して、専用の aws-observability
namespace、ConfigMapを作成します。
kind: Namespace
apiVersion: v1
metadata:
name: aws-observability
labels:
aws-observability: enabled
---
kind: ConfigMap
apiVersion: v1
metadata:
name: aws-logging
namespace: aws-observability
data:
output.conf: |
[OUTPUT]
Name cloudwatch_logs
Match *
region eu-west-1
log_group_name fluent-bit-cloudwatch
log_stream_prefix from-fluent-bit-
auto_create_group On
上記の YAML マニフェストでは、 アプリケーションがログを出力すると直ぐに、CloudWatch log group の名前として記載されている fluent-bit-cloudwatch
が自動作成されます。
それでは、以下のコマンドを利用して、Fluent Bit 設定を作成していきます。
kubectl apply -f fluentbit-config.yaml
Fluent Bit ConfigMap が設定されたかを確認するため、次のコマンドを実行し、同様の内容が出力されるか確認しましょう。
$ kubectl -n aws-observability get cm
NAMESPACE NAME DATA AGE
aws-observability aws-logging
Fluent Bitをセットアップするために、次はCloudWatchへの書き込み権限を付与します。まず最初に以下のポリシーをローカルにダウンロードします。
$ curl -o permissions.json \
https://raw.githubusercontent.com/aws-samples/amazon-eks-fluent-logging-examples/mainline/examples/fargate/cloudwatchlogs/permissions.json
続いてポリシーを作成し、 EKS on Fargate クラスターの pod execution role にポリシーをアタッチしましょう。
aws iam create-policy \
--policy-name FluentBitEKSFargate \
--policy-document file://permissions.json
aws iam attach-role-policy \
--policy-arn arn:aws:iam::123456789012:policy/FluentBitEKSFargate \
--role-name eksctl-fluentbit-cluster-FargatePodExecutionRole-XXXXXXXXXX
上記のコマンドでは、eksctl-fluentbit-cluster-FargatePodExecutionRole-XXXXXXXXX
Xとなっている部分をご自身の環境に合わせて変更してください(例えば、 EKS コンソールから Fargate profileにアクセスして確認します)。同様にarn:aws:iam::123456789012:policy/FluentBitEKSFargate
にあるアカウントID (123456789012)
もご自身のアカウント IDに入れ替えてください。
ロギングインフラストラクチャーのセットアップを実施するとCloudWatchへ送信するログを生成する事が出来る様になります。
最初に、HTTP インターフェイスを利用したログを生成する Service を作成します。logger-server.yaml
ファイルを作成し以下の内容を入力してください。
apiVersion: apps/v1
kind: Deployment
metadata:
name: logger-server
spec:
selector:
matchLabels:
app: nginx
replicas: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: main
image: nginx:1.14.2
ports:
- containerPort: 80
続いて、Deployment、Pod 、トラフィックをルーティングする Service を作成します。
$ kubectl -n demo apply -f logger-server.yaml && kubectl -n demo expose deploy logger-server
それでは、logger-server Deploymentが管理するPodが、実際に期待した通りにロギングが有効化されているかを確認しましょう。
# find the name of the logger-server pod:
$ kubectl -n demo get po -l app=nginx
NAME READY STATUS RESTARTS AGE
logger-server-fb8546f69-qflh2 1/1 Running 0 21h
# get details about the logger-server pod:
$ kubectl -n demo describe po/logger-server-fb8546f69-qflh2
Name: logger-server-fb8546f69-qflh2
Namespace: demo
Priority: 2000001000
Priority Class Name: system-node-critical
Node: fargate-ip-192-168-147-211.eu-west-1.compute.internal/192.168.147.211
Start Time: Wed, 25 Nov 2020 16:01:51 +0000
Labels: app=nginx
eks.amazonaws.com/fargate-profile=defaultfp
pod-template-hash=fb8546f69
Annotations: CapacityProvisioned: 0.25vCPU 0.5GB
Logging: LoggingEnabled
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal LoggingEnabled 2m7s fargate-scheduler Successfully enabled logging for pod
Normal Scheduled 44s fargate-scheduler Successfully assigned demo/logger-server-fb8546f69-qflh2 to fargate-ip-192-168-147-211.eu-west-1.compute.internal
Normal Pulling 45s kubelet Pulling image "nginx:1.14.2"
Normal Pulled 40s kubelet Successfully pulled image "nginx:1.14.2"
Normal Created 39s kubelet Created container main
Normal Started 39s kubelet Started container main
正しく動いている様です。Successfully enabled logging for pod
とイベントに出力されていることを確認できます。これは、次の手順に進める事が出来る事を意味しています。最後の手順はログの生成です。
logger-server
がログを生成するために、サービスをローカル環境に転送し、クライアントとしてcurl
を使用してGET
リクエストを発行します。加えてローカルのログをみてみましょう。3つのterminalを使って実行します。
# [terminal 1] forward the logger-server traffic locally:
$ kubectl -n demo port-forward svc/logger-server 8080:80
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80
Handling connection for 8080
# [terminal 2] watch logs locally:
$ kubectl -n demo logs deploy/logger-server -f
127.0.0.1 - - [25/Nov/2020:16:03:41 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.64.1" "-"
127.0.0.1 - - [25/Nov/2020:16:03:42 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.64.1" "-"
127.0.0.1 - - [25/Nov/2020:16:03:43 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.64.1" "-"
# [terminal 3] generate HTTP traffic:
$ curl localhost:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
Fluent Bit config mapで特定したロググループ名は fluent-bit-cloudwatch
です。CloudWatch consoleで確認してみましょう。
全て期待通りに動いてます!まとめる前に、 Fluent Bit を EKS Fargateで正常に利用するたの、ヒントやTipsを紹介します。
使用上の考慮事項
ログルーターによって使用される追加のリソースについて考慮する事をお奨めします。私たちのテストでは、50MBのメモリを追加リソースとして考慮した方が良い事を示唆しています。そのため、 Fluent Bit プロセスが並んで動くために、ドキュメントに記載されている resource requestにより、アプリケーション podに対してリソースを追加しましょう。アプリケーションが大量のログを生成する事を想定している場合は、suggeted headroom として 100MBを考慮しましょう。
プラグイン (ログ送信先)の選択に依存して、ログ収集とストレージコストを別々に支払います。詳細については、CloudWatch 料金 ページを参照してください。
ローンチ時点では、以下の KubernetesおよびEKS platform versionでサポートされています。
- Kubernetes 1.15: platform version eks.6
- Kubernetes 1.16: platform version eks.5
- Kubernetes 1.17: platform version eks.5
- Kubernetes 1.18: platform version eks.3
このインテグレートされたロギングを使った感想を教えてください。また container roadmapを通じた提案をお待ちしています。追加の詳細やアナウンスメントについては re:Invent 2020 セッションを視聴してください。
翻訳はソリューションアーキテクトの浅野 佑貴が担当しました。原⽂はこちらです。