Amazon EKS on Fargate　Flunet Bit for AWS でログ転送

# Fargate でログを送るには

- Fluent Bit をベースにした組み込みのログルーターが利用可能。
- Fluent Bit コンテナをサイドカーとして明示的に実行する必要はなく、AWS によって行われる。


# 設定するには

- 必要となるのは、ログルーターの設定だけであり、設定は ConfigMap で行う。

- ConfigMap には以下の定義が必須となる。
  - `name: aws-logging`
  - `namespace: aws-observability`


# どう動作するのか

- ConfigMap を作成すると、Fargate の EKS は自動的に検出する。


# 送信先

https://aws.amazon.com/jp/blogs/news/fluent-bit-for-amazon-eks-on-aws-fargate-is-here-jp/

上記の AWS Blog にイメージ図が記載されているので、そちらを参照。

- CloudWatch
- OpenSearch Service
- Kinesis Data Firehose 経由で S3
- Kinesis Data Streams、およびパートナーツールなどの送信先にログをストリーミング


# Fluent Conf

https://docs.fluentbit.io/manual/administration/configuring-fluent-bit/classic-mode/configuration-file

- Fargate のログルータでは、以下のセクションだけを受け入れる。
  - Filter
  - Output
  - Parser

他のセクションを提供した場合は拒否される。


# Demo

## 1. fargateProfiles の作成

Fargate で起動するように、fargateProfiles を作成する。

```ClusterConfig.yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: cluster-test
  region: ap-northeast-1
  version: "1.27"

iam:
  withOIDC: true

fargateProfiles:
  - name: node-fargate
    selectors:
      - namespace: default
      - namespace: kube-system
      - namespace: aws-observability
```

## 2. namespace の作成

`namespace aws-observability` を作成および作成されたことを確認する。

```namespace.yaml
kind: Namespace
apiVersion: v1

metadata:
  name: aws-observability
  labels:
    aws-observability: enabled
```

```
kubectl apply -f namespace.yaml
```

```
kubectl get ns aws-observability

NAME                STATUS   AGE
aws-observability   Active   2m8s
```

## 3. ConfigMap の作成

Fluent Conf を使用して ConfigMap を作成し、コンテナログを CloudWatchLogs に送信するように作成し、作成されたことを確認する。

```ConfigMap.yaml
kind: ConfigMap
apiVersion: v1

metadata:
  name: aws-logging
  namespace: aws-observability

data:
# Fluent Bit のプロセスログを CloudWatch に送信する場合は true を設定する
  flb_log_cw: "false" 

  filters.conf: |
# すべてのログエントリに parser を適用する。この parser は後述の parsers.conf で定義する。
    [FILTER]
        Name parser
        Match *
        Key_name log
        Parser crio

# kubernetes Filter を利用する。
# https://docs.fluentbit.io/manual/pipeline/filters/kubernetes
    [FILTER]
        Name kubernetes
        Match kube.*
        Merge_Log On
        Keep_Log Off
        Buffer_Size 0
        Kube_Meta_Cache_TTL 300s

# CloudWatch Logs に送信する設定を定義する。
  output.conf: |
    [OUTPUT]
        Name cloudwatch_logs
        Match   kube.*
        region ap-northeast-1
        log_group_name my-logs
        log_stream_prefix from-fluent-bit-
        log_retention_days 60
        auto_create_group true

# Fluent Bit がログエントリを受け取り、この場合正規表現に基づいてログを解釈し変換する。
  parsers.conf: |
    [PARSER]
        Name crio
        Format Regex
        Regex ^(?<time>[^ ]+) (?<stream>stdout|stderr) (?<logtag>P|F) (?<log>.*)$
        Time_Key    time
        Time_Format %Y-%m-%dT%H:%M:%S.%L%z
```

```
kubectl apply -f configmap.yaml
```

```
kubectl get ConfigMap -n aws-observability

NAME               DATA   AGE
aws-logging        4      30s
```

## 4. Fargate プロファイルのポッド実行ロールに、CloudWatch Logs への書き込み権限を付与する

Fargate プロファイルのポッド実行ロールが、CloudWatch Logs にログを送信するための IAM ポリシー(eks-fargate-logging-policy.json)を追加します。

![スクリーンショット 2023-12-19 19.23.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/4227c600-2665-8097-34f3-0293711a4eba.png)

```eks-fargate-logging-policy.json
{
	"Version": "2012-10-17",
	"Statement": [{
		"Effect": "Allow",
		"Action": [
			"logs:CreateLogStream",
			"logs:CreateLogGroup",
			"logs:DescribeLogStreams",
			"logs:PutLogEvents",
            "logs:PutRetentionPolicy"
		],
		"Resource": "*"
	}]
}
```

## 5. 動作確認

適当な deployment を作成し、作成されたことと、ロギングが有効になっていること(LoggingEnabled)を確認する。

```deployment.yml
apiVersion: apps/v1
kind: Deployment

metadata:
  name: nginx-deployment

spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

```

```
kubectl apply -f deployment.yml
```

```
kubectl get pod -o wide

NAME                                READY   STATUS    RESTARTS   AGE     IP                NODE                                                         NOMINATED NODE   READINESS GATES
nginx-deployment-57d84f57dc-h7tvp   1/1     Running   0          6m47s   192.168.162.163   fargate-ip-192-168-162-163.ap-northeast-1.compute.internal   <none>           <none>
nginx-deployment-57d84f57dc-hrxb6   1/1     Running   0          6m47s   192.168.171.25    fargate-ip-192-168-171-25.ap-northeast-1.compute.internal    <none>           <none>
```

```
kubectl describe pod nginx-deployment-57d84f57dc-h7tvp

Annotations:
                      Logging: LoggingEnabled

Events:
  Type    Reason          Age    From               Message
  ----    ------          ----   ----               -------
  Normal  LoggingEnabled  3m54s  fargate-scheduler  Successfully enabled logging for pod
```

CloudWatch Logs にコンテナログが転送されたことを確認する。

![スクリーンショット 2023-12-19 19.59.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/2b800a8d-c88f-d288-f341-4b42f6160126.png)

![スクリーンショット 2023-12-19 20.11.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/3166d7c1-7d96-906f-a909-164a991d141d.png)


# リンク

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/fargate-logging.html#fargate-logging-troubleshooting