[쿠버네티스] - Argo CD

chancehee·2024년 3월 2일
0

쿠버네티스

목록 보기
17/17
post-thumbnail

[ 개요 ]

토이 프로젝트를 개발하고 배포할 때, JAR 파일(혹은 Node.js)을 빌드하고 Docker Image를 Docker Hub에 Push하고, Kubernetes Cluster에서 Docker Hub에서 Docker Image를 Pull 받아 Deployment를 생성하는 모든 작업을 수작업으로 진행했다.

./gradlew clean build
docker build --push --platform linux/amd64 -t [이미지 이름] .
kubectl apply -f [배포.yml]
등 등 ...

결론적으로 코드의 변경이 있으면, 운영 서버에 반영되기 까지 모든 작업은 수작업이고 MSA로 구성된 많은 Application를 관리하는 것은 귀찮고, 실수할 가능성도 존재했다.

나와 친구 개발자는 CI/CD 파이프라인을 구축해서 코드 통합, 배포 작업을 자동화하는 것을 목표로 했다.

[ CI ]

대표적인 CI/CD Tool을 떠올리면 Jenkins, GitHub Actions가 있다.
필자는 GitHub Actions를 선택했는데, 이유는 Jenkins를 AWS Ubuntu 서버에서 사용하기 위해서는 4GB RAM 권장이 있어서 AWS 비용 절감을 목표로 했기 때문이다. (추가적으로 직관적인 workflows 구성도 한 몫 했다.)

[ CD ]

Jenkins, GitHub Actions로 CD까지 가능하다.
하지만, Kubernetes를 사용하는 많이 개발자들은 Argo CD를 많이 사용하는 것을 찾아볼 수 있다.

그 이유가 궁금했다.

주요한 이유 중 하나는 Argo CD 공식문서를 통해 확인할 수 있었다.

What is Argo CD?
Argo CD is a declarative GitOps continous delivery tool for Kubernetes.

Why Argo CD?
Application definitions, configurations, and environments should be declarative and version controlled.

Application deployment and lifecycle management should be automated, auditable, and easy to understand

핵심은 Argo CD는 Kubernetes에 특화된 도구로 Desired State와 실제로 Kubernetes Cluster에 적용된 State를 모니터링하고 Sync를 맞춰주는 것이다. (+ 쉬운 작업)

[ 실습 ]

환경 : Ubuntu 20.04 LTS, K3s(단일 노드)
CI : GitHub Actions
CD : Argo CD

위 CI/CD 도구로 파이프라인을 구축하는 것을 목표로 작업을 진행했다.

Preview

  1. GitHub에 code push (event trigger -> GitHub Actions)
  2. GitHub Actions에 등록해 놓은 Action 동작
    • JAR build
    • Docker Image build
    • Docker Imange push
    • Kustomize 작업
  3. Deployment.yml change (event trigger -> Argo CD)
  4. Argo CD에 등록해 놓은 Application 설정에 따라 Sync 작업 수행
  5. Desired State ----> K3s Cluster (update sync)

작업 순서

  1. Docker Hub Token 발급 및 GitHub Token 설정
  2. GitHub Secret 등록 (발급 받은 Token 및 환경 변수)
  3. GitHub Action 정의 (code push trigger 시점에 자동으로 동작시킬 작업)
  4. Argo CD 설치 및 구성 (K3s Cluster에 namespace 설정 및 Argo CD Pod 띄우기)
  5. Kustomize 작업 정의
  6. Argo CD Application 등록 (Deployment.yml change trigger 시점에 자동으로 동작시킬 작업)

1. Docker Hub Token 발급 및 GitHub Token 설정

2. GitHub Secret 등록 (발급 받은 Token 및 환경 변수)

Spring application.yml 파일도 등록했다.

3. GitHub Action 정의 (code push trigger 시점에 자동으로 동작시킬 작업)

name: CI

on:
  push:
    branches:
      - back-gateway # 트리거 브랜치
env:
  IMAGE_NAME: gallery-gateway

