1. Control Plane 로깅 확인
이번 실습은 4장 Amazon EKS 원클릭 배포 환경에서 진행합니다.
인프라 배포를 진행하지 않은 경우 링크를 통해 배포 후 복귀 바랍니다.
그리고 새롭게 인프라를 배포하면 아래 기본 설정 명령을 입력 후 진행 바랍니다.
기본 설정 명령어
Default 네임 스페이스 변경
1
kubectl ns default
워커 노드의 IP 변수 선언
1
2
3
4
5
6
7
8
9
10
11
N1=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2a -o jsonpath={.items[0].status.addresses[0].address})
N2=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2b -o jsonpath={.items[0].status.addresses[0].address})
N3=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2c -o jsonpath={.items[0].status.addresses[0].address})
echo "export N1=$N1" >> /etc/profile
echo "export N2=$N2" >> /etc/profile
echo "export N3=$N3" >> /etc/profile
노드에 SSH 접근
1
for node in $N1 $N2 $N3; do ssh ec2-user@$node hostname; done
AWS Load Balancer Controller 설치
1
2
3
4
5
6
7
helm repo add eks https://aws.github.io/eks-charts
helm repo update
helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=$CLUSTER_NAME \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller
ExternalDNS 설치
1
2
3
4
5
6
7
8
9
10
// 자신의 도메인 주소로 설정
MyDomain=<자신의 도메인>
MyDnsHostedZoneId=$(aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." --query "HostedZones[0].Id" --output text)
echo $MyDomain, $MyDnsHostedZoneId
curl -s -O https://raw.githubusercontent.com/cloudneta/cnaeblab/master/_data/externaldns.yaml
MyDomain=$MyDomain MyDnsHostedZoneId=$MyDnsHostedZoneId envsubst < externaldns.yaml | kubectl apply -f -
kube-ops-view 설치
1
2
3
4
5
6
7
8
9
helm repo add geek-cookbook https://geek-cookbook.github.io/charts/
helm install kube-ops-view geek-cookbook/kube-ops-view --version 1.2.2 --set env.TZ="Asia/Seoul" --namespace kube-system
kubectl patch svc -n kube-system kube-ops-view -p '{"spec":{"type":"LoadBalancer"}}'
kubectl annotate service kube-ops-view -n kube-system "external-dns.alpha.kubernetes.io/hostname=kubeopsview.$MyDomain"
echo -e "Kube Ops View URL = http://kubeopsview.$MyDomain:8080/#scale=1.5"
StorageClass 생성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cat <<EOT > gp3-sc.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: gp3
allowVolumeExpansion: true
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
parameters:
type: gp3
allowAutoIOPSPerGBIncrease: 'true'
encrypted: 'true'
EOT
kubectl apply -f gp3-sc.yaml
ACM 인증서 변수 선언
1
CERT_ARN=`aws acm list-certificates --query 'CertificateSummaryList[].CertificateArn[]' --output text`; echo $CERT_ARN
1.1. Control Plane 로깅 활성화
Amazon EKS Control Plane 로깅 활성화
1
2
3
// Amazon EKS Control Plane 로깅 활성화 설정
aws eks update-cluster-config --region $AWS_DEFAULT_REGION --name $CLUSTER_NAME \
--logging '{"clusterLogging":[{"types":["api","audit","authenticator","controllerManager","scheduler"],"enabled":true}]}'
로그 그룹 및 로그 스트림 확인
1
2
3
4
5
6
// CloudWatch의 로그 그룹 생성 확인
aws logs describe-log-groups | jq
// 로그 그룹에 구성된 로그 스트림 확인
aws logs describe-log-streams \
--log-group-name /aws/eks/${CLUSTER_NAME}/cluster | grep logStreamName
1.2. Control Plane 로그 확인
awscli로 Control Plane 로그 확인
1
2
3
4
5
6
7
8
9
10
11
12
13
// 10분 동안 Control Plane 로그 확인(more 옵션)
aws logs tail /aws/eks/$CLUSTER_NAME/cluster | more
// 신규 로그 바로 출력
aws logs tail /aws/eks/$CLUSTER_NAME/cluster --follow
//로그 스트림 대상 지정 (kube-controller-mananger)
aws logs tail /aws/eks/$CLUSTER_NAME/cluster --log-stream-name-prefix kube-controller-manager --follow
// 신규 터미널 생성 후 coreDNS 수량 조정
kubectl scale deployment -n kube-system coredns --replicas=1
kubectl scale deployment -n kube-system coredns --replicas=2
관리 콘솔에서 CloudWatch 서비스에 로그 영역에서 Logs Insights 메뉴로 진입합니다.
Select up to 50 log groups에 생성한 로그 그룹을 선택 후 다음 작업을 수행합니다.
CloudWatch 로그 인사이트에서 쿼리하기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// kube-apiserver-audit 로그에서 UserAgent 정렬 후 카운트 값
fields userAgent, requestURI, @timestamp, @message
| filter @logStream ~= "kube-apiserver-audit"
| stats count(userAgent) as count by userAgent
| sort count desc
// kube-apiserver 로그에서 timestamp로 정렬
fields @timestamp, @message
| filter @logStream ~= "kube-apiserver"
| sort @timestamp desc
// authenticator 로그에서 timestamp로 정렬
fields @timestamp, @message
| filter @logStream ~= "authenticator"
| sort @timestamp desc
1.3. Control Plane 로깅 비활성화
Control Plane 로깅 비활성화
1
2
3
4
5
6
7
8
9
// EKS Control Plane 로깅 비활성화
eksctl utils update-cluster-logging \
--cluster $CLUSTER_NAME \
--region $AWS_DEFAULT_REGION \
--disable-types all \
--approve
// Control Plane 로그 그룹 삭제
aws logs delete-log-group --log-group-name /aws/eks/$CLUSTER_NAME/cluster
2. Application 로깅 직접 확인
2.1. NGINX 웹 서버 배포
Helm으로 bitnami nginx 설치
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// helm repository 추가
helm repo add bitnami https://charts.bitnami.com/bitnami
// nginx 파라미터 파일 생성
cat <<EOT > nginx-values.yaml
service:
type: NodePort
ingress:
enabled: true
ingressClassName: alb
hostname: nginx.$MyDomain
path: /*
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
alb.ingress.kubernetes.io/success-codes: 200-399
alb.ingress.kubernetes.io/load-balancer-name: $CLUSTER_NAME-ingress-alb
alb.ingress.kubernetes.io/group.name: study
alb.ingress.kubernetes.io/ssl-redirect: '443'
EOT
cat nginx-values.yaml | yh
// nginx 배포
helm install nginx bitnami/nginx --version 14.1.0 -f nginx-values.yaml
생성 정보 확인
1
2
3
4
5
// ingress, deployment, service, endpoint nginx 확인
kubectl get ingress,deploy,svc,ep nginx
// alb targetgroupbinding 확인
kubectl get targetgroupbindings
2.2. Application 로그 확인
HTTP, HTTPS 접속 확인
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// HTTPS로 접속
curl -s https://nginx.$MyDomain
// HTTP로 접속
curl -s http://nginx.$MyDomain
// HTTP로 접속할 때 상세 로그 설정
curl -vs http://nginx.$MyDomain
// HTTP로 접속할 때 리다이렉션 location 정보 출력
curl -L http://nginx.$MyDomain
// 신규 터미널 모니터링 - 반복 접속
MyDomain = <자신의 도메인>
while true; do curl -s https://nginx.$MyDomain -I | head -n 1; date; sleep 1; done
컨테이너 로그 확인
1
2
3
4
5
// 컨테이너 로그 확인
kubectl logs deploy/nginx -c nginx -f
// 컨테이너 로그 파일 위치 확인
kubectl exec -it deploy/nginx -c nginx -- ls -l /opt/bitnami/nginx/logs/
bitnami nginx 빌드 정보 링크에서 access.log와 error.log 정보를 확인합니다.
노드에서 컨테이너 로그 확인
1
2
3
4
5
6
7
8
9
10
// /var/log/containers tree 확인 (nginx 파드가 생성된 노드 지정)
ssh ec2-user@$N1 sudo tree -C /var/log/containers
// /var/log/pods tree 확인 (nginx 파드가 생성된 노드 지정)
ssh ec2-user@$N1 sudo tree -C /var/log/pods
// /var/log/pods에서 로그 직접 확인 (nginx 로그 뒤에 삽입)
ssh ec2-user@$N1 sudo tail -f <XXXXXXXXX>
ssh ec2-user@$N1 sudo head <XXXXXXXXX>
kubelet의 컨테이너 로그 최대 사이즈
1
ssh ec2-user@$N1 journalctl -u kubelet | grep FLAG | grep container-log-max
3. FluentBit를 활용한 중앙 집중형 로깅 확인
3.1. 노드에서 로그 소스 확인
Application 로그 소스
1
2
3
4
5
6
// application 로그 소스 확인
for node in $N1 $N2 $N3; do echo ">>>>> $node <<<<<"; \
ssh ec2-user@$node sudo tree /var/log/containers; echo; done
for node in $N1 $N2 $N3; do echo ">>>>> $node <<<<<"; \
ssh ec2-user@$node sudo tree /var/log/pods; echo; done
Host 로그 소스
1
2
3
4
5
6
7
// host 로그 소스 (Logs from /var/log/dmesg, /var/log/secure, and /var/log/messages), 노드(호스트) 로그
for node in $N1 $N2 $N3; do echo ">>>>> $node <<<<<"; \
ssh ec2-user@$node sudo tree /var/log/ -L 1; echo; done
// 노드 1에 dmesg, secure, messages 로그 확인
for log in dmesg secure messages; do echo ">>>>> Node1: /var/log/$log <<<<<"; \
ssh ec2-user@$N1 sudo tail /var/log/$log; echo; done
Dataplane 로그 소스
1
2
3
4
5
6
7
8
// dataplane 로그 소스(/var/log/journal for kubelet.service, kubeproxy.service, and docker.service), 쿠버네티스 데이터플레인 로그
for node in $N1 $N2 $N3; do echo ">>>>> $node <<<<<"; \
ssh ec2-user@$node sudo tree /var/log/journal -L 1; echo; done
// journal 로그 확인 (kubelet 정보)
ssh ec2-user@$N3 sudo journalctl -u kubelet -x -n 200
ssh ec2-user@$N3 sudo journalctl -u kubelet -f
3.2. FluentBit 설치 및 확인
네임 스페이스 생성
1
2
3
4
5
// 네임스페이스 생성
kubectl apply -f https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/cloudwatch-namespace.yaml
// 네임스페이스 확인
kubectl get ns
FluentBit ConfigMap 생성
1
2
3
4
5
6
7
8
9
10
11
12
13
// Fluent-bit ConfigMap 생성
FluentBitHttpServer='On'
FluentBitHttpPort='2020'
FluentBitReadFromHead='Off'
FluentBitReadFromTail='On'
kubectl create configmap fluent-bit-cluster-info \
--from-literal=cluster.name=${CLUSTER_NAME} \
--from-literal=http.server=${FluentBitHttpServer} \
--from-literal=http.port=${FluentBitHttpPort} \
--from-literal=read.head=${FluentBitReadFromHead} \
--from-literal=read.tail=${FluentBitReadFromTail} \
--from-literal=logs.region=${AWS_DEFAULT_REGION} -n amazon-cloudwatch
FluentBit 생성
1
2
3
4
5
// Fluentbit 생성
kubectl apply -f https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/fluent-bit/fluent-bit.yaml
// 설치 확인
kubectl get ds,pod,cm,sa -n amazon-cloudwatch
FluentBit ConfigMap 확인
1
2
3
4
5
6
// FluentBit Configmap 확인
kubectl get cm fluent-bit-cluster-info -n amazon-cloudwatch -o yaml | yh
// FluentBit Configmap 상세 - 로그 INPUT/FILTER/OUTPUT 설정 확인
/// 설정 구성 : application-log.conf, dataplane-log.conf, fluent-bit.conf, host-log.conf, parsers.conf
kubectl describe cm fluent-bit-config -n amazon-cloudwatch
FluentBit DaemonSet 확인
1
2
3
4
5
6
// FluentBit Daemonset
/// 파드가 수집하는 방법 : Volumes에 HostPath 확인
kubectl describe ds fluent-bit -n amazon-cloudwatch
// /var/log에 tree 확인
ssh ec2-user@$N1 sudo tree /var/log
3.3. CloudWatch 로그 확인
신규 터미널 모니터링
1
kubectl logs deploy/nginx -f
부하 발생
1
2
3
yum install -y httpd
ab -c 500 -n 30000 https://nginx.$MyDomain/
관리 콘솔에 CloudWatch 로그 그룹에서 application 로그 그룹을 선택 –> 로그 스트림 필터링 nginx –> ApacheBench 필터링 후 확인합니다.
Log Insight 정보 확인
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Log Insight 컨테이너 이름별 애플리케이션 로그 오류 카운트
// 로그 그룹 선택 : /aws/containerinsights/<CLUSTER_NAME>/application
stats count() as error_count by kubernetes.container_name
| filter stream="stderr"
| sort error_count desc
// 컨테이너 프로세스 강제 종료
kubectl exec deploy/nginx -c nginx -- kill -s SIGINT 1
// 노드에서 컨테이너 에러 카운트
// 로그 그룹 선택 : /aws/containerinsights/<CLUSTER_NAME>/host
fields @timestamp, @message, ec2_instance_id
| filter message like 'level=error' or message like 'level=warning'
| stats count(*) as error_count by ec2_instance_id
3.4. 실습 자원 삭제
실습 종료 후 자원 삭제
1
2
3
4
5
6
7
8
9
10
11
// fluent-bit 삭제
kubectl delete ds fluent-bit -n amazon-cloudwatch && kubectl delete cm fluent-bit-cluster-info -n amazon-cloudwatch && kubectl delete cm fluent-bit-config -n amazon-cloudwatch && kubectl delete sa fluent-bit -n amazon-cloudwatch
// bitnami nginx 삭제
helm uninstall nginx
// 로그 그룹 삭제 : 데이터 플레인
aws logs delete-log-group --log-group-name /aws/containerinsights/$CLUSTER_NAME/application
aws logs delete-log-group --log-group-name /aws/containerinsights/$CLUSTER_NAME/dataplane
aws logs delete-log-group --log-group-name /aws/containerinsights/$CLUSTER_NAME/host
aws logs delete-log-group --log-group-name /aws/containerinsights/$CLUSTER_NAME/performance
Warning: 다음 섹션의 실습을 이어서 진행할 것으로 Amazon EKS 원클릭 배포를 유지합니다. 혹시나 다음 섹션을 진행하지 않을 경우 4장 Amazon EKS 원클릭 배포를 삭제해 주길 바랍니다.
여기까지 4장의 Amazon EKS 로깅 구성하기 실습을 마칩니다.
수고하셨습니다 :)