EFK Stack 구축을 통한 로그 수집
2021. 08. 06.
PROJECT
가상의 고객사 시스템 구축과 운영
-
SI
- AWS 클라우드 환경 구성
- 쿠버네티스 기반 EKS 환경 구성, 웹서비스 구축
-
SM
- 로그 수집을 위한 EFK Stack 구축
- CloudWatch 알람을 Slack으로 전송하여 실시간 모니터링
Work
- 컨테이너 환경에서의 로그 수집을 위해 EFK Stack 구축
- ElastiSearch, Fluentd, Kibana를 EKS 환경에서 구축
EFK란?
EFK
ElasticSearch+Fluentd+Kibana. 컨테이너 환경에서 로그를 수집한다.
- ElasticSearch: 대용량 로그 저장소
- Fluentd: 컨테이너의 스트림 로그를 수집하는 로그 수집기. 모든 노드마다 동일하게 배포되어야 함(Daemonset*)
- Kibana: ElasticSearch와 연동하여 로그 시각화. 이를 통해 문제 해결과 예방 가능
쿠버네티스는 파드가 정상상태가 아니면 새로 생성한다. 그렇다면 죽은 파드에 있는 컨테이너가 남긴 로그는 어떻게 되는 걸까? EFK는 컨테이너의 로그를 로그 저장소에 수집한다. 따라서 죽은 컨테이너의 로그도 남는다.
* Daemonset
쿠버네티스의 기본 Object를 생성하고 관리하는 컨트롤러(Deployment, ReplicaSet 등) 중 하나이다. Daemonset은 Pod가 각각의 노드에 하나씩만 배포되게 하는 Pod 관리 컨트롤러이다. 예를 들어 모든 노드에 로그 수집용 Daemonset pod를 띄울 수 있다.
- 관련 사이트
쿠버네티스 컨트롤러 : 데몬셋(DaemonSet)
ElasticSearch 배포
ElasticSearch
텍스트, 숫자, 위치 기반 정보, 정형 및 비정형 데이터 등 모든 유형의 데이터를 위한 분산형 오픈 소스 검색 및 분석 엔진이다. 한 마디로, 많은 양의 데이터를 보관하고 실시간으로 분석하는 엔진이다.
쿠버네티스를 사용하면 따로 ElasticSearch를 설치하는 과정을 생략할 수 있다. ElasticSearch yaml 파일을 작성하고 배포하면 끝이다. 우리는 ElasticSearch를 NodePort type 서비스로 배포하여 Nginx의 로드밸런서에 연결하여 통신 확인을 할 것이다.
ElasticSearch 배포
1. LoadBalancer의 Security group 9200 포트 오픈 → 인터넷(외부)을 통해 LB의 9200포트로 접근
2. LoadBalancer의 Listener 편집 → 9200번 포트로 들어온 트래픽을 Instance(WorkerNode)의 30920 포트로 전달
3. Worker Node로 전달된 트래픽은 9200 포트를 통해 서비스로 전달 yaml파일의 Service부분에 정의된 대로 9200 포트를 통해 서비스는 클러스터 안에서 내부적으로 노출됨.
4. 9200번 포트로 보내진 요청은 서비스에 의해 선택된 Pod의 9200포트로 전달됨 (TargetPort – 선택된 Pod의 포트)
실습
1. 먼저 지난주 실습과 동일하게 EKS를 구성하고 Nginx를 실행한다.
2. elasticSearch.yaml 파일을 작성한다.
# cat<<EOF > ~/elasticSearch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: elasticsearch
labels:
app: elasticsearch
spec:
replicas: 1
selector:
matchLabels:
app: elasticsearch
template:
metadata:
labels:
app: elasticsearch
spec:
containers:
- name: elasticsearch
image: elastic/elasticsearch:6.4.0
env:
- name: discovery.type
value: "single-node"
ports:
- containerPort: 9200
- containerPort: 9300
---
apiVersion: v1
kind: Service
metadata:
labels:
app: elasticsearch
name: elasticsearch-svc
namespace: default
spec:
ports:
- name: elasticsearch-rest
nodePort: 30920
port: 9200
protocol: TCP
targetPort: 9200
- name: elasticsearch-nodecom
nodePort: 30930
port: 9300
protocol: TCP
targetPort: 9300
selector:
app: elasticsearch
type: NodePort
EOF
3. 배포한 후 배포된 pod와 service를 확인한다.
# kubectl apply –f elasticSearch.yaml //배포
# kubectl get pod | grep elastic //배포된 pod 확인
# kubectl get svc | grep elastic //배포된 서비스 확인
4. Loadbalancer 리스너에 추가한다. [EC2 > 로드밸런서 > 리스너 > 리스너 편집 ]
리스너란, 정의한 프로토콜과 포트를 사용하여 연결 요청을 확인하는 프로세스이다. 리스너에 정의한 규칙에 따라 로드밸런서가 등록된 대상으로 요청을 라우팅 하는 방법을 결정한다.
다음과 같이 추가한다.
5. 로드밸런서의 9200 포트로 외부 접근을 허용하기 위해 보안그룹의 인바운드 규칙을 추가한다.'
[ EC2 > 로드밸런서 > Security > Security Group ID 클릭 > 인바운드 규칙 편집 ]
파란색으로 뜬 ID를 누르고 다음과 같이 편집한다. Kubernetes ELB 보안그룹을 선택해서 편집해야 한다. 아니면 접속되지 않는다.
6. Nginx 로드밸런서 DNS에 :9200를 붙여 접속하면 다음과 같은 화면을 볼 수 있다.
**Kibana 배포**
Kibana
Elastic Stack을 기반으로 구축된 오픈소스 프론트엔드 어플리케이션으로, ElasticSearch에서 색인된 데이터를 검색하고 시각화하는 기능을 제공한다. 오픈소스 기반의 분석 및 시각화 플랫폼이다.
Kibana 배포
1. LoadBalancer의 Security group 5601 포트 오픈 → 인터넷(외부)을 통해 LB의 5601포트로 접근
2. LoadBalancer의 Listener 편집 → 5601번 포트로 들어온 트래픽을 Instance(WorkerNode)의 30561 포트로 전달
3. Worker Node로 전달된 트래픽은 5601 포트를 통해 서비스로 전달 yaml파일의 Service부분에 정의된 대로 5601 포트를 통해 서비스는 클러스터 안에서 내부적으로 노출됨.
4. 5601번 포트로 보내진 요청은 서비스에 의해 선택된 Pod의5601포트로 전달됨 (TargetPort – 선택된 Pod의 포트)
실습
1. kibana.yaml 파일을 작성한다.
# cat<<EOF > ~/kibana.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: kibana
labels:
app: kibana
spec:
replicas: 1
selector:
matchLabels:
app: kibana
template:
metadata:
labels:
app: kibana
spec:
containers:
- name: kibana
image: elastic/kibana:6.4.0
env:
- name: SERVER_NAME
value: "kibana.kubenetes.example.com"
- name: ELASTICSEARCH_URL
value: "http://elasticsearch-svc.default.svc.cluster.local:9200"
ports:
- containerPort: 5601
---
apiVersion: v1
kind: Service
metadata:
labels:
app: kibana
name: kibana-svc
namespace: default
spec:
ports:
- nodePort: 30561
port: 5601
protocol: TCP
targetPort: 5601
selector:
app: kibana
type: NodePort
EOF
2. 배포한 뒤 배포된 서비스를 확인한다.
# kubectl apply –f kibana.yaml //배포
# kubectl get service //배포된 서비스 확인
3. 로드밸런서 리스너에 추가한다.
4. 보안그룹에서 인바운드 규칙을 추가한다.
5. 로드밸런서 DNS에 :5601을 붙여 Kibana web 접근을 확인한다.
Fluentd 배포
Fluentd
로그수집기. 다양한 데이터 소스(HTTP, TCP 등)로부터 원하는 형태로 가공되어 여러 목적지(ElasticSearch, s3 등)로 전달할 수 있다.
Fluentd 배포
1. fluentd.yaml을 작성한다. Daemonset으로 배포할 것이므로 kind: Daemonset으로 작성해주었다.
# cat<<EOF > ~/fluentd.yaml
---
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: apps/v1
kind: DaemonSet
metadata:
name: fluentd
namespace: kube-system
labels:
k8s-app: fluentd-logging
version: v1
kubernetes.io/cluster-service: "true"
spec:
selector:
matchLabels:
k8s-app: fluentd-logging
version: v1
template:
metadata:
labels:
k8s-app: fluentd-logging
version: v1
kubernetes.io/cluster-service: "true"
spec:
serviceAccount: fluentd
serviceAccountName: fluentd
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
containers:
- name: fluentd
image: fluent/fluentd-kubernetes-daemonset:v1.4.2-debian-elasticsearch-1.1
env:
- name: FLUENT_ELASTICSEARCH_HOST
value: "elasticsearch-svc.default.svc.cluster.local"
- name: FLUENT_ELASTICSEARCH_PORT
value: "9200"
- name: FLUENT_ELASTICSEARCH_SCHEME
value: "http"
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
EOF
2. 배포한 뒤 배포된 서비스를 확인한다.
# kubectl apply –f fluentd.yaml //배포
# kubectl get pod -n kube-system | grep fluentd //배포된 서비스 확인
로그 시각화
Kibana 인덱스 패턴 생성
1. [ Management > Index Patterns ]
2. Index pattern 이름을 logstash-*로 설정한다.
3. Configure settings를 @timestamp로 설정하고 index pattern을 생성한다.
4. 다음과 같이 생성된 것을 확인할 수 있다.
로그 시각화
1. [ Discover > Add a filter > kubernetes.labels.run is my-nginx 입력 ]
2. 로그를 확인할 수 있다.
자원 삭제
실습이 종료되었으므로 더 이상 비용이 청구되지 않게 자원을 삭제해줄 것이다.
1. kubernetes 자원 삭제
# kubectl delete -f elasticSearch.yaml
# kubectl delete -f kibana.yaml
# kubectl delete -f fluentd.yaml
# kubectl delete -f nginx-service.yaml
# kubectl delete -f nginx-deployment.yaml
2. EKS cluster와 Node Group 삭제
AWS 콘솔에서 EKS cluster와 NodeGroup 삭제를 확인해준다(지난주와 같음).
Author And Source
이 문제에 관하여(EFK Stack 구축을 통한 로그 수집), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@chchaeun/EFK-Stack-구축을-통한-로그-수집저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)