AWS/Project

[K8S 환경에 Kafka 및 EFK 배포] EKS 구성

jih0ssang 2024. 4. 18. 16:40

 

1.  AWS CLI 설치

로컬 환경에 AWS CLI 설치

https://docs.aws.amazon.com/ko_kr/cli/latest/userguide/install-cliv2.html

 

AccessKey 생성

$ aws configure
AWS AccessKey ID [********HTZD]:
AWS Secret Access Key [******RhfT]:
Default region name [ap-northeast-2]:
Default output format [json]:

 

2.  Kubectl 설치

로컬에서 쿠버네티스 클러스터를 kubectl로 제어해야하므로 로컬 OS에 맞게 curl로 kubectl을 설치한다.

 

kubectl 설치

https://docs.aws.amazon.com/eks/latest/userguide/install-kubectl.html

 

환경변수 설정

kubectl 설치 후 해당 경로를 환경변수로 추가한다.

 

필자의 로컬은 Windows이므로 시작 > 검색 > 계정의 환경변수 편집

편집 을 클릭하여 Kubectl이 설치되어있는 폴더 경로를 추가한다.   ex)C:\Isers\Downloads

 

환경변수 설정이 정상적으로 되었는지 확인

$ kubectl version

 

 

3.  EKS Cluster 생성

 

클러스터 서비스 역할은 사전에 IAM Role을 생성해야 한다.

 

 

IAM Role 생성

신뢰할 수 있는 개체로 EKS - Cluster 를 선택한다.

 

자동으로 AmazonEKSClusterPolicy가 추가가 된다.

 

 

 

 

4.  EKS Worker Node 생성

EKS Cluster는 클러스터를 생성해주는 것이고, Worker Node는 EC2 인스턴스로 따로 구성된다.

이 때 사용되는 인스턴스의 역할을 생성해주어야 한다.

클러스터 서비스 역할은 사전에 IAM Role을 생성해야 한다.

 

IAM Role 생성

 

 

해당 Role에 AWS 관리형 Policy 3개를 추가한다.

 

 

 

노드에 대한 원격 액세스를 허용하여 발급받은 EC2 키 페어를 선택한다.

 

5.  IAM 액세스 항목 추가

AccessKey로 EKS 접근을 하고자 하면 액세스 항목에 AccessKey를 발급한 해당 IAM User를 추가하고 정책을 주어야 한다.

정책은

AmazonEKSAdminPolicy

AmazonEKSClusterAdminPolicy

등 주면 된다.

 

6.  kubeconfig 생성

EKS 클러스터가 생성되었다면 로컬에서도 kubectl 명령어를 사용하여 쿠버네티스 클러스터에 접근하기 위해 config 파일을 생성해야 한다.

aws eks --region ap-northeast-2 update-kubeconfig --name [EKS cluster명]

 

 

 

7.  확인

kubectl get pod -A 명령어를 통해 node들이 보이는지 확인

 

 

8. Service Account 생성

$ kubectl -n kube-system create sa tiller
$ kubectl create clusterrolebinding tiller --clusterrole cluster-admin --serviceaccount=kube-system:tiller

 

9. Helm 설치

# Helm 3.14	설치
$ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3

$ chmod 700 get_helm.sh

$ ./get_helm.sh
$ kubectl --namespace kube-system create sa tiller
$ kubectl create clusterrolebinding tiller --clusterrole cluster-admin --serviceaccount=kube-system:tiller
$ helm init --service-account tiller
$ helm repo update

 

 

10. GitHub 가져와서 Kafka 배포

 

$ git clone https://github.com/rafaelmnatali/kafka-k8s.git

$ cd confluent-local
$ kubectl apply -f 00-namespace.yaml
$ kubectl apply -f 01-kafka-local.yaml

gitHub 직접 접속해서 zip파일을 다운로드 받아서 인스턴스에 올렸다.

그리고 kafka를 배포한다.

경고문

 

Pod ContainerCreating 상태

kafka-0 이 Running이 안돼서 kafka-1, 2만 사용할 예정이다.

 

11. Topic 생성

Container 접속

$ kubectl exec -it kafka-1 -n kafka -- bash

 

 

