[EKS Study 7주차] EKS Automation - ACK
- -
CloudNet@ 팀의 가시다님께서 Leading 하시는 AEWS Study 7주차 스터디 내용 정리
이번 포스팅에서는 kubernetes 에서 AWS Resource API 를 다룰 수 있게 해주는 AWS Controller for Kubernetes (ACK) 대해 알아보겠습니다.
1. AWS Controller for Kubernetes (ACK)
AWS 리소스를 kubernetes 에서 직접 정의하고 사용할 수 있게 해주는 오픈소스 도구입니다.
AWS 리소스 관리를 위해 k8s Cluster 밖으로 벗어나는 번거로움을 해결하기 위해 만들어졌습니다.
1.1. ACK 를 통해 사용가능한 AWS 서비스
ACK 가 지원하는 AWS 서비스 문서
23.06.10 기준 현재 총 27가지 서비스를 지원하고 있습니다만,
실제 안정적으로 사용할 수 있는 GA 는 17개 정도로 적긴 합니다.
그래도 EC2, IAM, ECR, Lambda, S3, RDS 등 AWS 에서 보편적으로 자주 사용하는 서비스는 GA 니 간단하게 사용하실 때는 불편함이 없을 것 같습니다.
1.2. 작동 원리
a. k8s user 가 Manifest(CRD) 에 AWS 리소스에 대한 정의를 작성한 후 k8s 의 API Server 호출
b. API Server 는 호출한 User 가 해당 CRD 와 리소스 사용에 대한 권한이 있는 User 인 지 판단
c. 유효한 User 일 경우, API Server 는 etcd 에 해당 CRD 에 대해 기록하고 User 에게 응답
d. etcd 에 기록되는 순간, ACK 컨트롤러가 이를 인지하고 AWS API 와 통신하여 AWS 리소스를 생성
2. ACK for S3 실행
ACK 는 AWS 리소스 마다 개별 Controller 를 가지고 있으며 Helm 으로 간단하게 설치가 가능합니다.
이번 포스팅에서는 S3 버킷을 관리하는 ACK Controller 를 테스트 해보겠습니다.
각각의 ACK Controller Image는 AWS Public ECR 에서 확인하실 수 있습니다.
ACK 의 실행 순서는 컨트롤러에 상관 없이 거의 동일합니다.
a. Helm 설치
b. IRSA 설정
c. AWS 리소스 배포
2.1. S3 ACK 설치
export SERVICE=s3
export RELEASE_VERSION=$(curl -sL https://api.github.com/repos/aws-controllers-k8s/$SERVICE-controller/releases/latest | grep '"tag_name":' | cut -d'"' -f4)
export ACK_SYSTEM_NAMESPACE=ack-system
export AWS_REGION=ap-northeast-2
helm install \
--create-namespace \
-n $ACK_SYSTEM_NAMESPACE ack-$SERVICE-controller \
oci://public.ecr.aws/aws-controllers-k8s/$SERVICE-chart \
--version=$RELEASE_VERSION \
--set=aws.region=$AWS_REGION
2.2. IRSA 설정
ACK S3 Controller 에 권장되는 권한은 AWSS3FullAccess 입니다.
eksctl create iamserviceaccount \
--name ack-$SERVICE-controller \
--namespace ack-system \
--cluster $CLUSTER_NAME \
--attach-policy-arn $(aws iam list-policies --query 'Policies[?PolicyName==`AmazonS3FullAccess`].Arn' --output text) \
--override-existing-serviceaccounts --approve
IRSA 설정이 잘 되었다면 rollout 명령어를 통해 기존 S3 Controller 를 대체해줍니다.
kubectl -n ack-system rollout restart deploy ack-$SERVICE-controller-$SERVICE-chart
2.3. S3 생성
export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)
export BUCKET_NAME=my-ack-s3-bucket-$AWS_ACCOUNT_ID
cat << EOF > bucket.yaml
apiVersion: s3.services.k8s.aws/v1alpha1
kind: Bucket
metadata:
name: $BUCKET_NAME
spec:
name: $BUCKET_NAME
EOF
kubectl apply -f bucket.yaml
버킷 생성 후 AWS 콘솔에서 확인하실 수 있습니다.
ACK 로 생성한 버킷은 아래 명령어로 확인 가능합니다.
kubectl get bucket
2.4. S3 삭제
버킷 삭제는 생성과 마찬가지로 명령어 한 줄로 가능합니다.
kubectl delete -f bucket.yaml
2.5. ACK for S3 삭제
# Helm Uninstall
export SERVICE=s3
helm uninstall -n $ACK_SYSTEM_NAMESPACE ack-$SERVICE-controller
# CRD Remove
kubectl delete -f ~/$SERVICE-chart/crds
# IRSA 제거
eksctl delete iamserviceaccount --cluster myeks --name ack-$SERVICE-controller --namespace ack-system
3. Multi Region 에서의 ACK 사용
ACK 는 Annotation 을 통해 다른 AWS Region에 리소스를 배포할 수 있습니다.
여기서는 버지니아 북부(us-east-1), 서울(ap-northeast-2) 지역에 VPC 를 동시에 배포해보도록 하겠습니다.
3.1. ACK for EC2 설치 (+IRSA)
VPC 를 배포하기 위해서는 EC2 Controller 가 필요합니다.
앞서 실습했던 S3 Controller 와 동일한 순서로 설치를 진행합니다.
export SERVICE=ec2
export RELEASE_VERSION=$(curl -sL https://api.github.com/repos/aws-controllers-k8s/$SERVICE-controller/releases/latest | grep '"tag_name":' | cut -d'"' -f4 | cut -c 2-)
export ACK_SYSTEM_NAMESPACE=ack-system
export AWS_REGION=ap-northeast-2
helm install \
-n $ACK_SYSTEM_NAMESPACE ack-$SERVICE-controller \
oci://public.ecr.aws/aws-controllers-k8s/$SERVICE-chart \
--version=$RELEASE_VERSION \
--set=aws.region=$AWS_REGION
IRSA 도 진행합니다.
eksctl create iamserviceaccount \
--name ack-$SERVICE-controller \
--namespace $ACK_SYSTEM_NAMESPACE \
--cluster $CLUSTER_NAME \
--attach-policy-arn $(aws iam list-policies --query 'Policies[?PolicyName==`AmazonEC2FullAccess`].Arn' --output text) \
--override-existing-serviceaccounts --approve
# Controller 재실행
kubectl -n $ACK_SYSTEM_NAMESPACE rollout restart deploy ack-$SERVICE-controller-$SERVICE-chart
3.2. 리소스 Yaml 에 Annotation 추가
ACK 로 Multi Region 에 리소스를 배포하는 방법은 2가지가 있습니다.
1가지는 리소스 Yaml 에 직접 Region 과 관련한 Annotation 을 추가하는 것이고,
다른 1가지는 k8s Namespace 에 Annotation 을 추가해 Region 을 강제하는 것입니다.
이번에는 리소스 Yaml 파일에 Annotation 을 추가해보겠습니다.
metadata:
annotations:
services.k8s.aws/region: <AWS_REGION>
다음과 같이 us-east-1, ap-northeast-2 에 VPC를 만드는 Yaml 파일을 생성합니다.
cat <<EOF > vpc.yaml
apiVersion: ec2.services.k8s.aws/v1alpha1
kind: VPC
metadata:
name: vpc-ue1
annotations:
services.k8s.aws/region: us-east-1
spec:
cidrBlocks:
- 10.0.0.0/16
enableDNSSupport: true
enableDNSHostnames: true
tags:
- key: Name
value: vpc-ack-ue1
---
apiVersion: ec2.services.k8s.aws/v1alpha1
kind: VPC
metadata:
name: vpc-an2
annotations:
services.k8s.aws/region: ap-northeast-2
spec:
cidrBlocks:
- 10.0.0.0/16
enableDNSSupport: true
enableDNSHostnames: true
tags:
- key: Name
value: vpc-ack-an2
EOF
kubectl apply -f vpc.yaml
배포 후 AWS 콘솔에서 확인해봅니다.
각 리전에 배포된 것을 알 수 있습니다.
다음 실습을 위해 리소스를 삭제합니다.
kubectl delete -f vpc.yaml
3.3. Namespace 에 Annotation 추가
이번에는 Namespace 에 Annotation 을 추가하여 해당 Namespace 에 배포되는 리소스의 리전을 특정해보겠습니다.
만약 ACK 를 사용한다면, 이 방법이 더 유용할 것으로 판단됩니다.
다음과 같이 네임스페이스를 2개 생성하되, 각각 us-east-1 , ap-northeast-2 어노테이션을 달아줍니다.
cat <<EOF > ack-ns.yaml
apiVersion: v1
kind: Namespace
metadata:
name: ue1
annotations:
services.k8s.aws/default-region: us-east-1
---
apiVersion: v1
kind: Namespace
metadata:
name: an2
annotations:
services.k8s.aws/default-region: ap-northeast-2
EOF
kubectl apply -f ack-ns.yaml
kubectl describe ns an2 ue1
VPC 배포
VPC 와 관련된 Yaml 파일을 생성하여 각각의 Namespace 에 배포해봅니다.
cat <<EOF > vpc2.yaml
apiVersion: ec2.services.k8s.aws/v1alpha1
kind: VPC
metadata:
name: vpc-ue1
namespace: ue1
spec:
cidrBlocks:
- 10.0.0.0/16
enableDNSSupport: true
enableDNSHostnames: true
tags:
- key: Name
value: vpc2-ack-ue1
---
apiVersion: ec2.services.k8s.aws/v1alpha1
kind: VPC
metadata:
name: vpc-an2
namespace: an2
spec:
cidrBlocks:
- 10.0.0.0/16
enableDNSSupport: true
enableDNSHostnames: true
tags:
- key: Name
value: vpc2-ack-an2
EOF
kubectl apply -f vpc2.yaml
각 Region 에 배포된 VPC 를 확인해봅니다.
kubectl get vpc -A
실습 후 리소스를 삭제합니다.
kubectl delete -f vpc2.yaml
4 ACK Drift 관리
Terraform 이나 CloudFormation 을 사용하다보면, 실제 AWS 환경과 IaC 코드가 일치하지 않아 문제가 많이 발생합니다.
ACK 를 통해서 AWS 리소스를 생성하고 관리할 때도 Drift 관리가 중요할 것입니다.
k8s 클러스터 외부에서 AWS 리소스의 환경 변화가 있을 때 ACK 가 어떻게 반응하는 지 살펴보겠습니다.
기본적으로 모든 ACK 컨트롤러는 10시간 마다 Drift 를 감지 시도를 진행합니다.
그 후, 사전에 적용된 yaml spec 내용에 따라 원상복구를 시도하게 됩니다.
ACK 컨트롤러의 values.yaml 에서 아래 리소스를 수정하면 Drift 감지 시간을 변경할 수 있습니다.
reconcile:
defaultResyncPeriod: 1800 # 30 minutes (in seconds)
resourceResyncPeriods:
Bucket: 1800 # 30 minutes (in seconds)
참고 문서
- ACK 공식 GitHub
https://github.com/aws-controllers-k8s/community
- EKS Workshop - ACK
https://www.eksworkshop.com/docs/automation/controlplanes/ack/
'AWS > EKS' 카테고리의 다른 글
ECR 멀티 아키텍처 이미지를 활용하여 EKS Graviton 노드 그룹 관리하기 (0) | 2023.08.31 |
---|---|
[AWS/EKS] IAM Group 을 통한 EKS 인증 관리 (0) | 2023.06.03 |
[AWS/EKS] EKS 인증/인가 파헤치기 (4) | 2023.06.02 |
[EKS Study 5주차] EKS AutoScaling - Karpenter (0) | 2023.05.28 |
[EKS Study 5주차] EKS AutoScaling - CA (0) | 2023.05.28 |