CloudWatch Container Insights를 사용해 컨테이너식 애플리케이션 및 마이크로서비스의 지표 및 로그를 수집하고 집계하며 요약할 수 있습니다. Container Insights는 Amazon EC2의 Amazon Elastic Container Service(Amazon ECS), Amazon Elastic Kubernetes Service(Amazon EKS) 및 Kubernetes 플랫폼에서 사용할 수 있고 Amazon ECS 지원은 Fargate에 대한 지원을 포함합니다.
이 지표에는 CPU, 메모리, 디스크, 네트워크 같은 리소스 사용률이 포함되어 있습니다. 또한 Container Insights는 컨테이너 재시작 오류 같은 진단 정보를 제공하여 문제를 격리하고 신속하게 해결할 수 있도록 도와줍니다. Container Insights에서 수집한 지표에 대해 CloudWatch 경보를 설정할 수도 있습니다.
Container Insights에서 수집한 지표는 CloudWatch 자동 대시보드에서 사용할 수 있습니다. CloudWatch Logs Insights를 사용해 컨테이너 성능 및 로그를 분석하고 이와 관련해 발생하는 문제를 해결할 수 있습니다.
운영 데이터는 성능 로그 이벤트로서 수집됩니다. 이들은 정형 JSON 스키마를 사용하는 항목이기 때문에 카디널리티가 높은 데이터를 적정 규모로 수집 및 저장할 수 있습니다. 이러한 데이터를 토대로 CloudWatch는 집계 지표를 클러스터, 노드, Pod, 작업 및 서비스 수준에서 CloudWatch 지표로 생성합니다.
Container Insights에서 수집된 지표는 사용자 지정 지표로 청구됩니다. CloudWatch 요금에 대한 자세한 내용은 Amazon CloudWatch 요금을 참조하십시오.
Amazon EKS 및 Kubernetes에서 Container Insights는 컨테이너화된 버전의 CloudWatch 에이전트를 사용하여 클러스터에서 실행 중인 모든 컨테이너를 검색합니다. 이어서 성능 스택의 모든 계층에서 성능 데이터를 수집합니다.
랩에서는 아래와 같은 도구들을 사용하여, 랩을 구성합니다.
Helm : 클러스터에 Wordpress를 설치합니다. (PHP/Nginix 구성을 하셔도 무방합니다.)
CloudWatch Container Insights : 클러스터에서 로그 및 지표를 수집합니다.
Siege : Wordpress 및 EKS Cluster를 로드 테스트합니다.
CloudWatch Container Insights 대시 보드 : 컨테이너 성능 및 로드에 대 시각화합니다.
Role이 Private/Public 2개의 노드입니다. 그중 public node의 role을 "--stack-name" 뒤의 값에 입력합니다. 해당 값을 사용자 bash profile에 입력하고, role 이름을 다시 확인합니다.
PUB_ROLE_NAME=$(aws cloudformation describe-stack-resources --stack-name eksctl-eksworkshop-nodegroup-ng-public-01 | jq -r '.StackResources[] | select(.ResourceType=="AWS::IAM::Role") | .PhysicalResourceId')
MGMD_PUB_ROLE_NAME=$(aws cloudformation describe-stack-resources --stack-name eksctl-eksworkshop-nodegroup-managed-ng-public-01 | jq -r '.StackResources[] | select(.ResourceType=="AWS::IAM::Role") | .PhysicalResourceId')
echo "export PUB_ROLE_NAME=${PUB_ROLE_NAME}" | tee -a ~/.bash_profile
echo "export MGMD_PUB_ROLE_NAME=${PUB_ROLE_NAME}" | tee -a ~/.bash_profile
test -n "$PUB_ROLE_NAME" && echo PUB_ROLE_NAME is "$PUB_ROLE_NAME" || echo PUB_ROLE_NAME is not set
test -n "$MGMD_PUB_ROLE_NAME" && echo MGMD_PUB_ROLE_NAME is "$MGMD_PUB_ROLE_NAME" || echo MGMD_PUB_ROLE_NAME is not set
PRI_ROLE_NAME=$(aws cloudformation describe-stack-resources --stack-name eksctl-eksworkshop-nodegroup-ng-private-01 | jq -r '.StackResources[] | select(.ResourceType=="AWS::IAM::Role") | .PhysicalResourceId')
MGMD_PRI_ROLE_NAME=$(aws cloudformation describe-stack-resources --stack-name eksctl-eksworkshop-nodegroup-managed-ng-private-01 | jq -r '.StackResources[] | select(.ResourceType=="AWS::IAM::Role") | .PhysicalResourceId')
echo "export PRI_ROLE_NAME=${PRI_ROLE_NAME}" | tee -a ~/.bash_profile
echo "export MGMD_PRO_ROLE_NAME=${MGMD_PRI_ROLE_NAME}" | tee -a ~/.bash_profile
test -n "$PRI_ROLE_NAME" && echo PRI_ROLE_NAME is "$PRI_ROLE_NAME" || echo PRI_ROLE_NAME is not set
test -n "$MGMD_PRI_ROLE_NAME" && echo PRI_ROLE_NAME is "$MGMD_PRI_ROLE_NAME" || echo MGMD_PRI_ROLE_NAME is not set
정책(Policy)를 Worker node 의 IAM 역할(Role)에 연결합니다.
aws iam attach-role-policy \
--role-name $PUB_ROLE_NAME \
--policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy
aws iam attach-role-policy \
--role-name $PRI_ROLE_NAME \
--policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy
aws iam attach-role-policy \
--role-name $MGMD_PUB_ROLE_NAME \
--policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy
aws iam attach-role-policy \
--role-name $MGMD_PRI_ROLE_NAME \
--policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy
위의 과정을 IAM 대시보드에서 수행해도 됩니다.
정상적으로 연결되었는지 확인합니다.
aws iam list-attached-role-policies --role-name $PUB_ROLE_NAME | grep CloudWatchAgentServerPolicy || echo 'Policy not found'
aws iam list-attached-role-policies --role-name $PRI_ROLE_NAME | grep CloudWatchAgentServerPolicy || echo 'Policy not found'
aws iam list-attached-role-policies --role-name $MGMD_PUB_ROLE_NAME | grep CloudWatchAgentServerPolicy || echo 'Policy not found'
aws iam list-attached-role-policies --role-name $MGMD_PRI_ROLE_NAME | grep CloudWatchAgentServerPolicy || echo 'Policy not found'
아래와 같은 결과를 확인 할 수 있습니다.
whchoi98:~/environment $ aws iam list-attached-role-policies --role-name $PUB_ROLE_NAME | grep CloudWatchAgentServerPolicy || echo 'Policy not found'
"PolicyName": "CloudWatchAgentServerPolicy",
"PolicyArn": "arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy"
2. Container Insight 설치
다음과 같은 내용을 배포하고 구성합니다.
"Amazon-Cloudwatch" namespace를 만듭니다.
2개의 DaemonSet을 만듭니다. (Cloudwatch-agent, fluentd)
Cloudwatch-agent : Metric을 Cloudwatch로 전송
fluentd : log를 Cloudwatch에 전송.
2개 DaemonSet을 위한 보안 정책적용. (SecurityAccount, ClusterRole, ClusterRoleBinding)
2개 DaemonSet을 위한 ConfigMap
curl -s https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/quickstart/cwagent-fluentd-quickstart.yaml | sed "s/{{cluster_name}}/eksworkshop/;s/{{region_name}}/${AWS_REGION}/" | kubectl apply -f -
kubectl -n amazon-cloudwatch get daemonsets
아래와 같은 결과를 확인 할 수 있습니다.
whchoi:~/environment/myeks (master) $ kubectl -n amazon-cloudwatch get daemonsets
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
cloudwatch-agent 12 12 12 12 12 <none> 27s
fluentd-cloudwatch 12 12 12 12 12 <none> 27s
CloudWatch 대쉬보드 - Container Insight에 접속해서 각 주요 기능을 살펴 봅니다.
Cloudwatch - Container Insight - Resource
Container Insight - container map
Container Insight - Performance Dashboards
3.Load Test 구성.
siege 도구를 통해 HTTP 부하를 테스트 합니다.
Siege(https://www.joedog.org/siege-home/)는 HTTP 부하 테스트와 벤치마킹 유틸리티 입니다. 한번에 복수개의 URL 로 테스트가 가능하고, Basic 인증을 지원하며 HTTP와 HTTPS 프로토콜로 테스트가 가능하는 등 ApacheBench 의 제한을 어느정도 해소 해 줍니다. 또 ApacheBench 와 비슷한 인터페이스를 가지고 있어 다른 툴과의 연계가 자유로운 편입니다. 하지만 Thread 기반으로 구현되어 있어 동시성에 제한이 있으며, 미미할 수 있지만 Context Switching 등으로 인하여 성능에도 영향이 있습니다.
아래와 같이 Cloud9 IDE에 설치합니다. 외부 다른 리눅스나 mac os에서 설치해도 됩니다.
sudo yum -y install siege
아래 결과를 통해 표기된 웹페이지로 URL로 부하를 줍니다.
kubectl -n wordpress get svc my-wordpress
또는 아래 결과를 통해 표기된 웹페이지 URL을 변수에 저장하고 , 사용합니다.
export my_wordpress_url=$(kubectl -n wordpress get svc my-wordpress -o jsonpath="{.status.loadBalancer.ingress[].hostname}")
출력 결과는 아래와 같습니다. EXTERNAL-IP 주소입니다.
whchoi98:~ $ kubectl -n wordpress get svc my-wordpress
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-wordpress LoadBalancer 172.20.162.6 ac4026294517a4cd69df77ce5ebc4547-1003101175.ap-northeast-2.elb.amazonaws.com 80:31492/TCP,443:32711/TCP 138m
whchoi98:~ $ export my_wordpress_url=$(kubectl -n wordpress get svc my-wordpress -o jsonpath="{.status.loadBalancer.ingress[].hostname}")
whchoi98:~ $ echo $my_wordpress_url
ac4026294517a4cd69df77ce5ebc4547-1003101175.ap-northeast-2.elb.amazonaws.com
siege는 아래와 같은 옵션으로 부하를 줄 수 있습니다.
-c : 동시 접속 유 , -t: 부하 시간 -r : 반복 횟수 , -d: 요청시 Delay time , -d : 요청결과 출력, -q: 실시간 수행 출력을 표시 하지 않습니다.