본문 바로가기!

EKS

[EKS] CI/CD (Jenkins, ArgoCD)

728x90
반응형
  • Jenkins
    • CI/CD(Continuous Integration and Continuous Delivery)에 널리 사용되는 오픈 소스 자동화 서버입니다.
    • 수백 개의 플러그인을 사용하여 빌드, 테스트 및 배포와 같은 개발 파이프라인의 다양한 단계를 자동화하여 사실상 모든 프로젝트를 구축하고 테스트할 수 있도록 지원합니다.
    • Jenkins는 개발 프로세스에 대한 지속적인 피드백과 가시성을 용이하게 하여 팀이 문제를 조기에 감지하고 업데이트를 보다 효율적으로 배포할 수 있습니다.
  • ArgoCD
    • GitOps 방법론을 따르는 선언적인 Kubernetes 네이티브 연속 전달 도구입니다. Git 리포지토리에 애플리케이션 리소스를 정의하여 애플리케이션의 라이프사이클을 보다 제어되고 예측 가능한 방식으로 관리할 수 있습니다.
    • ArgoCD는 이러한 리포지토리를 지속적으로 모니터링하고 Kubernetes에 있는 애플리케이션의 상태가 Git에 정의된 원하는 상태와 일치하는지 확인합니다.
    • 이 접근 방식은 배포 프로세스에 대한 수동 개입을 줄이고 애플리케이션 배포에 대한 신뢰성과 보안을 높일 수 있습니다.

 

1.  ECR (w. Terraform)

1-1)  Terraform Code를 통한 ECR 배포

resource "aws_ecr_repository" "ecr_app_repo" {
  name                 = var.ecr_name
  image_tag_mutability = "MUTABLE"

  image_scanning_configuration {
    scan_on_push = true
  }
  force_delete = true
}

 

1-2)  Ubuntu Image Pull

# ubuntu 이미지 다운로드
docker pull ubuntu:20.04
docker images

 

1-3)  Dockerfile을 통한 Docker build 테스트

# 실습을 위한 디렉터리 생성 및 이동
mkdir -p /root/myweb && cd /root/myweb

# Dockerfile 파일 생성
vi Dockerfile
FROM ubuntu:20.04
ENV TZ=Asia/Seoul VERSION=1.0.0 NICK=<자신의 닉네임>
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone && \
    sed -i 's/archive.ubuntu.com/mirror.kakao.com/g' /etc/apt/sources.list && \
    sed -i 's/security.ubuntu.com/mirror.kakao.com/g' /etc/apt/sources.list && \
    apt-get update && apt-get install -y apache2 figlet && \
    echo "$NICK Web Server $VERSION<br>" > /var/www/html/index.html && \
    echo "<pre>" >> /var/www/html/index.html && \
    figlet AEWS Study >> /var/www/html/index.html && \
    echo "</pre>" >> /var/www/html/index.html
EXPOSE 80
CMD ["usr/sbin/apache2ctl", "-DFOREGROUND"]

 

# 이미지 빌드
cat Dockerfile
docker build -t myweb:v1.0.0 .
docker images
docker image history myweb:v1.0.0
docker image inspect myweb:v1.0.0 | jq

# 컨테이너 실행
docker run -d -p 80:80 --rm --name myweb myweb:v1.0.0
docker ps
curl localhost

# 웹 접속 확인
curl -s ipinfo.io/ip | awk '{ print "myweb = http://"$1"" }'

 

1-4)  Build된 이미지를 ECR에 Push

aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin {AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-2.amazonaws.com

docker tag myweb:v1.0.0 {AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-2.amazonaws.com/ecr-repo-for-app:v1.0.0
docker images

docker push {AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-2.amazonaws.com/ecr-repo-for-app:v1.0.0

 

1-5)  ECR에 Push된 이미지로 애플리케이션 배포 테스트

docker rmi {AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-2.amazonaws.com/ecr-repo-for-app:v1.0.0
docker images

 

ECR_REPO={AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-2.amazonaws.com/ecr-repo-for-app
docker run -d -p 80:80 --rm --name myweb $ECR_REPO:v1.0.0
docker ps

 

 

2.  Jenkins

2-1)  Jenkins 설치 및 설정

# 실습 편리를 위해서 root 계정 전환
sudo su -

# Add required dependencies for the jenkins package
# https://docs.aws.amazon.com/corretto/latest/corretto-17-ug/amazon-linux-install.html
sudo yum install fontconfig java-17-amazon-corretto -y
java -version
alternatives --display java
JAVA_HOME=/usr/lib/jvm/java-17-amazon-corretto.x86_64
echo $JAVA_HOME

 

# 젠킨스 설치
sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key
sudo yum upgrade
sudo yum install jenkins -y
sudo systemctl daemon-reload
sudo systemctl enable jenkins && sudo systemctl start jenkins   # 다소 시간 걸림
sudo systemctl status jenkins

 

# 초기 암호 확인
sudo systemctl status jenkins
cat /var/lib/jenkins/secrets/initialAdminPassword

# 접속 주소 확인 
curl -s ipinfo.io/ip | awk '{ print "Jenkins = http://"$1":8080" }'

 

 

  • 초기 암호 입력

 

 

 

 

  • 관리자 계정 설정

 

 

  • 설정 완료 후 젠킨스 접속
    • item : 젠킨스에서 사용하는 작업의 최소 단위
    • 사람 : 계정 관련
    • Jenkins 관리 : 전역 설정 등

 

 

2-2)  First-Project 생성 테스트

  • Jenkins 관리 → Tools 진입

 

 

  • JDK installations : jdk-17 , /usr/lib/jvm/java-17-amazon-corretto.x86_64 → Save

 

  • 첫번째 Item(Project) 생성
    • 새로운 Item 클릭 → Name : First-Project , Freestyle project ⇒ 하단 OK 클릭

 

 

  • Build Steps → Add build step ⇒ Execute shell 클릭

 

  • 간단한 문장 출력 될 수 있게 입력 : echo "Aws Workshop Study" → 하단 Apply 후 저장

 

  • 지금 빌드 클릭하여 생성 확인 및 'Console Output'확인

 

 

  • 콘솔 출력 확인 : 하단에 SUCCESS 확인

 

  • Build Steps → Execute shell 에 'whoami' 및 'touch hello.txt' 추가

 

  • 다시 빌드 후 콘솔 출력 확인

 

 

  • Item(Job) 프로젝트 디텍토리 확인 : 혹은 젠킨스 작업 공간 확인

 

 

2-3)  Docker-Project 생성 테스트 (w. ECR)

  • jenkins 유저로 docker 사용 가능하게 설정
# jenkins 유저로 docker 사용 가능하게 설정
grep -i jenkins /etc/passwd
usermod -s /bin/bash jenkins
grep -i jenkins /etc/passwd

# jenkins 유저 전환
su - jenkins
whoami
pwd
docker info
exit

#
chmod 666 /var/run/docker.sock
usermod -aG docker jenkins

# Jeknins 유저로 확인
su - jenkins
docker info

 

 

  • ECR 로그인 후 Dockerfile 생성
# ECR 로그인 하기
aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin {AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-2.amazonaws.com

# myweb:v2.0.0 컨테이너 이미지 생성을 위한 Dockerfile 준비
# 실습을 위한 디렉터리 생성 및 이동
mkdir -p ~/myweb2 && cd ~/myweb2

# Dockerfile 파일 생성
vi Dockerfile
FROM ubuntu:20.04
ENV TZ=Asia/Seoul VERSION=2.0.0 NICK=leejunho
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone && \
    sed -i 's/archive.ubuntu.com/mirror.kakao.com/g' /etc/apt/sources.list && \
    sed -i 's/security.ubuntu.com/mirror.kakao.com/g' /etc/apt/sources.list && \
    apt-get update && apt-get install -y apache2 figlet && \
    echo "$NICK Web Server $VERSION<br>" > /var/www/html/index.html && \
    echo "<pre>" >> /var/www/html/index.html && \
    figlet AEWS Study >> /var/www/html/index.html && \
    echo "</pre>" >> /var/www/html/index.html
EXPOSE 80
CMD ["usr/sbin/apache2ctl", "-DFOREGROUND"]

 

 

  • Docker-Project 생성

 

 

  • 3개의 Execute shell을 다음과 같이 입력
# 첫번째 Execute shell에 입력
cd /var/lib/jenkins/myweb2
docker build -t myweb:v2.0.0 .
docker tag myweb:v2.0.0 {AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-2.amazonaws.com/ecr-repo-for-app:v2.0.0
docker push {AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-2.amazonaws.com/ecr-repo-for-app:v2.0.0

# 번째 Execute shell에 입력
docker rmi {AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-2.amazonaws.com/ecr-repo-for-app:v2.0.0
docker images

# 세번째 Execute shell에 입력
aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin 544093516502.dkr.ecr.ap-northeast-2.amazonaws.com
ECR_REPO={AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-2.amazonaws.com/ecr-repo-for-app
docker run -d -p 80:80 --rm --name myweb $ECR_REPO:v2.0.0

 

 

  • 지금 빌드 클릭

 

 

  • Jenkins 서버에서 정상적으로 ECR의 이미지를 통해 애플리케이션이 배포되었는지 확인

 

 

 

2-5)  Trigger-Project 생성 테스트 (w. GitHub)

 

  • Trigger-Project 생성

 

 

  • 빌드 매개변수 : String
    • 변수명(VERSION), Default Vault(v1.0.0)
    • 변수명(NICK), Default Vault(<자신의 계정명>)

 

 

  • 소스 코드 관리 : Git
    • Repo URL : https://github.com/**<자신의 계정명>**/aews-cicd
    • Branch : */main
    • Additional Behaviours → Sparse Checkout paths (Path) : 1

 

 

  • 빌드 유발 : Poll SCM (* * * * *)

 

  • Build Steps : Execute shell
# 첫번째 Execute shell 입력
cd /var/lib/jenkins/myweb2
rm -rf Dockerfile
wget https://github.com/junhoee/aews-cicd/blob/main/1/Dockerfile

# 두번째 Execute shell 입력
cd ./1
docker build -t myweb:$VERSION .
docker run -d -p 80:80 --rm --name myweb myweb:$VERSION

 

 

  • 자신의 Github Repo 1 에서 Dockerfile에 VERSION 정보를 수정 후 Commit → 1분 정도 후에 젠킨스에서 확인

 

  • 자동의 repo의 commit을 트리거하여 build가 진행됨을 확인

 

 

  • 파라미터와 함께 빌드 클릭 → 아래 입력 후 확인

 

 

2-6)  Jenkins with Kubernetes

  • Jenkins 에서 k8s 사용을 위한 사전 준비
# jenkins 사용자에서 아래 작업 진행
whoami
mkdir ~/.kube

# root 계정에서 아래 복사 실행
cp ~/.kube/config /var/lib/jenkins/.kube/config
chown jenkins:jenkins /var/lib/jenkins/.kube/config

# jenkins 사용자에서 aws eks 사용(sts 호출 등)을 위한 자격증명 설정
aws configure
AWS Access Key ID [None]: AKIA5ILF2###
AWS Secret Access Key [None]: ###
Default region name [None]: ap-northeast-2

# jenkins 사용자에서 kubectl 명령어 사용 확인
kubectl get pods -A

 

 

  • 파이프라인으로 디플로이먼트/서비스 배포
  • k8s-1 이름으로 pipeline item 생성

 

  • 아래와 같이 pipeline 구성 후 저장
    • ECR_REPO_NAME에는 자신의 ECR Repo 이름을 입력합니다.
pipeline {
    agent any

    tools {
        jdk 'jdk-17'
    }

    environment {
        ECR_REPO_NAME = '{AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-2.amazonaws.com/ecr-repo-for-app'
        GITHUB_URL = 'https://github.com/junhoee/aews-cicd.git'
        DIR_NUM = '3'
    }

    stages {
        stage('Container Build') {
            steps {	
                // 릴리즈파일 체크아웃
                checkout scmGit(branches: [[name: '*/main']], 
                    extensions: [[$class: 'SparseCheckoutPaths', 
                    sparseCheckoutPaths: [[path: "/${DIR_NUM}"]]]], 
                    userRemoteConfigs: [[url: "${GITHUB_URL}"]])

                // 컨테이너 빌드 및 업로드
                sh "docker build -t ${ECR_REPO_NAME}:v1.0.0 ./${DIR_NUM}"
                sh "docker push ${ECR_REPO_NAME}:v1.0.0"
            }
        }

        stage('K8S Deploy') {
            steps {
                sh "kubectl apply -f ./${DIR_NUM}/deploy/deployment-svc.yaml"
            }
        }
    }
}

 

 

  • 포크 받은 Repo의  3/deploy/deployment-svc.yaml 파일에 ECR의 image를 받아올수있게 해당 부분 수정

 

 

  • 빌드 테스트

 

 

  • 접속 테스트용 파드 생성 및 애플리케이션 호출 테스트

 

 

 

3.  ArgoCD

https://argo-cd.readthedocs.io/en/stable/

 

 

  • API Server : Web UI 대시보드, k8s api 처럼 API 서버 역할
    • API 서버는 웹 UI, CLI 및 CI/CD 시스템에서 소비되는 API를 노출하는 gRPC/REST 서버입니다.
    • It has the following responsibilities
      • 응용프로그램 관리 및 상태 보고
      • 응용 프로그램 작업(예: 동기화, 롤백, 사용자 정의 작업) 호출
      • 저장소 및 클러스터 자격 증명 관리(K8s 비밀로 저장)
      • 외부 ID 공급자에게 인증 및 인증 위임
      • RBAC 시행
      • Git 웹 훅 이벤트에 대한 listener/forwarder
  • Repository Server : Git 연결 및 배포할 yaml 생성
    • 리포지토리 서버는 애플리케이션 매니페스트를 보유하고 있는 Git 리포지토리의 로컬 캐시를 유지하는 내부 서비스입니다.
    • 다음 입력이 제공될 때 Kubernetes 매니페스트를 생성하고 반환하는 역할을 합니다:
      • repository URL
      • revision (commit, tag, branch)
      • application path
      • template specific settings: parameters, helm values.yaml
  • Application Controller : k8s 리소스 모니터링, Git과 비교
    • 애플리케이션 컨트롤러는 Kubernetes 컨트롤러로 실행 중인 애플리케이션을 지속적으로 모니터링하고 현재 라이브 상태를 원하는 대상 상태와 비교합니다(repo에 지정된 대로).
    • OutOfSync는 애플리케이션 상태를 감지하고 선택적으로 수정 조치를 취합니다. 라이프사이클 이벤트(PreSync, Sync, PostSync)에 대한 사용자 정의 후크를 호출하는 역할을 합니다
  • Redis : k8s api와 git 요청을 줄이기 위한 캐싱
  • Notification : 이벤트 알림, 트리거
  • Dex : 외부 인증 관리
  • ApplicationSet Controller : 멀티 클러스터를 위한 App 패키징 관리

 

  • 기능
    • 지정된 대상 환경에 애플리케이션을 자동으로 배포
    • 다중 구성 관리/템플릿 도구 지원(Kustomize, Helm, Jsonnet, plane-YAML)
    • 여러 클러스터를 관리하고 구축할 수 있는 기능
    • SSO 통합(OIDC, OAuth2, LDAP, SAML 2.0, GitHub, GitLab, Microsoft, LinkedIn)
    • 인가를 위한 멀티 테넌시 및 RBAC 정책
    • Git 저장소에서 커밋된 모든 애플리케이션 구성으로 롤백/롤백/어떠한 곳에서도 실행
    • 애플리케이션 리소스의 상태 분석
    • 자동화된 구성 드리프트 감지 및 시각화
    • 애플리케이션을 원하는 상태로 자동 또는 수동으로 동기화
    • 응용프로그램 활동의 실시간 보기를 제공하는 웹 UI
    • 자동화 및 CI 통합을 위한 CLI
    • 웹후크 통합(GitHub, BitBucket, GitLab)
    • 자동화를 위한 토큰 액세스
    • 복잡한 애플리케이션 롤아웃(예: Blue/Green 및 카나리아 업그레이드)을 지원하는 PreSync, Sync, PostSync 후크
    • 애플리케이션 이벤트 및 API 호출에 대한 감사 추적
    • 프로메테우스 메트릭
    • Git에서 helm 매개변수를 재정의하기 위한 매개변수 재정의

 

 

3-1)  ArgoCD 설치

  • helm 설치
# 사용 리전의 개인 도메인 인증서 ARN 확인 
MyDomain=junholee.site
CERT_ARN=$(aws acm list-certificates --query "CertificateSummaryList[?DomainName=='${MyDomain}'].CertificateArn" --output text)
echo $CERT_ARN

# 도메인 확인
echo $MyDomain

# LB Subnet ID 
subnet1=subnet-0d836f49cf6fdccf2
subnet2=subnet-04c86db47ab12383e
subnet3=subnet-0347585c270752e08

# helm 설치
cat <<EOT > argocd-values.yaml
global:
  domain: argocd.$MyDomain

configs:
  params:
    server.insecure: true

controller:
  metrics:
    enabled: true
    serviceMonitor:
      enabled: true

server:
  ingress:
    enabled: true
    controller: aws
    ingressClassName: alb
    hostname: "argocd.$MyDomain"
    annotations:
      alb.ingress.kubernetes.io/scheme: internet-facing
      alb.ingress.kubernetes.io/target-type: ip
      alb.ingress.kubernetes.io/subnets: $subnet1, $subnet2, $subnet3
      alb.ingress.kubernetes.io/backend-protocol: HTTP
      alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":80}, {"HTTPS":443}]'
      alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
      alb.ingress.kubernetes.io/ssl-redirect: '443'
      external-dns.alpha.kubernetes.io/hostname: argocd.$MyDomain
    aws:
      serviceType: ClusterIP
      backendProtocolVersion: GRPC
  metrics:
    enabled: true
    serviceMonitor:
      enabled: true

repoServer:
  metrics:
    enabled: true
    serviceMonitor:
      enabled: true

applicationSet:
  metrics:
    enabled: true
    serviceMonitor:
      enabled: true

notifications:
  metrics:
    enabled: true
    serviceMonitor:
      enabled: true
EOT

kubectl create ns argocd
helm repo add argo https://argoproj.github.io/argo-helm
helm install argocd argo/argo-cd --version 6.7.11 -f argocd-values.yaml --namespace argocd

 

  • 생성 확인
# 확인
kubectl get ingress,pod,svc -n argocd
kubectl get crd | grep argo

 

  • 최초 접속 암호 확인 및 최초 접속 테스트
    • https://argocd.<자신의도메인> admin / <최초 접속 암호>
    • (옵션) 로그인 후 User info → UPDATE PASSWORD 변경 가능
# 최초 접속 암호 확인
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d ;echo

 

 

 

3-2) App 배포 with Directory

  • App 생성 : New App 클릭

 

  • Application Name : first-myweb
  • Project Name : default
  • SYNC POLICY : Manual
    • AUTO-CREATE NAMESPACE : 클러스터에 네임스페이스가 없을 시 argocd에 입력한 이름으로 자동 생성
    • APPLY OUT OF SYNC ONLY : 현재 동기화 상태가 아닌 리소스만 배포
  • PRUNE PROPAGATION POLICY
    • foreground : 부모(소유자, ex. deployment) 자원을 먼저 삭제함
    • background : 자식(종속자, ex. pod) 자원을 먼저 삭제함
    • orphan : 고아(소유자는 삭제됐지만, 종속자가 삭제되지 않은 경우) 자원을 삭제함
  • [체크] AUTO-CREATE-NAMESPACE

 

 

  • SOURCE
    • Repository URL : https://github.com/junhoee/aews-cicd
    • Revision : main
    • Path : 3/deploy
  • DESTINATION
    • Cluster URL : https://kubernetes.default.svc
    • Namespace : first
    • [선택] Directory ← 소스를 보고 자동으로 유형 선택됨
  • 화면 상단 [CREATE] 클릭

 

 

  • 배포하기 - [SYNC] 클릭 > [SYNCHRONIZE] 클릭
    • PRUNE : GIt에서 자원 삭제 후 배포시 K8S에서는 삭제되지 않으나, 해당 옵션을 선택하면 삭제시킴
    • FORCE : --force 옵션으로 리소스 삭제
    • APPLY ONLY : ArgoCD의 Pre/Post Hook은 사용 안함 (리소스만 배포)
    • DRY RUN : 테스트 배포 (배포에 에러가 있는지 한번 확인해 볼때 사용)

 

 

  • 리소스 클릭 후 확인 : 각각 LIVE MANIFEST(쿠버네티스 정보) vs DESIRED MANIFEST(Git깃 정보)
  • 1) Deployment 리소스 직접 수정 해보기 : EDIT 클릭 후 lables 아래 추가 → SAVE

  • ArgoCD는 리포지토리를 지속적으로 모니터링하고 Kubernetes에 있는 애플리케이션의 상태가 Git에 정의된 원하는 상태와 일치하는지 확인하게 되는데 github 레포의 label 과 현재 적용되어 있는 label이 다르기 때문에 위와 같이 OutOfSync가 떠있는 모습을 확인 가능합니다.

 

 

  • Git Repo화면에서 값 변경 후 → Commit 후 ArgoCD에서 DIFF 확인 : 3분 간격, 바로 확인 시 REFRESH 클릭

  • Sync 후 다시 github 레포의 label 과 같이 적용되는 것을 확인 가능합니다.

 

 

 

  • Git Repo화면에서 replicas 5로 변경 후 → Commit 후 ArgoCD에서 REFRESH 클릭 후 Sync 후 확인

 

 

 

3-3) ArgoCD CLI

  • ArgoCD CLI 설치
