안정적 서비스 운영을 위해서는 서비스의 CPU, Memory 등을 모니터링하고 Application Log를 확인하는 것이 중요하다. 이는 kubernetes에서도 마찬가지로서 Cluster, NameSpace, Service, Pod 등에 대한 모니터링과 필요에 따라 Application 로그 수집이 필요하다. 본 포스팅에서는 다양한 모니터링 방법 중에서 AWS에서 제공하는 Container Insights와 로그 수집기인 fluent-bit로 로그를 수집하는 테스트를 진행한다 (kubernetes 모니터링 툴로는 이 외에도 오픈소스인 Prometheus와 Grafana를 통합하여 많이 사용하고있다.)
- Container Insights (모니터링)
- ECS, EKS Cluster에 대하여 CPU, 메모리, 디스크, 네트워크와 같은 많은 리소스에 대한 지표를 자동으로 수집
- CloudWatch agent로 수집된 지표를 사용하여 CloudWatch DashBoard 구성 가능 - Fluent-bit (로깅)
- fluentd보다 메모리를 적게 사용하는 경량화된 로그 수집, 전달자 역할 수행
- 수집된 지표를 다양한 OUTPUT plugin을 통해 CloudWatch logs, ElastiSearch, S3 등으로 전달 가능 (본 포스팅에서는 CloudWatch logs로 전달한다)
본 포스팅에서 구성할 아키텍처는 아래와 같다 (AWS 블로그 참고).
구성 사전조건
- Container Insights를 지원하는 리전에 EKS Cluster가 존재해야 함
- 지원하는 리전 리스트: https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/ContainerInsights.html - kubectl을 사용해야 함 (kubectl 을 사용하여 EKS에 cloudwatch-agent, fluent-bit를 생성함)
- EKS 노드가 CloudWatch로 데이터를 전송할 수 있도록 IAM 권한을 부여해야 함
- Container Insights로의 지표 수집을 위해서 cloudwatch-agent를 DaemonSet 으로 생성한다. 이때 cloudwatch-agent가 Cloudwatch로 지표를 전송하기 위해서는 AWS 관리형 정책인 CloudWatchAgentServerPolicy 가 부여되어야한다.
- AWS에서는 (1) 노드에 적용된 IAM역할에 이 정책을 추가하거나 (2) k8s가 사용할 수 있는 IAM 역할을 생성하고 annotation으로 ServiceAccount와 IAM 역할을 연결하는 방법이 있다. 이 두 방법에는 차이가 존재하지만 본 포스팅에서는 간단히 작업하기위해 (1) 방법을 사용한다.
본 포스팅에서는 Container Insights와 fluent-bit 구성을 나누어 설치하였다. 보다 적은 파일로 관리하고자 할 경우, quick-start.yaml 파일을 받는 방법도 좋다 (https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/Container-Insights-setup-EKS-quickstart.html).
curl -O https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/quickstart/cwagent-fluent-bit-quickstart.yaml
1. IAM 권한 확인
1.1 EKS 노드에 적용되어있는 IAM역할 권한 확인
EKS Cluster > 구성 > 컴퓨팅 > 노드 그룹 > 세부정보 > 노드 IAM 역할 클릭 (EKS 인스턴스 태그를 통해 직접 찾는 방법도 가능함)
1.2 정책 추가
노드에 적용되어있는 IAM 역할에 부여되어있는 권한 정책을 확인한다. CloudWatchAgentServerPolicy가 존재하지 않는다면 해당 정책을 추가한다.
2. Container Insights (cloudwatch-agent) 구성
AWS는 EKS에 CloudWatch agent를 DaemonSet 형태로 생성하여 각 노드에 위치시키는데, 이 CloudWatch agent는 기존 EC2 인스턴스에 설치되는 CloudWatch agent와 달리 logs를 사용한다는 차이가 있다. 따라서 수집된 모니터링 지표는 CloudWatch logs의 /aws/containerinsights/<EKS-CLUSTER-NAME>/performance에 적재된다.
2.1 Cloudwath agent 파일 다운로드
AWS 문서에서는 yaml 다운로드 없이 바로 kubectl과 sed로 처리하지만 본 포스팅에서는 yaml 관리를 위해 다운로드 받아 실행한다.
AWS에서는 모니터링, 로깅을 위하여 다음의 쿠버네티스 객체들을 생성한다.
- NameSpace: amazon-cloudwatch
- ServiceAccount, ClusterRole, ClusterRoleBinding: RBAC를 통한 cloudwatch agent에 권한 부여
- ConfigMap: cwagentconfig, cloudwatch agent config에 수집 Cluster 이름 명시
- DaemonSet: cloudwatch-agent DaemonSet을 생성하여 새로운 노드가 생성될 때 마다 1개씩 위치하도록 함
cloudwatch-namespace.yaml 파일 다운로드
기존에 다른 설정을 통해 해당 namespace가 존재한다면 이 단계는 진행하지 않아도 된다.
curl -O https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/cloudwatch-namespace.yaml
cwagent-serviceaccount.yaml 파일 다운로드
이 파일에는 cloudwatch-agent가 사용할 ServiceAccount를 생성하고 이들에게 부여할 ClusterRole과 ClusterRoleBinding이 설정되어 있다. cloudwatch-agent는 Cluster 내 모든 네임스페이스와 이곳에 존재하는 객체에 대해 모니터링을 수행하므로 ClusterRole이 필요하다.
curl -O https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/cwagent/cwagent-serviceaccount.yaml
(이 부분은 1. IAM 권한 확인을 수행했다면 수정 할 필요 없다)
만일 1. IAM 권한 확인의 노드의 IAM 역할에 정책을 할당하지 않고 ServiceAccount와 IAM 역할을 연결하여 할 경우 annotation을 추가한다.
apiVersion: v1
kind: ServiceAccount
metadata:
name: cloudwatch-agent
namespace: amazon-cloudwatch
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::<AWS-ACCOUNT>:role/<ROLE-NAME>
이 때 해당 역할에는 CloudWatchAgentServerPolicy 권한이 추가되어있어야 한다. 또한, 이 역할의 신뢰 관계 (Trust RelationShip)는 EKS Cluster의 OIDC Provider로 선택하고, 아래와 같이 수정이 필요하다. <CLUSTER-OIDC-PROVIDER>에는 각각 AWS 계정 번호와 EKS Cluster의 OIDC 공급자를 입력한다.
"<CLUSTER-OIDC-PROVIDER>:sub": "system:serviceaccount:amazon-cloudwatch:cloudwatch-agent"
OIDC provider에 대해 신뢰 관계 역할을 생성하는 방법은 다음 포스팅에서 설명하고있다.
2022.01.10 - [AWS/EKS] - [AWS/EKS] 콘솔로 생성하는 EKS - ② EKS Cluster 생성, OIDC 구성
cwagent-config.yaml 파일 다운로드 및 수정
아래의 명령어로 configmap.yaml 파일을 다운받는다.
curl -O https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/cwagent/cwagent-configmap.yaml
cwagent-config.yaml 수정
cloudwatch agent는 지표 수집을 위해 JSON 형식의 파일 (예. cwagentconfig.json)이 필요하며, 이 파일을 configmap에 정의하고있다.
이 중에서 반드시 {{cluster-name}} 부분을 자신의 EKS Cluster 이름으로 수정하여 지표를 수집할 클러스터를 지정한다.
아래 yaml 파일에서 cluster_name 외에 설정되어있는 값은 다음과 같다.
- metrics_collection_interval: 지표를 수집하는 빈도 (default 60초), Kubelet의 기본 cadvisor 수집 간격은 15초이기 때문에 이 값을 15초 미만으로 설정하면 해당 간격만큼 수집되지 않음
- force_flush_interval: CloudWatch Logs로 로그를 보내기 전 배치 처리 간격 (default 5초)
이 외에도 region, endpoint-override 등 설정할 수 있는 값이 존재하며 자세한 내용은 다음 AWS 문서를 참고한다 (https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/Container-Insights-setup-metrics.html).
# create configmap for cwagent config
apiVersion: v1
data:
# Configuration is in Json format. No matter what configure change you make,
# please keep the Json blob valid.
cwagentconfig.json: |
{
"logs": {
"metrics_collected": {
"kubernetes": {
"cluster_name": "MY-EKS-CLUSTER-NAME",
"metrics_collection_interval": 60
}
},
"force_flush_interval": 5
}
}
kind: ConfigMap
metadata:
name: cwagentconfig
namespace: amazon-cloudwatch
cwagent-daemonset.yaml 다운로드
마지막으로 각 노드에서 지표를 수집 할 cloudwatch-agent의 DaemonSet 구성을 다운로드받는다.
curl -O https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/cwagent/cwagent-daemonset.yaml
2.2 kubernetes 객체 생성
cloudwatch agent를 위한 준비가 완료되었으며 다운로드, 수정한 파일로 객체들을 생성한다.
kubectl apply -f cloudwatch-namespace.yaml
kubectl apply -f cwagent-serviceaccount.yaml
kubectl apply -f cwagent-configmap.yaml
kubectl apply -f cwagent-daemonset.yaml
2.3 Container Insights 수집 확인
cloudwatch-agent DaemonSet 까지 생성 후 Container Insights에서 수집된 지표를 확인하기까지 약 10분이 소요된다.
CloudWatch > 인사이트 > Container Insights
3. Fluent-bit 구성
AWS에서는 컨테이너에서 CloudWatch Logs로 로그를 전송하는 방법으로 FluentD, Fluent-bit를 제공한다.
그 중에서 AWS는 Fluent-Bit 사용을 권하고 있으므로 본 포스팅에서는 Fluent-bit를 사용하여 컨테이너의 로그를 CloudWatch logs로 전송하는 방법을 다룬다.
3.1 fluent-bit 구성 파일 다운로드
namespace 생성 (amazon-cloudwatch 네임스페이스 없는 경우 수행)
앞의 2.1에서 amazon-cloudwatch 네임스페이스를 생성했다면 이 단계는 넘어간다.
curl -O https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/cloudwatch-namespace.yaml
configmap/fluent-bit-cluster-info 구성
AWS 문서에서는 다음과 같이 fluent-bit-cluster-info configmap을 생성하는 방법을 제시하고있으며 각 항목은 다음과 같다.
- cluster.name: 클러스터 이름
- http.server: 사용 여부 (On/Off)
- http.port: http 포트 (default 2020)
- read.head: 해당 로그 파일의 가장 처음부터 읽기
- read.tail: 배포된 시점부터 파일에 추가된 데이터부터 읽기
- logs.region: log 저장할 리전
ClusterName=cluster-name
RegionName=cluster-region
FluentBitHttpPort='2020'
FluentBitReadFromHead='Off'
[[ ${FluentBitReadFromHead} = 'On' ]] && FluentBitReadFromTail='Off'|| FluentBitReadFromTail='On'
[[ -z ${FluentBitHttpPort} ]] && FluentBitHttpServer='Off' || FluentBitHttpServer='On'
kubectl create configmap fluent-bit-cluster-info \
--from-literal=cluster.name=${ClusterName} \
--from-literal=http.server=${FluentBitHttpServer} \
--from-literal=http.port=${FluentBitHttpPort} \
--from-literal=read.head=${FluentBitReadFromHead} \
--from-literal=read.tail=${FluentBitReadFromTail} \
--from-literal=logs.region=${RegionName} -n amazon-cloudwatch
만일 이를 yaml 파일로 작성하려면 아래와같다.
# fluent-bit-cluster-info-configmap.yaml
apiVersion: v1
data:
cluster.name: cluster-name
logs.region: cluster-region
http.server: "On"
http.port: "2020"
read.head: "Off"
read.tail: "On"
kind: ConfigMap
metadata:
name: fluent-bit-cluster-info
namespace: amazon-cloudwatch
yaml 파일로 생성하였을 경우, 다음 명령어로 configmap 객체를 생성한다.
kubectl apply -f fluent-bit-cluster-info-configmap.yaml
fluent-bit.yaml 다운로드
AWS에서는 fluent-bit 최적화 구성을 위한 fluent-bit.yaml 파일을 제공하고있으며 다음의 명령어로 다운로드 가능하다.
이 파일에는 다음 kubernetes 객체를 생성하는 내용이 담겨져있다.
- serviceaccount/fluent-bit
- clusterrole.rbac.authorization.k8s.io/fluent-bit-role
- clusterrolebinding.rbac.authorization.k8s.io/fluent-bit-role-binding
- configmap/fluent-bit-config
- daemonset.apps/fluent-bit
$ curl -O 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
이 파일은 아래와 같은 로그들을 수집하고 이를 CloudWatch logs에 로그 그룹화하여 수집한다 (fluent-bit의 config 수정으로 해당 구성 변경 가능).
다음 명령어로 fluent-bit 객체들을 배포할 수 있다.
kubectl apply -f fluent-bit.yaml
fluent-bit 가 정상적으로 생성되고 로그 수집을 시작하면, CloudWatch logs에서 로그 그룹과 각 로그 그룹에 맞는 로그 스트림이 생성된 것을 확인할 수 있다.
만일 일부 로그만 수집하고자한다면, configmap/fluent-bit-config (fluent-bit-cluster-info 와 구별 필요) 을 수정한다. configmap/fluent-bit-config에는 fluent-bit가 수집하는 로그의 소스 (INPUT), 필터 (FILTER), 포맷변환 (PARSER), 로그 전송 목적지 (OUTPUT) 등이 정의되어있다. fluent-bit config의 각 섹션 (INPUT, FILTER, OUTPUT 등)은 다양한 plugin을 제공하고 있으므로 이 값을 적절히 수정함으로써 CloudWatch logs로 수집할 로그 종류, 로그 그룹 이름, 스트림 조정이 가능하다 (이 방법에 대해서는 추후 타 포스팅에서 다루겠다).
본 포스팅에서는 Container Insights (cloudwatch-agent)로 모니터링을, Fluent-bit와 CloudWatch logs로 로그 수집하는 방법을 다루었다. 이 방법은 AWS에서 모니터링, 로그 수집을 모두 할 수 있다는 점에서 장점이 있다. 다만, 지표와 로그가 CloudWatch logs에 저장되므로 해당 로그 그룹의 만기를 정하지않으면 로그가 계속 쌓여 많이 과금될 수 있음을 반드시 알아두는 것이 중요하다 (영구 보존해야하는 로그가 아닌경우 반드시 로그 이벤트 만기를 정하자).
[참고]
https://docs.fluentbit.io/manual/pipeline/outputs/cloudwatch
'AWS > EKS' 카테고리의 다른 글
[EKS/Error] aws-node 동작 안됨 문제 (EKS Node NotReady) (0) | 2022.05.05 |
---|---|
[AWS/EKS] AWS IAM 사용자에 대한 RBAC (Role-based Access Control) 설정하기 (0) | 2022.04.11 |
[AWS/EKS] 콘솔로 생성하는 EKS - ④ ingress로 서비스 외부 노출 시키기 (AWS LoadBalancer Controller 설치) (0) | 2022.03.17 |
[AWS/EKS] 콘솔로 생성하는 EKS - ③ 노드 그룹 생성 (0) | 2022.01.17 |
[AWS/EKS] 콘솔로 생성하는 EKS - ② EKS Cluster 생성, OIDC 구성 (0) | 2022.01.10 |
댓글