GitOps란 DevOps를 실천하는 방법 중 하나이다. 그 중에서도 Cloud Native한 Application을 대상으로 CD(Continuous Deployment)에 초점을 두고 있다.
Application 배포와 운영에 관련된 모든 요소를 코드화하여 Git에서 관리(Ops)하는 개념을 GitOps라고 한다. 그렇다고 IaC와 유사하지만 같은 개념은 아니다.
IaC는 Infrastructure as a Code의 약자로써 인프라를 프로비저닝하고 설정 값을 변경하는 개념이라고 하면 GitOps는 애플리케이션 배포에 초점이 맞춰져 있다.
ArgoCD는 GitOps의 대표적인 예시라고 할 수 있다.
Pull 형태를 사용하며, ArgoCD에서 설정한 Git Repository를 지속적으로 감시하고, Git Repository의 YAML 파일에 선언되어 있는 Manifest 파일들이 Kubernetes에 배포되어 있는 Application의 Current State를 지속적으로 감시하며, 이에 대한 Sync(동기화) 유무를 확인한다.
Git Repository (Desired State) <-> ArgoCD <-> Kubernetes Objects (Current State)
아래 그림이 잘 설명되어 있다.
1 - 초기 세팅 및 설치하기
제공해주는 ArgoCD 설치 템플릿을 사용할 예정이며, 이를 Ingress Controller을 활용하여 ALB로 서빙할 수 있도록 할 예정이다.
주의 사항
필자는 ACM 및 Route 53이 구성되어 있는 상태고, External DNS Controller, ALB Ingress Controller가 구성되어 있는 상태이다.
❯ kubectl get pods -n kube-system | egrep "external|load-balancer"
aws-load-balancer-controller-5d4445d699-p9svp 1/1 Running 0 3d20h
external-dns-cb4cc4bd6-d7cfr 1/1 Running 0 3d19h
EKS Cluster 내에 ArgoCD 배포
NodePort로 변경해야 ALB에서 Worker Node의 Port로 접근하여 외부에서도 ArgoCD Pod에 도달할 수 있기 때문에 변경해주었음
# Namespace 생성
kubectl create namespace argocd
kubectl apply -n argocd -f <https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml>
# SVC 타입을 NodePort로 변경
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "NodePort"}}'
ArgoCD CLI 설치
최신 버전을 사용할 수 있도록 가져온 뒤, argocd 명령어를 사용할 수 있도록 한다.
❯ VERSION=$(curl --silent "<https://api.github.com/repos/argoproj/argo-cd/releases/latest>" | grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/\\1/')
❯ echo $VERSION
v2.1.7
❯ curl -LO https://github.com/argoproj/argo-cd/releases/download/$VERSION/argocd-linux-amd64
chmod u+x argocd-linux-amd64
sudo mv argocd-linux-amd64 /usr/local/bin/argocd
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 626 100 626 0 0 1232 0 --:--:-- --:--:-- --:--:-- 1232
100 105M 100 105M 0 0 1324k 0 0:01:21 0:01:21 --:--:-- 4817k
[sudo] password for user:
❯ argocd --help
argocd controls a Argo CD server
Usage:
argocd [flags]
argocd [command]
Available Commands:
...
ALB로 접근하기 위한 Ingress 오브젝트 생성
단순 ArgoCD를 위한 ALB를 1개 더 생성한다면 비용적으로 비효율적이다. 고로, 기존에 있는 ALB가 있다면 그루핑을 하여 8443 등의 포트로 접근할 수 있도록 설정해준다.
1. Ingress (springboot 애플리케이션이 접근할 수 있도록 해주는 Ingress)
group.name : alb-01로 설정했으니, ArgoCD Ingress에서도 해당 group.name을 설정해준다면 동일한 ALB에서 서빙할 수 있을 것이다.
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
namespace: demo-springboot
name: demo-springboot-ingress
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/group.name: alb-01
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:ap-northeast-2:{ACCOUNT_ID}:certificate/28ff71d5-f0d6-4958-abcb-ece79efb6323
alb.ingress.kubernetes.io/tags: createdBy=aws-load-balancer-controller
alb.ingress.kubernetes.io/ssl-policy: ELBSecurityPolicy-2016-08
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
external-dns.alpha.kubernetes.io/hostname: pingping2.shop
spec:
rules:
- http:
paths:
- path: /*
backend:
serviceName: ssl-redirect
servicePort: use-annotation
- path: /*
backend:
serviceName: demo-springboot-svc
servicePort: 80
2. ArgoCD Ingress (ArgoCD가 ALB를 통해 접근할 수 있도록 설정)
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
namespace: argocd
name: demo-argocd-ingress
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/group.name: alb-01
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:ap-northeast-2:{ACCOUNT_ID}:certificate/28ff71d5-f0d6-4958-abcb-ece79efb6323
alb.ingress.kubernetes.io/tags: createdBy=aws-load-balancer-controller
alb.ingress.kubernetes.io/backend-protocol: HTTPS
alb.ingress.kubernetes.io/ssl-policy: ELBSecurityPolicy-2016-08
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 8080}, {"HTTPS":8443}]'
alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "8443", "StatusCode": "HTTP_301"}}'
external-dns.alpha.kubernetes.io/hostname: pingping2.shop
spec:
rules:
- http:
paths:
- path: /*
backend:
serviceName: ssl-redirect
servicePort: use-annotation
- http:
paths:
- path: /*
backend:
serviceName: argocd-server
servicePort: 443
정상적으로 External DNS에서 Route53에 Record를 등록하였음
- ALB
ALB Ingress Controller에 의해 정상적으로 ALB가 생성 및 Annotation에 정의된 대로 리스너 등이 생성되었으며, 그루핑을 활용하여 추가 ALB를 생성하지 않고 기존에 있는 ALB에 리스너를 추가하였다.
정상적으로 ALB를 통해 접근 가능한 것을 확인할 수 있다.
초기 패스워드 변경
Ref : https://stackoverflow.com/questions/68297354/what-is-the-default-password-of-argocd
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
58smMedwhnF1b0t4
argocd account update-password
argocd login --grpc-web pingping2.shop:8443
Username: admin
Password:
'admin:login' logged in successfully
Context 'pingping2.shop:8443' updated
그 후에, Web에서 변경된 Password로 접속할 수 있다.
2. ArgoCD에 Git Repository 등록, Application 등록
1. Repository
Repositories 클릭
인증 방법은 SSH를 통해서도 가능하고, HTTPS 및 GITHUB APP으로도 가능하다.
가장 간단한 방법인 HTTPS 프로토콜을 통해서 인증을 진행함
GitOps 형태로 운영할 Repository를 선택하고, Username 그리고 Password (Token)을 기입한다.
만약 해당 Repository가 Public이면 별도의 Username, Password를 입력하지 않아도 되지만 Private일 경우 인증, 인가된 사용자만 해당 Repository를 사용할 수 있기에 Username과 Password를 필히 기입해줘야 사용이 가능하다.
그 후, Connection이 Successful로 뜨면 성공한 것이다.
2. Application
이제, ArgoCD가 Repository의 어느 Path에 있는 Manifest 파일들을 바라볼 것인지 설정하고, ArgoCD가 어떤 클러스터 및 Namespace에 배포할 것인지를 정의하는 과정이 필요하다.
⇒ 여기서 ArgoCD는 Application이라는 개념을 사용하게 된다.
CREATE APP 클릭
Source
어느 Git에서 소스 코드를 가져올 것인지 정의한다.
Destination
어디에 배포할 것인지 정의한다.
그 후, CREATE 하면 된다.
만약, SYNC가 맞지 않다면 싱크를 수행할 수 있으며, 아래와 같이 SYNC가 맞을 경우 노랑색 → 초록색으로 변하게 된다.
정상적으로 배포된 것을 확인할 수 있다.
그 외, 자동으로 SYNC를 맞추는 옵션 혹은 애플리케이션 업데이트 내역 ROLLBACK, 롤링 업데이트, HELM을 이용한 애플리케이션 배포, 블루그린 등 여러가지 옵션을 고려할 수 있으며, 사용 방법이 비교적 간단한 편이므로 공식 문서 등을 참고하여 사용하면 될 것 같다.
3. Application 수정 및 배포, 롤백하기
Image를 Tag : 3을 지닌 이미지로 변경하여 배포하고 싶을 경우라고 가정해보자.
아래의 내용으로 수정한 뒤
template:
metadata:
labels:
app: demo-springboot
spec:
containers:
- image: ACCOUNT_ID.dkr.ecr.ap-northeast-2.amazonaws.com/demo-maven-springboot:3
name: demo-maven-springboot
resources:
limits:
memory: 512Mi
cpu: "0.5"
requests:
memory: 256Mi
cpu: "0.2"
Local에서 원격 저장소로 Push 하였음
❯ git add kubernetes/demo-springboot/app.yaml
❯ git commit -m "[Edit] APP Image Tag : 3으로 수정"
[main 3f76ef4] [Edit] APP Image Tag : 3으로 수정
1 file changed, 1 insertion(+), 1 deletion(-)
❯ git push -u origin main
Enumerating objects: 9, done.
Counting objects: 100% (9/9), done.
Delta compression using up to 8 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 495 bytes | 495.00 KiB/s, done.
Total 5 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To <https://github.com/pingping95/EKSProj.git>
9e4853e..3f76ef4 main -> main
Branch 'main' set up to track remote branch 'main' from 'origin'.
ArgoCD는 우리가 설정한 Git Repo의 특정 PATH 형상을 감시하고, 현재 Kubernetes에 배포된 형상과 다른지 확인한다.
아래 deployment 파일의 상태가 OutOfSync라고 나온다.
DIFF를 클릭하면 어떤 부분이 달라졌는지 확인할 수 있다.
SYNC를 맞추기 전에, -w 옵션으로 어떤 변화가 일어나는지 확인
ARGO 서버에서도 어떤 일이 일어나는지 확인해보겠다.
kubectl logs -f -n argocd argocd-server-58d848f6b-mvdfn
SYNC 수행하게 되면, 아래와 같이 ReplicaSet이 1개 더 생성되며, Pod가 새로 생성 및 Down 된다.
컨테이너가 순차적으로 Rolling Update가 되고 있는 모습이다.
Rolling Update가 완료된 모습
정상적으로 Deploy가 된 것을 확인할 수 있다.
롤백을 하고 싶은 경우에는?
History And Rollback을 클릭하면 이전 배포 내역이 나오며, 원하는 History로 Rollback을 할 수 있다.
다시 이전 History로 Rollback되고 있는 모습이다.
다시 돌아온 것을 확인할 수 있다.
위와 같이 ArgoCD는 굉장히 손쉽게 지속적 배포를 쿠버네티스 환경에서 할 수 있도록 도와주는 도구이다.
'AWS' 카테고리의 다른 글
[Lambda] CW Logs 구독 필터와 Lambda 연결, Slack으로 인스턴스 스케줄러 동작 내역 확인하기 (0) | 2021.12.15 |
---|---|
[WEB] Apache Log 포맷 기본 정리 (+ Client의 IP를 보고 싶을 경우) (0) | 2021.12.14 |
[EKS] Jenkins로 CI 수행하기 - Maven Build 및 Image ECR Push (0) | 2021.11.26 |
[EKS] Amazon EBS CSI Driver 설치 및 사용하기 (0) | 2021.11.24 |
[EKS] External DNS 설치 및 사용하기 (0) | 2021.11.24 |