Search

Fluentbit + Fluentd

Cluster

apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: skills-eks-cluster version: "1.29" region: ap-northeast-2 cloudWatch: clusterLogging: enableTypes: ["*"] vpc: subnets: public: ap-northeast-2a: { id: public_a } ap-northeast-2b: { id: public_b } private: ap-northeast-2a: { id: private_a } ap-northeast-2b: { id: private_b } managedNodeGroups: - name: skills-app-nodegroup instanceName: skills-app-node instanceType: c5.large desiredCapacity: 2 minSize: 2 maxSize: 20 privateNetworking: true
YAML
복사
eksctl create cluster -f cluster.yaml aws eks --region ap-northeast-2 update-kubeconfig --name $EKS_CLUSTER_NAME echo 'alias k=kubectl' >> ~/.bash_profile && source ~/.bash_profile
Shell
복사

ENV

EKS_CLUSTER_NAME="<Cluster Name>"
Shell
복사

OIDC

eksctl utils associate-iam-oidc-provider --region=ap-northeast-2 --cluster=$EKS_CLUSTER_NAME --approve
Shell
복사

IRSA

eksctl create iamserviceaccount \ --name fluentd \ --region=ap-northeast-2 \ --cluster $EKS_CLUSTER_NAME \ --namespace=fluentd \ --attach-policy-arn arn:aws:iam::aws:policy/CloudWatchFullAccess \ --override-existing-serviceaccounts \ --approve
Shell
복사

ConfigMap

kubectl create configmap cluster-info \ --from-literal=cluster.name=$EKS_CLUSTER_NAME \ --from-literal=logs.region=ap-northeast-2 -n fluentd
Shell
복사

Namespace

apiVersion: v1 kind: Namespace metadata: name: fluentd labels: name: amazon-cloudwatch
YAML
복사
kubectl apply -f ns.yaml kubectl create ns app
Shell
복사

Fluentd

apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: fluentd-role rules: - apiGroups: [""] resources: - namespaces - pods - pods/logs verbs: ["get", "list", "watch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: fluentd-role-binding roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: fluentd-role subjects: - kind: ServiceAccount name: fluentd namespace: fluentd --- apiVersion: v1 kind: ConfigMap metadata: name: fluentd-config namespace: fluentd labels: k8s-app: fluentd-cloudwatch data: kubernetes.conf: | kubernetes.conf fluent.conf: | @include service.conf <match fluent.**> @type null </match> service.conf: | <source> @type forward bind 0.0.0.0 port 24224 tag cloudwatch_logs.fluent-bit.access </source> <match cloudwatch_logs.fluent-bit.*> @type cloudwatch_logs log_group_name <Log Group Name> log_stream_name <Log Stream Name> auto_create_stream true <buffer tag> flush_mode immediate </buffer> </match> --- apiVersion: apps/v1 kind: DaemonSet metadata: name: fluentd namespace: fluentd spec: selector: matchLabels: k8s-app: fluentd-cloudwatch template: metadata: labels: k8s-app: fluentd-cloudwatch annotations: configHash: 8915de4cf9c3551a8dc74c0137a3e83569d28c71044b0359c2578d2e0461825 spec: serviceAccountName: fluentd terminationGracePeriodSeconds: 30 # Because the image's entrypoint requires to write on /fluentd/etc but we mount configmap there which is read-only, # this initContainers workaround or other is needed. # See https://github.com/fluent/fluentd-kubernetes-daemonset/issues/90 initContainers: - name: copy-fluentd-config image: busybox command: ["sh", "-c", "cp /config-volume/..data/* /fluentd/etc"] volumeMounts: - name: config-volume mountPath: /config-volume - name: fluentdconf mountPath: /fluentd/etc - name: update-log-driver image: busybox command: ["sh", "-c", ""] containers: - name: fluentd-cloudwatch image: fluent/fluentd-kubernetes-daemonset:v1.10.3-debian-cloudwatch-1.0 env: - name: AWS_REGION valueFrom: configMapKeyRef: name: cluster-info key: logs.region - name: CLUSTER_NAME valueFrom: configMapKeyRef: name: cluster-info key: cluster.name - name: CI_VERSION value: "k8s/1.3.24" - name: FLUENT_CONTAINER_TAIL_PARSER_TYPE value: /^(?<time>.+) (?<stream>stdout|stderr) (?<logtag>[FP]) (?<log>.*)$/ resources: limits: memory: 400Mi requests: cpu: 100m memory: 200Mi volumeMounts: - name: config-volume mountPath: /config-volume - name: fluentdconf mountPath: /fluentd/etc - name: fluentd-config mountPath: /fluentd/etc/kubernetes.conf subPath: kubernetes.conf - name: varlog mountPath: /var/log - name: varlibdockercontainers mountPath: /var/lib/docker/containers readOnly: true - name: runlogjournal mountPath: /run/log/journal readOnly: true - name: dmesg mountPath: /var/log/dmesg readOnly: true volumes: - name: config-volume configMap: name: fluentd-config - name: fluentdconf emptyDir: {} - name: fluentd-config configMap: name: fluentd-config items: - key: kubernetes.conf path: kubernetes.conf - name: varlog hostPath: path: /var/log - name: varlibdockercontainers hostPath: path: /var/lib/docker/containers - name: runlogjournal hostPath: path: /run/log/journal - name: dmesg hostPath: path: /var/log/dmesg --- apiVersion: v1 kind: Service metadata: name: fluentd-svc namespace: fluentd spec: selector: k8s-app: fluentd-cloudwatch type: ClusterIP ports: - name: service protocol: TCP port: 24224 targetPort: 24224
YAML
복사
kubectl apply -f fluentd.yaml
Shell
복사

Fluentbit

apiVersion: v1 kind: ConfigMap metadata: name: fluent-bit-sidecar-config namespace: app data: fluent-bit.conf: | [SERVICE] Flush 1 Log_Level info Daemon off [INPUT] Name tail Path /log/*.log Tag service Refresh_Interval 10 Mem_Buf_Limit 50MB Skip_Long_Lines On [OUTPUT] Name forward Match * Host SVC_IP Port 24224 Retry_Limit False
YAML
복사
SVC_CLUSTER_IP=$(kubectl get svc -n fluentd -o json | jq -r '.items[].spec.clusterIP') sed -i "s|SVC_IP|$SVC_CLUSTER_IP|g" fluentbit.yaml kubectl apply -f fluentbit.yaml
Shell
복사

Deployment

apiVersion: apps/v1 kind: Deployment metadata: name: service namespace: app labels: app: service spec: replicas: 2 selector: matchLabels: app: service template: metadata: labels: app: service spec: containers: - name: service-conatiner image: 362708816803.dkr.ecr.ap-northeast-2.amazonaws.com/service:latest imagePullPolicy: Always ports: - containerPort: 8080 name: http volumeMounts: - name: log-volume mountPath: /log - name: fluent-bit-cnt image: fluent/fluent-bit:latest imagePullPolicy: IfNotPresent ports: - containerPort: 2020 name: metrics protocol: TCP volumeMounts: - name: config-volume mountPath: /fluent-bit/etc/ - name: log-volume mountPath: /log volumes: - name: log-volume emptyDir: {} - name: config-volume configMap: name: fluent-bit-sidecar-config
YAML
복사
kubectl apply -f deployment.yaml
Shell
복사

Add Log

kubectl exec -it -n app deployment.apps/service -- curl localhost:8080 > /dev/null 2>&1
Shell
복사

Check Log

kubectl logs -n app deployment.apps/service -c fluent-bit-cnt kubectl logs -n app deployment.apps/service -c service-a-conatiner
Shell
복사