-
k8s + git-action-argocd로 간단하게 GitOps 구축하기Infrastructure 2023. 4. 22. 02:06
팔자에도 없을 거라고 생각했던 쿠버네티스를 시작한지 어언 1년, 이제는 그래도 나름 한 서비스 배포 프로세스를 구축할 정도로는 올라온 것 같다.
회사 홈페이지의 백엔드 배포 프로세스를 재정립하려고 뜯어보니, 나름 프로세스가 잡혀있었으나 여전히 손이 가는 부분이 여럿 있었다.
예를 들어 template ec2에 ssh로 직접 접속하여 AMI를 만들고 올라간 버전을 직접 오토 스케일링 그룹에 적용 시키는 부분들. 사실 정석?(인프라 바닥부터 배우는 중이라...)이라고 생각하지만 우선 나는 아마존 콘솔에 OTP치고 로그인하는것도 귀찮은 사람이라 조금 더 자동화 해보기로 했다.
우선 목표는 최대한 자동화 하는 것, 물론 자동화가 만능은 아니라지만 branch 전략으로 많이 잡을 수 있을 것이라고 생각하고 기존에 돌고 있던 클러스터 환경에 git action과 argocd 적용해보는걸 목표로 작업했다.. 코드도 공유하고 싶지만 private github에 올려놓아서 공유가 안되는게 좀 아쉽구만..
그래서 배포 프로세스를 다음과 같이 잡아보기로함
1. dev 브랜치에 코드가 들어가면 개발 서버가 업데이트
2. main 브랜치에 코드가 들어가면 운영 서버가 업데이트
우선 main브랜치는 PR로만 코드를 넣을 수 있게끔 설정했고, dev브랜치는 개발 중에는 바로바로 push가 가능하지만 나중에는 여기도 PR기반으로 코드를 넣게끔 해야 할 것 같다.
git action은 뭘까? 간단하게 github 훅이라고 생각해보면 좋을 것 같다. (물론 깃에 진짜 훅 따로 있음...보통 커밋 메시지에 JIRA 티켓 번호같은거 검증하는데 많이 사용하는데 이건 github말고 git의 훅이고..)
git-action에다가 어떤걸 정의하냐면, 어떤 브랜치(dev, main)에 어떤 작업(커밋이 올라오면, PR이 올라오면)이 일어나면 뭘(프로젝트 테스트, 빌드, 등) 해라 라는 것을 yaml로 정의할 수 있다. 보통 프로젝트 루트에 .github/workflows폴더에 yaml파일의 형태로 선언한다.
이번 경우는 두 브랜치에서 작업이 일어나니, dev.yaml과 main.yaml 두개를 만들...려고 했으나 PR이 올라오면 그 안에서도 유닛 테스트 및 빌드를 돌리고 싶어서 pr.yaml까지 총 3개를 만들었다.
아무리 그래도 코드 없이 넘어가긴 좀 그래서 예제 코드를 좀 살펴보면 아래와 같은 형식이다.
name: test and build and push!! on: push: branches: - dev jobs: build: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v2 - name: Setup Docker Buildx uses: docker/setup-buildx-action@v1 - name: Login docker hub uses: docker/login-actions@v1 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push uses: docker/build-push-action@v2 with: context: . file: ./Dockerfile platforms: linux/amd64 push: true tags: ${{ ... }}
코드는 엄청 간단하다. on(언제) - push(푸쉬가 일어나면) - branches(어떤 브랜치에)라고 조건을 설정하고 jobs에서 runs-on(어떤 환경에서 job들을 실행할지), steps에서 실행하고자 하는 동작들을 선언해준다. tag에는 워낙 다양한게 들어올 수 있는데, build-number를 이용해서 숫자를 하나씩 올려가는 방법도 있고, github에 tag달아서 올린다면 그 tag를 가져와서 쓰는 라이브러리도 있다. 니즈에 맞게 잘 가져다 쓰면 될 듯.
여기까지 잘 세팅했다면 dev브랜치에 코드를 넣으면 자동으로 도커 이미지를 빌드해서 태그를 붙이고 도커 허브에 넣어준다. 이 때 하나 고민한게 있는데, nodejs 서버의 .env를 도커 이미지 만들때 같이 만들어서 넣을까 아니면 configMap으로 관리할까 였다. 보통 컨피그맵으로 관리하면 편하긴 한....데 어쨋든 비밀값들이 깃헙에 공개(프라이빗 레포지토리긴 해도 팀원들도 다 볼 수 있는건 마찬가지니까...)되는게 싫어서 그냥 github의 secrets으로 관리하기로 하고, yaml에다가 .env를 같이 만들어서 도커 이미지를 빌딩하도록 세팅했다. 뭐 물론 이렇게 해도 컨피그맵으로 환경 변수 정도는 얼마든지 조절 가능하긴 하니까...
그리고 요걸 쿠버네티스에서 관리하기 위한 차트 레포지토리를 만들고, 적절하게 차트를 만들어서 넣어줬다. 구성은 그냥 있을 거 다 있는 구성, statefulset(개인적으로 파드 이름이 결정적으로 떨어져서 선호), L4 loadbalancer service, ingress, hpa 등 넣어주고
그리고 helm으로 클러스터에 argo-cd를 설치해준다. argo-cd에 대해 간단히 설명하자면 GitOps를 도와주는 녀석! 지정한 차트 레포지토리를 바라보면서, 어떤 차트의 values.yaml이 바뀌면 그 변화를 자동으로 클러스터에 적용시켜주는 굉장히 편리한 배포 툴이다. 그래서 딱 얘기한거처럼 배포한 argocd 대시보드에 접속해서 비밀번호를 재설정 한번 해주고, 차트 레포지토리를 등록한다음 개발 서버와 배포 서버, redis같은 녀석들을 배포해줬다. 이제 끝!
argo-cd에 대해 팀원들과 이야기를 나누면서, 권한이 생각보다 막강한데 아이디와 비밀번호로 대시보드 접근하는게 보안상 위험할 수 있을 것 같다는 이야기를 나눴다. 나도 공감하는 내용이라, 어떻게 해결할 수 있을까 생각해봤는데 (아직 적용은 못했지만) 사인된 커밋만 바라보는 기능들이 있어서 유저 키를 등록해서 조금 더 안전하게 관리할 수 있지 않을까 싶긴하다.
그리고 git-action을 이용하면 다른 레포지토리에 값을 수정하는 기능도 구현 가능하다고 알고 있는데, 아직 이 기능까지 적용하진 않았다. 한창 배포 프로세스를 다잡는 중이어서 argocd를 다루는 부분은 아직 수동으로 남겨두고 싶은 나의 마음이랄까.. 언젠가는 요 부분까지 자동화 해두면 코드 커밋 프로세스를 통해서 배포를 엄청 편하게 할 수 있을 것 같다고 생각한다.