はじめに
EKS 1.24へのアップグレードに伴い、コンテナのログをFluent BitでCloudWatch Logsに送るように変更しました。
Amazon EKS Kubernetes versions - Amazon EKS
If you already have Fluentd configured for Container Insights, then you must migrate Fluentd to Fluent Bit before updating your cluster. The Fluentd parsers are configured to only parse log messages in JSON format. Unlike dockerd, the containerd container runtime has log messages that aren't in JSON format. If you don't migrate to Fluent Bit, some of the configured Fluentd's parsers will generate a massive amount of errors inside the Fluentd container.
FluentdとFluent Bitの差異
こちらを参照します。
docs.aws.amazon.com
設定はFluent Bit optimized configurationとFluentd-compatible configurationが提供されていますが、Fluentd-compatible configurationは containerd
に対応していなさそう(#139)ですし、Fluent Bit optimized configurationを使用します。
主な違いは以下の通りです。
- ログストリーム名
kube-proxy
と aws-node
のログを格納するロググループ
- メタデータ
- 変更:
docker.container_id
-> kubernetes.docker_id
- 削除:
kubernetes
の container_image_id
、 master_url
、 namespace_id
、 namespace_labels
Fluentdの削除
まずは既存のリソースを削除します。
メトリクスを収集するCloudWatchエージェントについては、必要であれば除外するか、こちらの手順で再インストールしてください。
docs.aws.amazon.com
curl https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/quickstart/cwagent-fluentd-quickstart.yaml | sed "s/{{cluster_name}}/Cluster_Name/;s/{{region_name}}/Region/" | kubectl delete -f -
namespace "amazon-cloudwatch" deleted
serviceaccount "cloudwatch-agent" deleted
clusterrole.rbac.authorization.k8s.io "cloudwatch-agent-role" deleted
clusterrolebinding.rbac.authorization.k8s.io "cloudwatch-agent-role-binding" deleted
configmap "cwagentconfig" deleted
daemonset.apps "cloudwatch-agent" deleted
configmap "cluster-info" deleted
serviceaccount "fluentd" deleted
clusterrole.rbac.authorization.k8s.io "fluentd-role" deleted
clusterrolebinding.rbac.authorization.k8s.io "fluentd-role-binding" deleted
configmap "fluentd-config" deleted
daemonset.apps "fluentd-cloudwatch" deleted
Fluent Bitのインストール
こちらの手順を行います。
docs.aws.amazon.com
YAMLはリポジトリで管理・カスタマイズしたいので、手元に取得します。
各リソースの説明についてはリンク先を参照してください。
# cloudwatch-namespace.yaml
wget https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/cloudwatch-namespace.yaml
# fluent-bit-cluster-info.yaml
ClusterName=cluster-name
RegionName=cluster-region
FluentBitHttpPort='2020'
FluentBitReadFromHead='Off'
[[ ${FluentBitReadFromHead} = 'On' ]] && FluentBitReadFromTail='Off'|| FluentBitReadFromTail='On'
[[ -z ${FluentBitHttpPort} ]] && FluentBitHttpServer='Off' || FluentBitHttpServer='On'
kubectl create configmap fluent-bit-cluster-info \
--from-literal=cluster.name=${ClusterName} \
--from-literal=http.server=${FluentBitHttpServer} \
--from-literal=http.port=${FluentBitHttpPort} \
--from-literal=read.head=${FluentBitReadFromHead} \
--from-literal=read.tail=${FluentBitReadFromTail} \
--from-literal=logs.region=${RegionName} -n amazon-cloudwatch -o yaml --dry-run > fluent-bit-cluster-info.yaml
# fluent-bit.yaml
wget https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/fluent-bit/fluent-bit.yaml
マニフェストを適用します。
namespace/amazon-cloudwatch created
serviceaccount/fluent-bit created
clusterrole.rbac.authorization.k8s.io/fluent-bit-role created
clusterrolebinding.rbac.authorization.k8s.io/fluent-bit-role-binding created
configmap/fluent-bit-cluster-info created
configmap/fluent-bit-config created
daemonset.apps/fluent-bit created
CloudWatch Logsでログストリームの作成を確認します。
先頭にノード名がついてますね。
ログのフォーマットは以下です。
{
"log": "...",
"stream": "...",
"time": "...",
"kubernetes": {
"pod_name": "...",
"namespace_name": "...",
"pod_id": "...",
"host": "....",
"container_name": "...",
"docker_id": "...",
"container_hash": "...",
"container_image": "..."
}
}
ログストリーム名の変更
アプリケーション( /aws/containerinsights/<Cluster_Name>/application
)のログストリームについては、従来の単位(Pod、Namespace、コンテナ、コンテナID)で構成したいので、log_stream_templateで名前を変更します(区切り文字には制限があります)。
apiVersion: v1
kind: ConfigMap
metadata:
name: fluent-bit-config
namespace: amazon-cloudwatch
labels:
k8s-app: fluent-bit
data:
...
application-log.conf: |
...
[OUTPUT]
Name cloudwatch_logs
Match application.*
region ${AWS_REGION}
log_group_name /aws/containerinsights/${CLUSTER_NAME}/application
log_stream_prefix ${HOST_NAME}-
+ log_stream_template $kubernetes['pod_name'].$kubernetes['namespace_name'].$kubernetes['container_name'].$kubernetes['docker_id']
auto_create_group true
extra_user_agent container-insights