이번 게시글은 가시다님의 AEWS [2기] 스터디 내용을 정리한 포스트 입니다.
이번 게시글은 7 주차의 스터디 내용인 EKS CI/CD에 대해 살펴봅니다.
EKS 배포
실습을 위해 EKS 클러스터를 배포합니다. AWS 콘솔에 로그인 한 뒤 CloudFormation에서 아래 YAML 파일로 스택을 생성하시면 됩니다. 진행 과정은 아래 링크를 참고해 주세요.
배포 확인
Bastion EC2 인스턴스의 공인 IP로 SSH 접근을 시도합니다. 공인 IP는 CloudFormation의 결과에 나오는 출력값 혹은 EC2 메뉴에서 bastion 호스트의 공인IP를 확인합니다.
# ssh -i "Keyname" ec2-user@"Public IP"
ssh -i hj42700eks.pem ec2-user@3.36.133.15
Bastion 접속 후 아래와 같이 기본 설정을 진행합니다.
# default 네임스페이스 적용
kubectl ns default
# 노드 정보 확인 : t3.medium
kubectl get node --label-columns=node.kubernetes.io/instance-type,eks.amazonaws.com/capacityType,topology.kubernetes.io/zone
# ExternalDNS
MyDomain=<자신의 도메인>
echo "export MyDomain=<자신의 도메인>" >> /etc/profile
MyDomain=junkmm.site
echo "export MyDomain=junkmm.site" >> /etc/profile
MyDnzHostedZoneId=$(aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." --query "HostedZones[0].Id" --output text)
echo $MyDomain, $MyDnzHostedZoneId
curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/aews/externaldns.yaml
MyDomain=$MyDomain MyDnzHostedZoneId=$MyDnzHostedZoneId envsubst < externaldns.yaml | kubectl apply -f -
# kube-ops-view
helm repo add geek-cookbook https://geek-cookbook.github.io/charts/
helm install kube-ops-view geek-cookbook/kube-ops-view --version 1.2.2 --set env.TZ="Asia/Seoul" --namespace kube-system
kubectl patch svc -n kube-system kube-ops-view -p '{"spec":{"type":"LoadBalancer"}}'
kubectl annotate service kube-ops-view -n kube-system "external-dns.alpha.kubernetes.io/hostname=kubeopsview.$MyDomain"
echo -e "Kube Ops View URL = http://kubeopsview.$MyDomain:8080/#scale=1.5"
# AWS LB Controller
helm repo add eks https://aws.github.io/eks-charts
helm repo update
helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=$CLUSTER_NAME \
--set serviceAccount.create=false --set serviceAccount.name=aws-load-balancer-controller
# gp3 스토리지 클래스 생성
kubectl apply -f https://raw.githubusercontent.com/gasida/PKOS/main/aews/gp3-sc.yaml
# 노드 보안그룹 ID 확인
NGSGID=$(aws ec2 describe-security-groups --filters Name=group-name,Values=*ng1* --query "SecurityGroups[*].[GroupId]" --output text)
aws ec2 authorize-security-group-ingress --group-id $NGSGID --protocol '-1' --cidr 192.168.1.100/32
프로메테우스 & 그라파나(admin/prom-operator) 설치, 대시보드 추천 15757 17900 15172
# 사용 리전의 인증서 ARN 확인
CERT_ARN=`aws acm list-certificates --query 'CertificateSummaryList[].CertificateArn[]' --output text`
echo $CERT_ARN
# repo 추가
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
# 파라미터 파일 생성 : PV/PVC(AWS EBS) 삭제에 불편하니, 4주차 실습과 다르게 PV/PVC 미사용
cat <<EOT > monitor-values.yaml
prometheus:
prometheusSpec:
podMonitorSelectorNilUsesHelmValues: false
serviceMonitorSelectorNilUsesHelmValues: false
retention: 5d
retentionSize: "10GiB"
ingress:
enabled: true
ingressClassName: alb
hosts:
- prometheus.$MyDomain
paths:
- /*
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
alb.ingress.kubernetes.io/success-codes: 200-399
alb.ingress.kubernetes.io/load-balancer-name: myeks-ingress-alb
alb.ingress.kubernetes.io/group.name: study
alb.ingress.kubernetes.io/ssl-redirect: '443'
grafana:
defaultDashboardsTimezone: Asia/Seoul
adminPassword: prom-operator
defaultDashboardsEnabled: false
ingress:
enabled: true
ingressClassName: alb
hosts:
- grafana.$MyDomain
paths:
- /*
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
alb.ingress.kubernetes.io/success-codes: 200-399
alb.ingress.kubernetes.io/load-balancer-name: myeks-ingress-alb
alb.ingress.kubernetes.io/group.name: study
alb.ingress.kubernetes.io/ssl-redirect: '443'
alertmanager:
enabled: false
EOT
cat monitor-values.yaml | yh
# 배포
kubectl create ns monitoring
helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack --version 57.2.0 \
--set prometheus.prometheusSpec.scrapeInterval='15s' --set prometheus.prometheusSpec.evaluationInterval='15s' \
-f monitor-values.yaml --namespace monitoring
# Metrics-server 배포
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
# 프로메테우스 ingress 도메인으로 웹 접속
echo -e "Prometheus Web URL = https://prometheus.$MyDomain"
# 그라파나 웹 접속 : 기본 계정 - admin / prom-operator
echo -e "Grafana Web URL = https://grafana.$MyDomain"
Docker
이번 실습에서는 개인 Docker Hub에 컨테이너 이미지를 Push 하기 때문에, Docker에 회원 가입을 진행해야 합니다.
Bastion 호스트에서 간단한 웹 서비스 컨테이너 이미지를 생성하고, Push 해 보도록 하겠습니다.
아래 명령으로 base 이미지인 ubuntu:20.04를 다운로드 받습니다.
docker pull ubuntu:20.04
docker images
실습을 위해 디렉터리를 생성 및 이동합니다.
mkdir -p /root/myweb && cd /root/myweb
`vi Dockerfile` 명령으로 Dockerfile을 생성합니다. NICK 변수를 본인의 이름으로 변경합니다.
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"]
`:wq`로 저장 및 편집 종료한 뒤, 터미널에서 아래 명령으로 컨테이너 이미지를 생성합니다.
docker build -t myweb:v1.0.0 .
아래 명령으로 image가 잘 생성되었는지 확인합니다.
docker images
아래 명령으로 컨테이너를 실행시킵니다.
docker run -d -p 80:80 --rm --name myweb myweb:v1.0.0
아래 명령으로 웹 접속 URL을 확인합니다.
curl -s ipinfo.io/ip | awk '{ print "myweb = http://"$1"" }'
아래 명령으로 docker hub에 이미지를 업로드 합니다.
# 도커 이미지 태그 변경
DHUB=<도커 허브 계정>
DHUB=junkmm.site
docker tag myweb:v1.0.0 $DHUB/myweb:v1.0.0
docker images
# 도커 허브 로그인
docker login
Username: <자신의 ID>
Password: <암호>
# push 로 이미지를 저장소에 업로드
docker push $DHUB/myweb:v1.0.0
자신의 Repository에 myweb 저장소가 생기고, v1.0.0 이미지가 생성되었는지 확인합니다.
아래 명령으로 Local 이미지로 실행한 web을 중지하고, Docker Hub에 업로드한 이미지로 컨테이너를 실행시킵니다.
# 컨테이너 종료
docker rm -f myweb
docker ps
# 로컬 이미지 삭제
docker rmi $DHUB/myweb:v1.0.0
docker images
#
docker run -d -p 80:80 --rm --name myweb $DHUB/myweb:v1.0.0
docker iamges
# 확인
docker ps
curl localhost
curl -s ipinfo.io/ip | awk '{ print "myweb = http://"$1"" }'
# 삭제
docker rm -f myweb
로컬 환경에서 Docker를 통해 Web 서비스를 배포해 보았습니다. 해당 이미지를 이번 CI/CD 실습에 활용 할 예정입니다.
Jenkins
CI(Continuous Intergration)를 위해 Jenkins를 사용합니다. 오픈 소스이 개발 소스를 빌드하거나 배포할 때 사용할 수 있습니다.
설치 및 설정
Bastion 호스트에서 아래 명령어로 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
Jenkins의 초기 암호를 확인합니다.
# 초기 암호 확인
cat /var/lib/jenkins/secrets/initialAdminPassword
접속 URL을 확인합니다.
curl -s ipinfo.io/ip | awk '{ print "Jenkins = http://"$1":8080" }'
Jenkins URL로 접근하여 위에서 조회한 관리자 비밀번호를 입력합니다.
다음 화면에서 Install suggested plugins를 설치해 플러그인을 설치합니다.
기본 플러그인이 설치됩니다.
Admin 유저를 설정합니다. (admin/qwe123)
기본 사용, Tools 설정
Jenkins 메인 화면 입니다.
Item은 젠킨스에서 사용하는 최소 작업 단위이고, 사람은 Jenkins의 계정 관련 설정, Jenkins 관리는 전역 설정을 적용하는 메뉴 입니다.
Jenkins 기본 사용을 위해 JDK 정의를 진행합니다. Jenkins 관리 -> Tools에 진입합니다.
JDK Installations에서 `Add JDK`를 클릭하고, 아래와 같이 정보를 입력합니다.
첫 번째 Item을 생성합니다. 메인화면 -> Item으로 진입하고, 이름 입력 후 Freestyle project를 선택합니다.
Build Steps -> Add build step -> Excute shell을 선택합니다.
간단한 문장 출력이 될 수 있게 `echo "Aws Workshop Study"`를 입력하고 저장합니다.
지금 빌드를 클릭하여 Jenkins의 Item을 실행합니다.
하단 Build History에 새로운 내역이 생깁니다. 해당 내역에 마우스를 위치하면 아래 사진과 같이 Side Menu가 표시됩니다. Console Output을 클릭합니다.
콘솔 출력에 Excute Shell에 정의한 Welcome to my first project가 찍혀있습니다.
Item(Job) 메뉴로 돌아와 구성 탭에서 Excute shell 부분을 아래와 같이 수정하고, 실행 시킵니다.
다시 Console Output을 확인 해보면, 위에서 정의한 명령어를 실행한 출력값들을 확인해볼 수 있습니다. 이로 인해 Jenkins는 사용자가 정의한 작업을 순서대로 처리하는 특성을 확인해볼 수 있습니다.
위 로그를 보면 Building in workspace라고 정의된 경로가 있습니다. 한국 말로 직역하면 작업 공간이고, 해당 디렉터리에 가보면 touch hello.txt에 의해 hello.txt 파일이 생성되어 있는것을 확인해볼 수 있습니다.
whoami 명령어로 조회한 Linux의 user명은 jenkins로 확인됩니다. 즉 jenkins가 설치된 Bastion호스트의 shell을 jenkins라는 user가 접근하여 위 명령어들을 조회한 것으로 이해가 됩니다.
Docker 사용
Jenkins에서 Docker 빌드를 하기 위해 jenkins 유저가 docker를 실행할 수 있는 권한을 부여해야 합니다.
#docker sock에 666 권한 할당
chmod 666 /var/run/docker.sock
usermod -aG docker jenkins
# Jeknins 유저로 확인
su - jenkins
docker info
# Dockerhub로 로그인 하기
docker login
Username: <자신의 계정명>
Password: <자신의 암호>
Dockerfile을 생성합니다.
# 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=<자신의 닉네임>
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"]
Jenkins에서 새로운 Item을 생성합니다. Add build step으로 총 2개의 Execute shell을 아래와 같이 생성합니다. 해석하자면 jenkins는 /var/lib/jenkins/myweb2 디렉토리로 이동하고, 해당 dir에서 `docker build`를 진행합니다. 이때 위에서 생성한 Dockerfile을 기반으로 build 합니다.
build가 완료되면 `docker run` 명령을 통해 해당 이미지를 실행시킵니다.
# shell 1
cd /var/lib/jenkins/myweb2
docker build -t myweb:v2.0.0 .
# shell 2
docker run -d -p 80:80 --rm --name myweb myweb:v2.0.0
빌드가 성공했습니다.
아래와 같이 docker image가 생성되고, 실행 중인것을 확인할 수 있습니다.
아래 명령으로 실습 리소스를 삭제합니다.
docker rm -f myweb
docker rmi myweb:v2.0.0
Github 가입
Github에 가입하고 https://github.com/gasida/aews-cicd.git 레포지토리를 포크합니다.
Jenkins Trigger-Project
Git Repo의 변화가 생기면 Jenkins Item(Job)이 실행되는 환경을 실습합니다.
Freestyle project를 생성합니다.
아래와 같이 변수를 추가합니다.(string)
Git 부분을 수정합니다.
빌드 유발을 설정합니다.
빌드 스텝을 설정합니다.
# Shell 1
cd /var/lib/jenkins/myweb2
rm -rf Dockerfile
wget https://raw.githubusercontent.com/$NICK/aews-cicd/main/1/Dockerfile
# Shell 2
cd /var/lib/jenkins/myweb2
docker build --build-arg VERSION=$VERSION -t myweb:$VERSION .
docker run -d -p 80:80 --rm --name myweb -e VERSION=$VERSION myweb:$VERSION
본인의 Github 계정에서 1/Dockerfile 의 Version 부분을 수정합니다.
파라미터와 함께 빌드를 클릭하고, Version을 변경합니다.
완료 후 `curl localhost`로 결과를 확인합니다.
실습 내용을 정리합니다.
docker rm -f myweb
docker rmi myweb:v5.3.1
docker rmi myweb:v1.0.0
Jenkins with Kubernetes
EKS 환경에 배포하는 Jenkins를 구성합니다. 이를 위해 Bastion Jenkins 사용자에서 사전 작업을 진행합니다.
# jenkins 사용자에서 아래 작업 진행
su - 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]: ###
AWS Secret Access Key [None]: ###
Default region name [None]: ap-northeast-2
# jenkins 사용자에서 kubectl 명령어 사용 확인
kubectl get pods -A
Jenkins의 파이프라인으로 Deployment/Service를 배포합니다.
먼저 본인 Github계정의 3/deploy/deployment-svc.yaml에 image 부분을 수정합니다.
Jenkins에서 새로운 Item에 진입 후 Pipeline을 선택합니다.
pipeline 부분에 아래 내용을 입력합니다.
pipeline {
agent any
tools {
jdk 'jdk-17'
}
environment {
DOCKERHUB_USERNAME = 'kimhj4270'
GITHUB_URL = 'https://github.com/junkmm/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 ${DOCKERHUB_USERNAME}/myweb:v1.0.0 ./${DIR_NUM}"
sh "docker push ${DOCKERHUB_USERNAME}/myweb:v1.0.0"
}
}
stage('K8S Deploy') {
steps {
sh "kubectl apply -f ./${DIR_NUM}/deploy/deployment-svc.yaml"
}
}
}
}
지금 빌드를 클릭합니다.
Bastion에서 접속 테스트용 파드를 배포합니다.
# 배포
cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Pod
metadata:
name: netpod
labels:
app: pod
spec:
containers:
- name: netshoot-pod
image: nicolaka/netshoot
command: ["tail"]
args: ["-f", "/dev/null"]
terminationGracePeriodSeconds: 0
EOF
아래 명령어로 myweb pod가 잘 배포되었는지 확인합니다.
kubectl exec -it netpod -- curl myweb:8080
실습 리소스를 삭제합니다.
kubectl delete deploy,svc myweb
Argo Project
Argo는 Kubernetes 환경에서 gitops패턴의 배포 환경을 지원해주는 CNCF 프로젝트 입니다. Argo CD는 쿠버네티스 환경에 배포를 담당하고, Argo Rollouts는 쿠버네티스 배포 시 Blue-Green, Canary 등 무중단 배포를 지원합니다.
ArgoCD
ArgoCD는 API, Repository Service, Application Controller 크게 3가지 서비스가 내장되어 있습니다. API는 Web UI 대시보드를 제공하고, API 서비스를 제공합니다. Repository Server는 Git 연결 및 배포할 yaml을 생성합니다. Application Controller는 K8s 리소스와 Git을 비교하며 Sync를 비교합니다. 동적으로 Git과 k8s를 동기화 할 수 있고, 수동으로 동기화 시킬 수 있습니다.
아래 명령으로 ArgoCD를 설치합니다.
# 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/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'
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
확인
Redis는 k8s api와 git 요청을 줄이기 위한 캐싱으로 사용됩니다. notification은 이벤트 알림 및 트리거를 제공하고, Applicationset-controller는 멀티 클러스터를 위한 App 패키징 관리를 위해 사용 됩니다.
`https://argocd.junkmm.site/admin`으로 접속합니다. 아래 명령으로 초기 admin의 암호를 확인합니다.
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d ;echo
admin/위 비밀번호로 로그인 합니다.
NewAPP을 클릭합니다.
아래와 같이 내용을 기입하고 생성합니다.
생성된 Application에 접근합니다.
Sync -> Syncronize를 클릭합니다.
Application이 Health되었습니다.
`kubectl get all -n first`로 조회 시 리소스가 조회된것을 알 수 있습니다.
Github의 Yaml파일을 수정해 보겠습니다. yaml의 label을 추가하고 저장합니다.
Refresh를 누르거나 3분을 기다리면 Status가 OutOfSync로 변경됩니다. Sync를 누르게 되면 Git에서 추가한 labels가 반영된 Deployment가 배포 됩니다.
위와 같이 Gitops를 하기 위해선 배포 yaml 수정을 git에서 진행해야 합니다.
생성한 Application은 Delete를 누른 뒤 아래와 같이 삭제합니다.
위 방식은 Web UI를 통해 구현한 예시입니다. Jenkins와 같은 도구나 CLI환경에서 배포해야 하는경우 argo 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
hakjunadmin@myeks.ap-northeast-2.eksctl.io
argocd cluster add hakjunadmin@myeks.ap-northeast-2.eksctl.io
y 입력
#
argocd app list
NAME CLUSTER NAMESPACE PROJECT STATUS HEALTH SYNCPOLICY CONDITIONS REPO PATH TARGET
아래 명령으로 Application을 생성할 수 있습니다.
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
아래 명령으로 sync를 맞출 수 있습니다.
argocd app sync guestbook
Application 삭제
Argo Rollouts
Argo Project 중 하나로 고급 배포 전략을 제공합니다. 그 중 대표적인 것으로 Blue-Green, Canary 배포 전략입니다.
블루-그린
카나리
아래 명령으로 설치를 진행합니다.
#
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/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'
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
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
아래 yaml을 배포합니다. Canary 배포를 진행하며, 최초 20% 비율로 트래픽을 흘리고, 승인 뒤 40%, 10초 단위로 20% 증가하는 방식의 배포입니다.
spec:
replicas: 5
strategy:
canary:
steps:
- setWeight: 20
- pause: {}
- setWeight: 40
- pause: {duration: 10}
- setWeight: 60
- pause: {duration: 10}
- setWeight: 80
- pause: {duration: 10}
# Run the following command to deploy the initial Rollout and Service:
kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-rollouts/master/docs/getting-started/basic/rollout.yaml
kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-rollouts/master/docs/getting-started/basic/service.yaml
rollouts으로 배포된 리소스는 아래 명령어로 확인 가능합니다.
kubectl argo rollouts get rollout rollouts-demo
`https://argorollouts.junkmm.site/rollouts/default`에 접근합니다.
아래의 명령어로 기존 리소스의 컨테이너 이미지를 업데이트 합니다.
kubectl argo rollouts set image rollouts-demo rollouts-demo=argoproj/rollouts-demo:yellow
위 yaml의 정의에 따라 관리자의 수동 승인 전 까지는 새로운 버전에 대핸 20%를 유지합니다. 총 5개 파드이니, 1개의 신규 버전과 4개의 기존 버전이 배포됩니다.
상단의 Promote를 클릭합니다.
승인되면 순차적으로 신규버전이 80%가 되기 까지 10초 씩 증가합니다.
rollback을 누르게 되면 기존 버전으로 되돌아 갑니다.
이전(승인 전)으로 되돌아간 생태에서 Abort를 누르면 모든 파드가 완전히 이전 버전으로 배포됩니다.
아래 명령으로 실습 리소스를 삭제합니다.
eksctl delete cluster --name $CLUSTER_NAME && aws cloudformation delete-stack --stack-name $CLUSTER_NAME
'클라우드' 카테고리의 다른 글
[EKS] IaC (0) | 2024.04.27 |
---|---|
[k8s] Pod의 전략적 배치 - Node Affinity (0) | 2024.04.17 |
[EKS] Autoscaling (0) | 2024.04.03 |
[EKS] Storage & NodeGroup (0) | 2024.03.23 |
[EKS] Networking (0) | 2024.03.14 |