AWS resource를 사용하고 있다면 Log 수집에 있어서 Cloudwatch log 기능이 좋은 대안이 될 수 있다.
ELK, EFK 와 같이 Elsaticsearch 기반의 Log 수집 체계도 많이 사용되고 있지만 사용하는데 러닝커브도 존재하고, 추가적인 리소스가 들 수밖에 없다.
Aws Cloudwatch logs 란 Amazon EC2, AWS CloudTrail, Route 53 및 다른 시스템, 애플리케이션 및 사용자 지정 로그 파일을 모니터링, 저장 및 액세스 해주는 기능이다.
로그 데이터 쿼리
Cloudwatch Logs Insights 기능을 사용하여 로그 데이터를 대화식으로 검색하고 분석할 수 있다.
로그 데이터를 통한 알림 기능
로그 데이터를 기반으로 알람을 설정할 수가 있다. 예를 들어 특정 리터럴 문자의 출현 횟수를 계산하여 만들 수도 있다.
로그 리텐션 설멍 및 데이터 아카이브
로그의 리텐션 기간을 설정할 수 있고 Log 데이터를 스토리지에 저장할 수 있도록 추가적인 설정도 가능하다.
활동내역 ( record ) 를 기록한 로그 하나 하나를 의미한다. 단순히 비교하면 특정 File 안에 있는 row 하나하나라고 할 수 있다. Timestamp, raw message 2개의 프로퍼티가 있다.
로그 이벤트의 연속적인 스트림이다. 로그 파일이라고 생각하면 된다.
로그 스트림의 폴더라고 생각하면 된다. 로그 스트림은 로그 그룹의 설정값을 모두 공유한다. ( retention, monitoring, access control etc...)
AWS 에는 기본으로 Elasticbeanstalk ( EB ) 에 대해 Streaming Log를 설정할 것인지 혹은 하지 않을 것인지 Console에서 선택할 수 있다.
하지만 기본적으로 설정돼있는 Log path를 제외하고 추가적인 Custom log group 을 만드는 것은 Console 에서 따로 제공해주지는 않는다.
Custom log group을 만들기 위해서는 awslogs agent 를 따로 설정해서 만들어야한다.
따라서 .ebextention
에 config 파일을 추가하여 EB 의 deploy 세팅을 변경해주어야한다.
.ebextention
는 EB의 configuarion 파일들을 모아 놓은 폴더라고 생각하면 된다.
.ebextention
|__ network-load-balancer.config
|__ taillogd.config
위와 같은 형태로 configuration 을 여러개 추가할 수 있고 알파뱃 순서로 적용된다. 따라서 따로 순서를 정하고 싶다면 00_ 과 같은 방식으로 prefix를 붙이면 configuarion을 원하는 순서대로 적용할 수 있다.
configuration의 format 은 yaml, json 모두 가능하며 aws 공식사이트에서는 yaml 방식을 추천하고 있다.
다양한 option field 값이 존재하고 이는 aws docs를 참고!
.ebextention
에 custom configuration 을 만들고 다음과 같이 적용한다.
packages:
yum:
awslogs: []
files:
"/etc/awslogs/awscli.conf" :
mode: "000755"
owner: root
group: root
content: |
[plugins]
cwlogs = cwlogs
[default]
region = `{"Ref":"AWS::Region"}`
"/etc/awslogs/awslogs.conf" :
mode: "000755"
owner: root
group: root
content: |
[general]
state_file = /var/lib/awslogs/agent-state
"/etc/awslogs/config/logs.conf" :
mode: "000755"
owner: root
group: root
content: |
[/var/log/nginx/datapack/access.log]
log_group_name = `{"Fn::Join":["/", ["/aws/elasticbeanstalk", { "Ref":"AWSEBEnvironmentName" }, "var/log/nginx/datapack/access.log"]]}`
log_stream_name = {instance_id}
file = /var/log/nginx/datapack/access.log
[/var/log/nginx/datapack/error.log]
log_group_name = `{"Fn::Join":["/", ["/aws/elasticbeanstalk", { "Ref":"AWSEBEnvironmentName" }, "var/log/nginx/datapack/error.log"]]}`
log_stream_name = {instance_id}
file = /var/log/nginx/datapack/error.log
[/var/log/uwsgi/access.log]
log_group_name = `{"Fn::Join":["/", ["/aws/elasticbeanstalk", { "Ref":"AWSEBEnvironmentName" }, "var/log/uwsgi/access.log"]]}`
log_stream_name = {instance_id}
file = /var/log/uwsgi/access.log
[/var/log/uwsgi/error.log]
log_group_name = `{"Fn::Join":["/", ["/aws/elasticbeanstalk", { "Ref":"AWSEBEnvironmentName" }, "var/log/uwsgi/error.log"]]}`
log_stream_name = {instance_id}
file = /var/log/uwsgi/error.log
commands:
"01":
command: systemctl enable awslogsd.service
"02":
command: systemctl restart awslogsd
위와 같은 방식으로 /etc/awslogs/config/logs.conf ( awslogs agent 의 configuration 파일 ) 에 생성하고자하는 loggroup의 정보와 그 target path를 작성하고 awslogsd service를 동작시켜서 amazon cloud agent 를 동작시키게 된다.
위와 같은 방식을 통해 custom agent를 설정할 수 있고 이 같은 방식을 통해 기타 EC2 인스턴스에도 설치가 가능하다.
eks 는 aws 에서 제공해주는 sample object를 이용하여서 설정을 해줄 수 있다. 아래 설명 방식은 default 세팅으로 cloudwatch agent 가 Cluster에 설치되게 된다. 추가적인 설정을 해주고 싶다면 바로 apply 시키지 않고 파일을 받고 본인의 입맛대로 설정해주면 된다.
기본 셋팅을 하게 되면 아래와 같은 형태의 Log group이 형성된다.
/aws/containerinsights/Cluster-Name/application
/aws/containerinsights/Cluster-Name/dataplane
/aws/containerinsights/Cluster-Name/host
application 그룹에는 해당 클러스터의 각 container 들의 로그 스트림이 있다. /var/log/containers의 모든 로그 파일
dataplane 그룹에는 kubelet.service, kubeproxy.service, and docker.service에 대한 /var/log/journal의 로그가 있다.
e.g.) docker, kubelet, kube-proxy, aws-node ( AWS EKS 의 기본 CNI ) 등.
host 그룹에는 해당 호스트에서 발생하는 /var/log/dmesg, /var/log/secure, /var/log/messages의 로그가 담겨있다.
namespace를 설정해준다.
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
Cloudwatch 에서 각 Node 모든 namespace의 pod, container 에 접근하기 위해서 ClusterRole을 부여한 Service account를 형성해준다.
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
configmap 파일을 받고 환경세팅을 해준다.
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
# 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": "{{cluster_name}}",
"metrics_collection_interval": 60
}
},
"force_flush_interval": 5
}
}
kind: ConfigMap
metadata:
name: cwagentconfig
namespace: amazon-cloudwatch
daemonset 형태로 Pod를 띄운다. 각 노드 마다 정보를 받아와야 하기 때문에 daemonset 형태로 구성
kubectl apply -f 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
위 설정을 마치면 아래와 같이 확인할 수 있다.
https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/logs/WhatIsCloudWatchLogs.html
https://aws.amazon.com/ko/premiumsupport/knowledge-center/push-log-data-cloudwatch-awslogs/