jobs:
  docker-build-and-deploy:
    runs-on: ubuntu-latest

    defaults:
      run:
        shell: bash
        working-directory: ./backend/gateway

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set up JDK 11
        uses: actions/setup-java@v2
        with:
          distribution: "adopt"
          java-version: "11"

      - name: Retrieve application properties
        env:
          APPLICATION_PROPERTIES: ${{ secrets.GATEWAY_APPLICATION_PROPERTIES }} # 시크릿에 등록시킨 application.yml 불러오기
        run: |
          mkdir ./src/main/resources
          touch ./src/main/resources/application.yml
          echo "${APPLICATION_PROPERTIES}" > ./src/main/resources/application.yml

      - name: Build Spring Boot application
        run: ./gradlew clean build -x test # JAR Build

      - name: Login to Docker Hub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.BACK_DOCKER_USERNAME }} # 도커 허브 username
          password: ${{ secrets.BACK_DOCKER_TOKEN }} # 도커 허브에서 생성한 토큰

      - name: Build Docker image
        run: docker build -t ${{ secrets.BACK_DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:${{ github.sha }} . # Docker Image Build

      - name: Push Docker image
        run: docker push ${{ secrets.BACK_DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:${{ github.sha }} # Docker Image Push

  kustomize-update:
    runs-on: ubuntu-latest
    needs: docker-build-and-deploy

    steps:
      - name: Checkout repository
        uses: actions/checkout@v2

      - name: Switch to gateway-argo branch
        run: |
          git fetch
          git checkout gateway-argo

      - name: Set Kustomize
        uses: yokawasa/action-setup-kube-tools@v0.9.2
        with:
          kustomize: "3.7.0"

      - name: Update kubernetes manifest
        run: |
          cd config/deploy/gateway/
          kustomize edit set image ${{ secrets.BACK_DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
          git config user.name "GitHub Actions"
          git config user.email "<>"
          git add .
          git commit -m 'k8s manifest for ${{ github.sha }}'

      - name: Push changes
        uses: ad-m/github-push-action@master
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }} # 자동으로 생성되도록 함
          branch: gateway-argo

4. Argo CD 설치 및 구성 (K3s Cluster에 namespace 설정 및 Argo CD Pod 띄우기)

Argo CD
Getting started를 그대로 따라하면 된다.
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml : 필자는 UI로 Argo CD를 작업하기 위해 core install이 아닌 stable manifests를 install 했다.

또한 외부에서 접속하기 위해서는 Load Balancer를 사용하거나 Port-fowarding이 필요하다.
필자는 바로 적용해보기 위해 후자를 선택했다.
kubectl port-forward --address=0.0.0.0 svc/argocd-server -n argocd 8080:80

--address 옵션을 지정하지 않으면, localhost 혹은 127.0.0.1 과 같은 기본적인 로컬 주소가 사용된다. 이 경우에는 포트 포워딩이 로컬 머신의 루프백 인터페이스에만 바인딩된다고 한다.

5. Kustomize 작업 정의

gateway.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: gateway-dp

spec:
  selector:
    matchLabels:
      app: gateway
  template:
    metadata:
      labels:
        app: gateway
    spec:
      containers:
        - image: chancehee/gallery-gateway
          name: gateway
          env:
            - name: GALLERY_MEMBER_HOST
              value: "member-svc:8001"
            - name: REDIS_HOST
              value: "redis-svc"
            - name: REDIS_PORT
              value: "6379"
            - name: REDIS_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: gallery-secret
                  key: REDIS_PASSWORD
            - name: GALLERY_GALLERY_HOST
              value: "gallery-svc:8002"
            - name: GALLERY_POST_HOST
              value: "post-svc:8003"
          ports:
            - containerPort: 8000

---
apiVersion: v1
kind: Service
metadata:
  name: gateway-svc
spec:
  ports:
    - port: 8000
  selector:
    app: gateway

kustomization.yml

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- gateway.yml # 위에서 정의한 파일 이름

images:
- name: chancehee/gallery-gateway
  newTag: 6919d288ad46de5a0129f0883fb9bf3ed2b8c4a5 # GitHub Action에서 정의한 임의의 값 (SHA)

6. Argo CD Application 등록 (Deployment.yml change trigger 시점에 자동으로 동작시킬 작업)

결과 확인

gateway 뿐만 아니라 여러 개의 파이프라인을 구축했다.
Desired State와 Kubernetes Cluster State의 Sync가 일치하는 것을 확인할 수 있다.

0개의 댓글