#
curl -sSL -o argocd-linux-amd64 https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
sudo install -m 555 argocd-linux-amd64 /usr/local/bin/argocd
rm -f argocd-linux-amd64

#
argocd version

#
argocd login argocd.$MyDomain
Username: admin
Password: ###
'admin:login' logged in successfully

#
kubectl config get-contexts -o name
admin@myeks.ap-northeast-2.eksctl.io
argocd cluster add admin@myeks.ap-northeast-2.eksctl.io
y 입력

#
argocd app list
NAME  CLUSTER  NAMESPACE  PROJECT  STATUS  HEALTH  SYNCPOLICY  CONDITIONS  REPO  PATH  TARGET

 

 

  • Application 생성 with CLI
#
kubectl config set-context --current --namespace=argocd
argocd app create guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook --dest-server https://kubernetes.default.svc --dest-namespace default

#
argocd app list
NAME              CLUSTER                         NAMESPACE  PROJECT  STATUS     HEALTH   SYNCPOLICY  CONDITIONS  REPO                                                 PATH       TARGET
argocd/guestbook  https://kubernetes.default.svc  default    default  OutOfSync  Missing  <none>      <none>      https://github.com/argoproj/argocd-example-apps.git  guestbook

 

 

  • Sync (Deploy) The Application
