argocd-설치-github-action-배포환경-구성

소개

이전까지는 어플리케이션 배포를 위한 CI/CD Pipeline 구성을 Github-Action(self-hosted) 을 이용하여 모두 구성하였었습니다.

이번에는 ArgoCD 를 이용하여 GitOps 기반으로 자동 배포 파이프라인을 고도화 해보려 합니다.

GitOps 를 위해 ArgoCD 를 구축하였고, 이전 포스트까지 구현하였던 인프라와 어플리케이션 기반으로 ArgoCD 로 전환한 절차를 정리해 봅니다.

ArgoCD 란?

ArgoCD 는 GitOps 기반으로 kubernetes 에 서비스를 배포하기 위한 도구입니다. Git Repository 를 기반으로 하여 manifest 들이 변경되면 그에 맞게 kubernetes 의 Resource 들을 sync 하면서 어플리케이션 배포를 자동화할 수 있게 됩니다.

ArgoCD 를 이용하면 아래와 같은 장점을 가져갈 수 있습니다.

  • 선언적으로 kubernetes resource 를 관리할 수 있습니다.
  • Git Repository 변경사항에 대해 자동으로 클러스터 상태를 동기화 할 수 있습니다.
  • Git 버전관리로 인해 롤백이 용이합니다.

배포 Pipeline 구성도

ArgoCD 구성을 통해 서비스 배포 파이프라인 구성은 최종적으로 아래와 같이 구성을 하고자 합니다.

argocd-배포

배포 절차는 아래와 같이 진행이 됩니다.

  • Application 개발 후 Github 으로 Push
  • Github Action(self-hosted) 을 통해 CI + Image 취약점 점검
  • Application 레포에 포함된 manifest 의 image tag 를 최신 값으로 수정
  • Argocd 의 Auto-sync 로 manifest 와 Kubernetes 클러스터 동기화
  • Application 최종 배포 완료

Application 은 기존에 만들어 두었던 node.js 로 만든 간단한 ingress traffic checker 를 사용하였습니다.

ArgoCD 설치

기본적으로 ArgoCD Docs 를 통해 상세한 설치 과정은 확인할 수 있습니다. 해당 절차를 바탕으로 설치를 진행해 봅니다.

먼저, argocd namespace 를 만듭니다.

# install argocd
kubectl create namespace argocd

helm 을 이용할 수도 있지만, 이번에는 install.yaml 을 기반으로 설치해봅니다.

# argocd 설치
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

argocd namespace 에 argocd 를 설치하고, 해당 namespace 에 잘 설치가 되었는지 확인해봅니다.

argocd-배포확인

이제 argocd 콘솔에 접속하기 위한 설정을 해줘야합니다. EKS 나 다른 클라우드 환경을 이용하고 있다면 설치시 Service type 을 LoadBalancer 로 변경하여 구성을 해줘야 합니다.

하지만 전 로컬환경에 구축한 kubernetes 환경이니 기본 ClusterIP type 으로 구성된 Service 에 port-forward 설정을 하여 로컬에서 접속할 수 있도록 설정하였습니다.

# nohup 을 이용한 background 로 port-forward 설정
nohup kubectl -n argocd port-forward argocd-server-74759b8c98-l2rzx 40080:8080 &

port-forward 설정을 해주고 localhost:40080 으로 접속하여 콘솔 접속 가능여부를 확인합니다.

argocd

잘 접속되는지 확인이 되었다면, admin 계정 접속을 하기 위해 password 를 확인합니다. argocd 구축시 생성된 initial-admin-secrets 를 통해 초기 password 를 확인하여 로그인합니다.

# get default admin password of argocd
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d

ArgoCD – Github 연동

먼저, Github Personal access Token 발행 페이지에서 아래와 같이 scopes 를 적용하여 token 을 만듭니다.

github-personal-access-token

ArgoCD 에서 kubernetes cluster 에 서비스를 배포하기 위해 동기화할 manifest 는 아래와 같이 application 레포내 별도의 manifest 폴더를 만들어 kustomize 구조로 만들었습니다.

ArgoCD 는 이제 해당 폴더를 바라보면서 kubernetes 리소스를 동기화 할 것입니다.

github-tree

