본문 바로가기

Data&Processing

fluentd 를 활용해서 Kubernetes log s3에 직접 기록하기

Fluentd

fluentd 는 open source 데이터(로그) 콜렉터로서 다양한 input, output 설정이 가능하며 kubernetes 에서도 많이 사용되는 log collect framework입니다. Kubernetes log는 각 node별 /var/log/containers 밑에 pod별로 생기기 때문에, node별로 fluentd 배포가 필요하며 따라서 k8s에 daemonSets 를 활용해서 배포하게 됩니다. 주로 나오는 use case는 tail(input) -> fluentd -> elasticSearch(output) 이며 기본예제로도 나와있어서 쉽게 따라할수 있습니다.

fluentd 에서 aws access key로 kubernetes log 를 s3에 직접기록하기

개발(?)배경

  1. 비용문제로 Elastic Search사용이 어려움
    1. ES 가 가능하다면 fluentd 보다 성능이 좋다는 fluentBit 사용도 가능
  2. Node Role에 S3관련 권한이 없어서(Role을 신청하면 되지만) access key 를 활용해서 s3적재
    1. 참고로 RBAC S3적재는 다음을 참조하면 됩니다.
      1. fluentd page 참조 - https://docs.fluentd.org/container-deployment/kubernetes   
      2. s3적재 참조 - https://docs.fluentd.org/output/s3

설정 및 배포 

  1. docker build
    1. https://github.com/fluent/fluentd-kubernetes-daemonset/tree/master/docker-image/v1.7/debian-s3 로 만든 image는 RBAC이고, access key활용으로 바꾸려면, 위에 폴더에서
    2. conf/fluent.conf 에 aws key관련 설정 추가 후
      aws_key_id "#{ENV['S3_ACCESS_KEY']}"
      aws_sec_key "#{ENV['S3_SECRET_KEY']}"
    3. docker build/배포(AWS의 경우에는 ECR)
  2. 다음 yaml파일을 통해 fluentd daemonSet을 배포하면 됩니다.
    1. DockerRepo/fluentd-kubernetes-daemonset:v1-debian-s3-key-based 가 1번에서 만든 fluentd-s3 image이고 본인이 만들고 배포한 배포URL, Docker Image명으로 사용하면 됩니다.
    2. K8s Secret 에 aws_accesskey 와 aws_secretkey를 설정해줍니다.
    3. S3_BUCKET_NAME, S3_BUCKET_REGION 설정해줍니다.
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: fluentd
  namespace: kube-system

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: fluentd
  namespace: kube-system
rules:
- apiGroups:
  - ""
  resources:
  - pods
  - namespaces
  verbs:
  - get
  - list
  - watch

---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: fluentd
roleRef:
  kind: ClusterRole
  name: fluentd
  apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
  name: fluentd
  namespace: kube-system
---
apiVersion: v1
kind: Secret
metadata:
  name: aws-secrets
  namespace: kube-system
type: Opaque
stringData:
  aws_accesskey:
  aws_secretkey:
---

apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: fluentd
  namespace: kube-system
  labels:
    k8s-app: fluentd-logging
    version: v1
spec:
  template:
    metadata:
      labels:
        k8s-app: fluentd-logging
        version: v1
    spec:
      serviceAccount: fluentd
      serviceAccountName: fluentd
      tolerations:
      - key: node-role.kubernetes.io/master
        effect: NoSchedule
      volumes:
        - name: aws-secrets
          secret:
            secretName: aws-secrets
      containers:
      - name: fluentd
        image: DockerRepo/fluentd-kubernetes-daemonset:v1-debian-s3-key-based
        env:
          - name:  S3_BUCKET_NAME
            value: ""
          - name:  S3_BUCKET_REGION
            value: ""
          - name: S3_ACCESS_KEY
            valueFrom:
              secretKeyRef:
                name: aws-secrets
                key: aws_accesskey
          - name: S3_SECRET_KEY
            valueFrom:
              secretKeyRef:
                name: aws-secrets
                key: aws_secretkey
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
      terminationGracePeriodSeconds: 30
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers

 

비용문제(고려)로 s3적재를 하긴 했지만 log를 자주 보거나 빠른 대응이 필요한 경우에는 elasticSearch 를 활용해서 적재하고, 최근 로그만 검색한다는 컨셉을 가져간다면 index retention정책으로 storage 비용은 줄일수도 있을듯 합니다.