#
argocd app get guestbook
...

# 모니터링
watch -d kubectl get pod,svc,ep

#
argocd app sync guestbook

 

 

 

3-4) Argo Rollouts 을 통한 배포

  • Argo Rollouts이란?
    • Argo Rollouts는 Kubernetes controller이자 CRDs로, Kubernetes에 블루그린, 카나리아, 카나리아 분석, 실험 및 점진적인 전달 기능과 같은 고급 배포 기능을 제공합니다.
    • Argo Rollouts(옵션)은 ingress controllers 및 service meshes와 통합되어 트래픽 조절 기능을 활용하여 업데이트 중에 트래픽을 점진적으로 새 버전으로 이동시킵니다.
    • 또한 Rollouts은 다양한 공급자의 메트릭을 쿼리하고 해석하여 주요 KPI를 확인하고 업데이트 중에 자동화된 프로모션 또는 롤백을 구동할 수 있습니다.
  • Why Argo Rollouts?
    • 기본 Kubernetes Deployment Object는 업데이트 중에 기본적인 안전 보장 세트(준비 탐색기)를 제공하는 RollingUpdate 전략을 지원합니다.
    • RollingUpdate 전략에는 다음과 같은 제한 사항이 있습니다
      • Rollouts 속도에 대한 제어가 거의 없음
      • 새 버전에 대한 트래픽 흐름을 제어할 수 없음
      • Readiness probes는 deeper, stress, or one-time checks에 적합하지 않습니다
      • 업데이트를 확인하기 위해 외부 메트릭을 쿼리할 수 없음
      • 진행을 중지할 수 있지만 업데이트를 자동으로 중단하고 롤백할 수 없습니다
  • Controller Features
  • 1) Blue-Green update strategy

