Gasida-서종호
님과악분일상-최성욱
님Jerry-이정훈
님의 노고에 다시한번 🙇 감사드립니다.
7주차의 주제는 EKS Automation 입니다.
ACK를 통해 AWS의 리소스를 yaml을 이용하여 쿠버네티스에서 컨트롤할 수 있는 서비스를 실습해보았습니다. 하지만, 아직은 Drift(선언 후 수동으로 리소스가 변경되었을때) 상태에 대해서 정확하게 추종하지는 못해서 아직까지는 도입에는 쉽지 않을것 같습니다.
EKS 스터디를 하며, Nodeless와 ALB-controller 등 실습했었던 서비스를 종합적으로 적용하여 ArgoCD를 배포하는 과정을 정리하였습니다.
7주간의 짧은 시간이었지만 PKOS 때보다도 더 쿠버네티스 운영에 익숙해진 것 같습니다.
7주차는 임연욱님, 배효성님의 경험 및 기술 공유를 발표하셨습니다.
임연욱님은 EKS Reliability
내용을 상세하게 전달해 주셨습니다. 특히 Multi-region(DR) 예방하는 아키텍처는 당장 도입해도 좋을 정도로 적은 비용으로 재해를 방지할 수 있는 솔루션이었던것 같습니다.
배효성님은 ISMS/ISMS-P 인증심사
에 대해서 상세하게 알려주셨습니다. 심사를 직접 실시하는 직무를 수행하며 일반적으로 각각의 업체에서 놓치기 쉬운 부분을 짚어주셔서 추후 ISMS 인증 심사시 큰 도움이 될 것 같습니다.
두분께 다시한번 감사드립니다
ACK를 이용하여 AWS의 리소스를 쿠버네티스 yaml을 이용하여 관리할 수 있습니다.
EKS에서 ArgoCD를 배포하여 GitOps를 실습해봅니다.
Nodeless Concept과 ALB-controller 등 스터디에서 실습한 내용을 바탕으로 운영 환경을 구성할 수 있습니다.
Amazon EKS 윈클릭 배포 가이드를 참조하여 실습에 필요한 인프라 구성요소를 간편하게 배포할 수 있습니다.
ACK
: aws 서비스 리소스를 k8s 에서 직접 정의하고 사용 할 수 있음예시) 사용자는 kubectl (쿠버네티스 api) 를 사용하여 AWS S3 버킷을 생성 할 수 있다
예시) 쿠버네티스 api 는 ack-s3-controller 에 요청을 전달하고, ack-s3-controller(IRSA)이 AWS S3 API 를 통해 버킷을 생성하게 됩니다
출처 - https://aws-controllers-k8s.github.io/community/docs/community/how-it-works/
ACK 가 지원하는 AWS 서비스
: (‘23.5.29일) 현재 17개 서비스는 GA General Availability (정식 출시) 되었고, 10개는 Preview (평가판) 상태입니다 - 링크
Permissions : k8s api 와 aws api 의 2개의 RBAC 시스템 확인, 각 서비스 컨트롤러 파드는 AWS 서비스 권한 필요 ← IRSA role for ACK Service Controller
출처 - https://aws-controllers-k8s.github.io/community/docs/user-docs/authorization/
서비스 별 ACK Controller 설치(w/Helm) 과 IAM Permissions 설정은 서비스 이름만 변수(예. SERVICE=s3 혹은 SERVICE=rds) 에 지정해서 CMD 복사/붙여넣기 하자
S3
- ACK S3 Controller 설치 with Helm
# 서비스명 변수 지정 export SERVICE=s3 # helm 차트 다운로드 #aws ecr-public get-login-password --region us-east-1 | helm registry login --username AWS --password-stdin public.ecr.aws 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-) helm pull oci://public.ecr.aws/aws-controllers-k8s/$SERVICE-chart --version=$RELEASE_VERSION tar xzvf $SERVICE-chart-$RELEASE_VERSION.tgz # helm chart 확인 tree ~/$SERVICE-chart # ACK S3 Controller 설치 export ACK_SYSTEM_NAMESPACE=ack-system export AWS_REGION=ap-northeast-2 helm install --create-namespace -n $ACK_SYSTEM_NAMESPACE ack-$SERVICE-controller --set aws.region="$AWS_REGION" ~/$SERVICE-chart # 설치 확인 helm list --namespace $ACK_SYSTEM_NAMESPACE kubectl -n ack-system get pods kubectl get crd | grep $SERVICE buckets.s3.services.k8s.aws 2022-04-24T13:24:00Z kubectl get all -n ack-system kubectl describe sa -n ack-system ack-s3-controller
- IRSA 설정 : 권장 정책 AmazonS3FullAccess - 링크
# Create an iamserviceaccount - AWS IAM role bound to a Kubernetes service account 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 # 확인 >> 웹 관리 콘솔에서 CloudFormation Stack >> IAM Role 확인 eksctl get iamserviceaccount --cluster $CLUSTER_NAME # Inspecting the newly created Kubernetes Service Account, we can see the role we want it to assume in our pod. kubectl get sa -n ack-system kubectl describe sa ack-$SERVICE-controller -n ack-system # Restart ACK service controller deployment using the following commands. kubectl -n ack-system rollout restart deploy ack-$SERVICE-controller-$SERVICE-chart # IRSA 적용으로 Env, Volume 추가 확인 kubectl describe pod -n ack-system -l k8s-app=$SERVICE-chart ...
- S3 버킷 생성, 업데이트, 삭제
# [터미널1] 모니터링 watch -d aws s3 ls # S3 버킷 생성을 위한 설정 파일 생성 export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text) export BUCKET_NAME=my-ack-s3-bucket-$AWS_ACCOUNT_ID read -r -d '' BUCKET_MANIFEST <<EOF apiVersion: s3.services.k8s.aws/v1alpha1 kind: Bucket metadata: name: $BUCKET_NAME spec: name: $BUCKET_NAME EOF echo "${BUCKET_MANIFEST}" > bucket.yaml cat bucket.yaml | yh # S3 버킷 생성 aws s3 ls kubectl create -f bucket.yaml bucket.s3.services.k8s.aws/my-ack-s3-bucket-<my account id> created # S3 버킷 확인 aws s3 ls kubectl get buckets kubectl describe bucket/$BUCKET_NAME | head -6 Name: my-ack-s3-bucket-<my account id> Namespace: default Labels: <none> Annotations: <none> API Version: s3.services.k8s.aws/v1alpha1 Kind: Bucket aws s3 ls | grep $BUCKET_NAME 2022-04-24 18:02:07 my-ack-s3-bucket-<my account id> # S3 버킷 업데이트 : 태그 정보 입력 read -r -d '' BUCKET_MANIFEST <<EOF apiVersion: s3.services.k8s.aws/v1alpha1 kind: Bucket metadata: name: $BUCKET_NAME spec: name: $BUCKET_NAME tagging: tagSet: - key: myTagKey value: myTagValue EOF echo "${BUCKET_MANIFEST}" > bucket.yaml # S3 버킷 설정 업데이트 실행 : 필요 주석 자동 업뎃 내용이니 무시해도됨! kubectl apply -f bucket.yaml # S3 버킷 업데이트 확인 kubectl describe bucket/$BUCKET_NAME | grep Spec: -A5 Spec: Name: my-ack-s3-bucket-<my account id> Tagging: Tag Set: Key: myTagKey Value: myTagValue # S3 버킷 삭제 kubectl delete -f bucket.yaml # verify the bucket no longer exists kubectl get bucket/$BUCKET_NAME aws s3 ls | grep $BUCKET_NAME
- ACK S3 Controller 삭제 - 링크
# helm uninstall export SERVICE=s3 helm uninstall -n $ACK_SYSTEM_NAMESPACE ack-$SERVICE-controller # ACK S3 Controller 관련 crd 삭제 kubectl delete -f ~/$SERVICE-chart/crds # IRSA 삭제 eksctl delete iamserviceaccount --cluster myeks --name ack-$SERVICE-controller --namespace ack-system # namespace 삭제 >> ACK 모든 실습 후 삭제 kubectl delete namespace $ACK_K8S_NAMESPACE
이전 글들과 연계되는 내용입니다.
1. [eks]Nodeless Concept
2. [pkos] 쿠버네티스 스터디 - 4주차 [Step 03. ArgoCD]
ArgoCD란?
Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes.
Application definitions, configurations, and environments should be declarative and version controlled. Application deployment and lifecycle management should be automated, auditable, and easy to understand.
ArgoCD는 원하는 애플리케이션 상태를 정의하기 위한 소스로 Git 리포지토리를 사용하는 GitOps 패턴을 따릅니다.
EKS 환경에서 ArgoCD를 배포하고 사용합니다.
달성하고자 하는 목표는 다음과 같습니다.
ArgoCD 파드 Fargate에 배포
ALB-Controller를 이용하여 ALB(Ingress) 생성
👉 Step 01. Helm 설치
# 설치 helm repo add argo https://argoproj.github.io/argo-helm helm repo update helm install argocd argo/argo-cd --set server.service.type=NodePort --namespace argocd --version 5.19.14 CERT_ARN=`aws acm list-certificates --query 'CertificateSummaryList[].CertificateArn[]' --output text` MyDomain=xgro.be ALB_NAME=$CLUSTER-ingress-alb ALB_GROUP_NAME=aews echo $CERT_ARN $MyDomain $ALB_NAME $ALB_GROUP_NAME
👉 Step 02. gRPC 및 https 라우팅을 위한 svc, ingress 생성
❗ 주의
spec.alb.ingress.kubernetes.io/backend-protocol-version: HTTP2 설정시 에러 발생gRPC 대신, HTTP2를 사용하여
argogrpc
서비스를 생성하면 타겟그룹이unhealthy
가 됩니다.ArgoCD는 CLI를 통한 통신에는 gRPC를 사용하고, UI는 https를 사용합니다.
요청에 따라 트래픽을 전달하기 위해서, gRPC 전용 서비스와 ALB 생성을 위한 Ingress를 각각 생성합니다.
cat <<EOT | kubectl apply -f - apiVersion: v1 kind: Service metadata: annotations: alb.ingress.kubernetes.io/backend-protocol-version: GRPC #This tells AWS to send traffic from the ALB using HTTP2. Can use GRPC as well if you want to leverage GRPC specific features labels: app: argogrpc name: argogrpc namespace: argocd spec: ports: - name: "443" port: 443 protocol: TCP targetPort: 8080 selector: app.kubernetes.io/name: argocd-server sessionAffinity: None type: NodePort EOT
cat <<EOT | kubectl apply -f - apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: alb.ingress.kubernetes.io/backend-protocol: HTTPS # Use this annotation (which must match a service name) to route traffic to HTTP2 backends. alb.ingress.kubernetes.io/conditions.argogrpc: | [{"field":"http-header","httpHeaderConfig":{"httpHeaderName": "Content-Type", "values":["application/grpc"]}}] alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]' alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN alb.ingress.kubernetes.io/load-balancer-name: $ALB_NAME alb.ingress.kubernetes.io/group.name: $ALB_GROUP_NAME alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/target-type: ip name: argocd namespace: argocd spec: ingressClassName: alb rules: - host: argocd.$MyDomain http: paths: - path: / backend: service: name: argogrpc port: number: 443 pathType: Prefix - path: / backend: service: name: argocd-server port: number: 443 pathType: Prefix tls: - hosts: - argocd.$MyDomain EOT
위의 서비스와 인그레스를 각각 배포하면, 아래와 같이 로드밸런서가 생성되며 타겟그룹이
Healthy
상태로 정상 작동하는것을 확인할 수 있습니다.
👉 Step 03. admin 계정의 암호 확인 및 로그인
정상적으로 배포가 완료되었다면, 아래 커맨드를 이용해서 Argocd의 초기 admin 비밀번호를 확인할 수 있습니다.# admin 계정의 암호 확인 ARGOPW=$(kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d) echo $ARGOPW mf8bOtNEq7iHMqq1
# 웹 접속 로그인 (아이디: admin) ALB의 DNS 주소로 접속 https echo -e "Argocd Web URL = https://argocd.$MyDomain"
실습에는 Github Repo를 사용하였습니다.
실습 진행을 위한 준비사항으로 아래 순서에 따라 진행합니다.
👉 Step 01. Private Repository를 생성
👉 Step 02. nginx.yaml 업로드
nginx를 배포해서 ArgoCD의 기능을 확인합니다.cat << EOT > nginx.yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: selector: matchLabels: app: nginx replicas: 1 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 provision: karpenter --- apiVersion: v1 kind: Service metadata: name: nginx-svc labels: app: nginx spec: ports: - port: 80 protocol: TCP selector: app: nginx EOT
👉 Step 03. 토큰 발급
Settings
/Developer Settings
에서 Repo 접근을 위한 Token을 발급합니다.
👉 Step 04. 리소스 등록
ArgoCD CLI 또는 UI를 이용하여 nginx 레포를 등록합니다.
참조 - 악분의 ArgoCD 공부기록
앞서 Karpenter를 미리 배포하였으므로, ArgoCD에 의해 등록된 리소스(nginx)는 Karpenter에 의해 생성되는 노드에서 배포되는것을 확인할 수 있습니다.