fluentd가 데이터를 보낼 토픽생성

# Topic 생성
$ kafka-topics --create --topic fluentd-container-logging --partitions 2 --replication-factor 2 --bootstrap-server kafka-1.kafka-headless.kafka.svc.cluster.local:9092 

# Topic 확인
$ kafka-topics --describe --topic fluentd-container-logging --bootstrap-server kafka-1.kafka-headless.kafka.svc.cluster.local:9092


# Topic 삭제
$ kafka-topics --delete --topic test --bootstrap-server kafka-1.kafka-headless.kafka.svc.cluster.local:9092

 

 

<fluentd가 보낸 데이터가 큐로 잘들어오는지 확인하기 위해 컨슘머 실행>

$ kafka-console-consumer --topic fluentd-container-logging --bootstrap-server kafka-1.kafka-headless.kafka.svc.cluster.local:9092 --from-beginning

현재 들어온 메시지가 0 개이다.

12. ELK 배포

Elasticsearch.yaml

apiVersion: v1
kind: Service
metadata:
  name: elasticsearch
  namespace: elk-stack
spec:
  selector:
    app: elasticsearch
  ports:
    - port: 9200
      protocol: TCP
      targetPort: 9200
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: elasticsearch
  namespace: elk-stack
  labels:
    app: elasticsearch
spec:
  replicas: 1
  selector:
    matchLabels:
      app: elasticsearch
  template:
    metadata:
      labels:
        app: elasticsearch
    spec:
      containers:
      - name: elasticsearch
        image: elastic/elasticsearch:6.8.6
        ports:
        - containerPort: 9200
          name: http
        - containerPort: 9300
          name: tcp

 

Kibana.yaml

apiVersion: v1
kind: Service
metadata:
  name: kibana
  namespace: elk-stack
spec:
  selector:
    app: kibana
  ports:
  - protocol: TCP
    port: 5601
    targetPort: 5601
  type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kibana
  namespace: elk-stack
  labels:
    app: kibana
spec:
  replicas: 1
  selector:
    matchLabels:
      app: kibana
  template:
    metadata:
      labels:
        app: kibana
    spec:
      containers:
      - name: kibana
        image: elastic/kibana:6.8.6
        ports:
        - containerPort: 5601
          name: http

 

Logstash.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: logstash-configmap
  namespace: elk-stack
data:
  logstash.yml: |
    http.host: "127.0.0.1"
    path.config: /usr/share/logstash/pipeline
    pipeline.workers: 2
  logstash.conf: |
    # all input will come from filebeat, no local logs
    input {
      kafka {
        bootstrap_servers => "my-kafka.kafka.svc.cluster.local:9092"
        topics => "fluentd-container-logging"
        group_id => "fluentd-consumer-group"
        enable_auto_commit => "true"
        auto_offset_reset => "latest"
        consumer_threads => 4
        codec => "json"
      }
    }

    output {
        elasticsearch {
          hosts => ["http://elasticsearch.elk-stack.svc.cluster.local:9200"]
          manage_template => false
          index => "kubernetes-container-log-%{+YYYY-MM-dd}"
        }
    }
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: logstash-deployment
  namespace: elk-stack
spec:
  replicas: 1
  selector:
    matchLabels:
      app: logstash
  template:
    metadata:
      labels:
        app: logstash
    spec:
      containers:
        - name: logstash
          image: docker.elastic.co/logstash/logstash:5.6.0
          ports:
            - containerPort: 5044
          volumeMounts:
            - name: config-volume
              mountPath: /usr/share/logstash/config
            - name: logstash-pipeline-volume
              mountPath: /usr/share/logstash/pipeline
      volumes:
        - name: config-volume
          configMap:
            name: logstash-configmap
            items:
              - key: logstash.yml
                path: logstash.yml
        - name: logstash-pipeline-volume
          configMap:
            name: logstash-configmap
            items:
              - key: logstash.conf
                path: logstash.conf
---
apiVersion: v1
kind: Service
metadata:
  name: logstash-service
  namespace: elk-stack
spec:
  selector:
    app: logstash
  ports:
    - protocol: TCP
      port: 5044
      targetPort: 5044
  type: ClusterIP