https://argoproj.github.io/argo-rollouts/concepts/

 

  • 2) Canary update strategy

https://argoproj.github.io/argo-rollouts/concepts/

 

 

  • Argo Rollouts 설치
# 사용 리전의 개인 도메인 인증서 ARN 확인 
MyDomain=junholee.site
CERT_ARN=$(aws acm list-certificates --query "CertificateSummaryList[?DomainName=='${MyDomain}'].CertificateArn" --output text)
echo $CERT_ARN

# 도메인 확인
echo $MyDomain

# LB Subnet ID 
subnet1=subnet-0d836f49cf6fdccf2
subnet2=subnet-04c86db47ab12383e
subnet3=subnet-0347585c270752e08

# helm 설치
cat <<EOT > argorollouts-values.yaml
dashboard:
  enabled: true
  ingress:
    enabled: true
    ingressClassName: alb
    hosts:
      - argorollouts.$MyDomain
    annotations:
      alb.ingress.kubernetes.io/scheme: internet-facing
      alb.ingress.kubernetes.io/target-type: ip
      alb.ingress.kubernetes.io/subnets: $subnet1, $subnet2, $subnet3
      alb.ingress.kubernetes.io/backend-protocol: HTTP
      alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":80}, {"HTTPS":443}]'
      alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
      alb.ingress.kubernetes.io/ssl-redirect: '443'
      external-dns.alpha.kubernetes.io/hostname: argorollouts.$MyDomain