이제 argocd settings 에서 연동할 github repository 설정을 통해 연동을 진행합니다. 여기서 미리 만들어 두었던 github personal token 을 password 로 설정합니다.

argocd-setting

Repo 연동이 완료되면, Application 을 추가해줍니다.

argocd-applications

argocd-applications

추가하여 제대로 sync 가 되어 배포가 되었는지 확인합니다.

argocd-applications

Github Action 으로 CI 구성 및 자동 배포 확인

이제 application 변경에 대한 CI 과정에서 image 가 변경되면, ArgoCD 가 최신 상태의 배포를 제대로 진행하는지 확인해봅니다.

github action 을 아래와 같이 구성하였습니다. Push 를 하게 되면 image build 를 하고 Trivy 를 통해 이미지 취약점 점검을 합니다.

완료가 되면 docker-hub 에 이미지를 푸쉬하고, 최신 image tag 를 적용한 manifest 로 업데이트합니다.

그렇게 manifest 변경이 일어나면 ArgoCD 가 위에서 완료한 설정 기반으로 auto-sync 를 하여 클러스터 내 서비스를 재배포하게 됩니다.

name: ci

on:
  push:
    branches:
      - main

permissions:
  id-token: write
  contents: read

jobs:
  build:
    runs-on: self-hosted
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Log in to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_TOKEN }}

      - name: Build Docker image
        uses: docker/build-push-action@v5
        with:
          context: .
          load: true
          tags: ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_REPOSITORY }}:${{ github.sha }}
          build-args: |
            DB_HOST=${{ secrets.DB_HOST }}
            DB_PORT=${{ secrets.DB_PORT }}
            DB_USER=${{ secrets.DB_USER }}
            DB_PASSWORD=${{ secrets.DB_PASSWORD }}
            DB_DATABASE=${{ secrets.DB_DATABASE }}

      - name: Run Trivy vulnerability scanner
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: "${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_REPOSITORY }}:${{ github.sha }}"
          format: "table"
          exit-code: "0"
          ignore-unfixed: true
          vuln-type: "os,library"
          severity: "CRITICAL,HIGH"

      - name: Push Docker image
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_REPOSITORY }}:${{ github.sha }}
          build-args: |
            DB_HOST=${{ secrets.DB_HOST }}
            DB_PORT=${{ secrets.DB_PORT }}
            DB_USER=${{ secrets.DB_USER }}
            DB_PASSWORD=${{ secrets.DB_PASSWORD }}
            DB_DATABASE=${{ secrets.DB_DATABASE }}

      - name: Image digest
        run: echo "Image pushed with digest ${{ steps.build-and-push.outputs.digest }}"

      - uses: azure/setup-kubectl@v3

      - uses: azure/k8s-set-context@v4
        with:
          method: kubeconfig
          kubeconfig: ${{ secrets.KUBE_CONFIG }}

  update-manifest:
    needs: build
    runs-on: self-hosted
    steps:
      - uses: actions/checkout@v4
        with:
          repository: ${{ github.repository }}
          ref: "main"
          token: ${{ secrets.GIT_PAT}}

      - name: Install Kustomize
        run: |
          curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
          sudo mv kustomize /usr/local/bin/

      - name: Update image tag in manifest
        env:
          KUBE_CONFIG: ${{ secrets.KUBE_CONFIG }}
          REGISTRY: ${{ secrets.DOCKER_USERNAME }}
          REPOSITORY: ${{ secrets.DOCKER_REPOSITORY }}
          IMAGE_TAG: ${{ github.sha }}
        run: |
          cd manifest/overlays
          kustomize edit set image $REGISTRY/$REPOSITORY=$REGISTRY/$REPOSITORY:$IMAGE_TAG

      - name: Commit updated Kustomize config
        run: |
          git config --global user.name ${{ secrets.GIT_EMAIL }}
          git config --global user.email ${{ secrets.GIT_USERNAME }}

          git add -A
          git commit -m "Update image tag to ${{ github.sha }} in manifest [skip ci]"
          git push origin main

해당 Action workflow 를 적용하였으면 신규 Push 를 발생하여 ArgoCD 를 통해 서비스가 제대로 배포가 되었는지 확인해봅니다.

argocd-applications

Refs

Series Navigation<< Github Self-hosted runner 구축 후 배포 Pipeline 만들기

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

Back To Top