過去記事でEKS FargateのPodを起動するところまでやってみた。今回はFargate PodからFluent Bit経由でCloudWatch Logsにログを送信してみる。
EKS Fargateの関連記事
EKS FargateクラスタをTerraformで作成する(1)
EKS FargateクラスタをTerraformで作成する(2)
Fargate + Fluent Bitの参考記事
Fluent Bit for Amazon EKS on AWS Fargate をリリース
Amazon EKS on Fargate上のPodログをCloudWatchLogsに送信する
EKSクラスタは過去記事同様にTerraformから自動作成とする。で、FluentBit対応に入るが、準備してからクラスタ作成したかったのでドキュメントとは若干順番が異なる。まず過去記事でFargate Pod用のIAMロールを作成したが、CWログ送信にあたって追加で権限が必要なため別途ポリシーを作成して対象ロールにアタッチする。
# ポリシーファイルをDL。
$ curl -OL https://raw.githubusercontent.com/aws-samples/amazon-eks-fluent-logging-examples/mainline/examples/fargate/cloudwatchlogs/permissions.json
# ポリシー作成
$ aws iam create-policy \
--policy-name eks-fargate-fluent-bit-cloudwatch \
--policy-document file://permissions.json
# 既存のFargate Pod用ロールにポリシーをアタッチする。
$ aws iam attach-role-policy \
--policy-arn arn:aws:iam::012345678910:policy/eks-fargate-fluent-bit-cloudwatch \
--role-name AmazonEKSFargatePodExecutionRole
この後terraform apply
でEKSクラスタを作成。この間に必要なマニフェストを用意。試行錯誤したが最終的にPoCに使ったマニフェストは以下2種。ファイル名や各種値は任意だが一部変更不可の値があるため注意。
- fargate-logging.yaml(ロギング専用Namespace及びConfigMapの定義)
- httpd-pod.yaml (Fargate用Namespace及びログ送信用Deploymentの定義)
fargate-logging.yaml
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
Match *
region ap-northeast-1
log_group_name /aws/eks/fargate-fluent-bit
log_stream_prefix fargate-pod-log-
auto_create_group true
httpd-pod.yaml
kind: Namespace
apiVersion: v1
metadata:
name: fargate-test #Fargateプロファイルで設定している値
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpd-pod #任意名称
namespace: fargate-test #Fargateプロファイルで設定している値
spec:
selector:
matchLabels:
app: nginx
replicas: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: main
image: nginx
ports:
- containerPort: 80
クラスタ作成完了後、aws eks update-kubeconfig --name [your cluster name]
を実行し、以下コマンドを実行する。
#ログ送信定義をapply
$ kubectl apply -f fargate-logging.yaml
namespace/aws-observability created
configmap/aws-logging created
#Fargate Podを起動
$ kubectl apply -f httpd-pod.yaml
namespace/fargate-test created
deployment.apps/httpd-pod created
#ConfigMapの確認
$ kubectl -n aws-observability get cm
NAME DATA AGE
aws-logging 1 32s
kube-root-ca.crt 1 32s
ここからログ送信のためhttpリクエストを生成していく。ターミナルを3個開いて作業する。
###ターミナル1
#deploymentをexposeする。
$ kubectl -n fargate-test expose deploy httpd-pod
#コネクション生成
kubectl -n fargate-test port-forward svc/httpd-pod 8080:80
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80
###ターミナル2
#リクエスト送信。以下コマンドを何度か繰り返す。
$ curl localhost:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
(snip)
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
###ターミナル3
#ローカルでログ確認
$ kubectl -n fargate-test logs deploy/httpd-pod -f
(snip)
127.0.0.1 - - [10/Jan/2022:09:17:15 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.64.1" "-"
127.0.0.1 - - [10/Jan/2022:09:17:47 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.64.1" "-"
127.0.0.1 - - [10/Jan/2022:09:19:01 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.64.1" "-"
マネコンを覗いてみると、CloudWatch Logsにログが送信されていることを確認できた。
しかし実際にはこのようにあっさり成功したのではなく、それなりに試行錯誤があった、変更不可の値を任意の名称に変えたりしてたから。以下はfargate-logging.yamlを2回目にapplyした時のエラー。初回はエラー出なかったんだよ。最初から言ってくれよ…
Error from server: error when creating “fargate-logging.yaml”: admission webhook “0500-amazon-eks-fargate-configmaps-admission.amazonaws.com” denied the request: fargate.conf is not valid. Please only provide output.conf, filters.conf, parsers.conf or flb_log_cw in the logging configmap
素直に公式ドキュメントの通りにしていればつまづくことはなかっただろう。まぁわかったからいいけどね。
それと設定が読み込まれていないと思われるケースではPod再起動してみたり。(しかし今回の場合は原因はこれじゃなかった)
$ kubectl -n fargate-test rollout restart deploy httpd-pod
課題
今回はログストリームのプレフィックスを決め打ちにしているが、本来であれば通常のEKSのように、Kubernetes filterでPod名から拾うとかさせたいのである。FargateでのKubernetes filterは初期の頃はサポートされていなかったが、現在は使用できるようになった。今度やってみよう。
Amazon EKS on AWS Fargate が Fluent Bit Kubernetes Filter のサポートを開始
ちなみに通常のEKSのログ送信については以下参照
EKS Container InsightsのFluent Bit設定