EOT

kubectl create ns argo-rollouts
helm install argo-rollouts argo/argo-rollouts --version 2.35.1 -f argorollouts-values.yaml --namespace argo-rollouts
# 확인
kubectl get all -n argo-rollouts
kubectl get crd | grep argo

 

 

  • rollouts 대시보드 : 네임스페이스별 확인 가능 - Docs
  • https://argorollouts.<자신의 도메인>/rollouts/

 

 

  • rollouts cli
#
curl -LO https://github.com/argoproj/argo-rollouts/releases/download/v1.6.4/kubectl-argo-rollouts-linux-amd64
chmod +x ./kubectl-argo-rollouts-linux-amd64
mv ./kubectl-argo-rollouts-linux-amd64 /usr/local/bin/kubectl-argo-rollouts

# 설치 확인
kubectl argo rollouts version

 

 

    • Argo Rollouts 배포 실습
    • Canary 실습
spec:
  replicas: 5
  strategy:
    canary:
      steps:
      - setWeight: 20
      - pause: {}
      - setWeight: 40
      - pause: {duration: 10}
      - setWeight: 60
      - pause: {duration: 10}
      - setWeight: 80
      - pause: {duration: 10}
  • spec.strategy에 canary를 적어주면 Canary 배포로 진행가능합니다.
  • step에 setWeight를 통해 단계별 가중치를 설정합니다.
wget https://raw.githubusercontent.com/argoproj/argo-rollouts/master/docs/getting-started/basic/rollout.yaml
wget https://raw.githubusercontent.com/argoproj/argo-rollouts/master/docs/getting-started/basic/service.yaml

cat ./rollout.yaml
cat ./service.yaml

kubectl apply -f ./rollout.yaml
kubectl apply -f ./service.yaml

 

 

  • CLI vs UI 확인 https://argorollouts.<각자 자신의 도메인>/rollouts/argocd
kubectl argo rollouts get rollout rollouts-demo

 

 

  • Updating a Rollout
  • kubectl argo rollouts 명령어를 통해 rollouts-demo:yellow 이미지로 배포 진행
#
watch -d kubectl get pod -n argocd -l app=rollouts-demo -owide --show-labels

# Run the following command to update the rollouts-demo Rollout with the "yellow" version of the container:
kubectl argo rollouts set image rollouts-demo rollouts-demo=argoproj/rollouts-demo:yellow

  • 20%의 Pod만 변경된후 Pause 상태인것을 확인가능합니다.

 

  • 첫번째 단계에서는 Pause 상태의 시간을 지정하지 않았기 때문에 UI에서 Promote --> PromoteFull을 클릭하여 진행합니다.

 

 

  • Promote는 미리 설정해놓은 step으로 배포를 진행하는 기능으로 아래와 같이 정상적으로 모든 과정이 진행됨을 확인 가능합니다.

728x90
반응형

'EKS' 카테고리의 다른 글

[EKS] Security  (0) 2024.04.14
[EKS] Autoscaling  (0) 2024.04.06
[EKS] Observability  (0) 2024.03.28
[EKS] AWS EKS의 Storage & Nodegroup  (1) 2024.03.23
[EKS] AWS EKS의 Networking (VPC CNI, LB Controller)  (0) 2024.03.16