개요 목적
이번 시간에는 Git과 코드 구성으로 배포를 쉽게 관리할 수 있는 GitOps 이론을 파악한다. 그리고 Kubernetes 안에 종속되는 GitOps 도구인 ArgoCD를 사용하여 SpringBoot 서버를 배포하는 방법에 대해서 알아본다.
GitOps란
GitOps란 DevOps의 실천 방법 중 하나로, 애플리케이션 배포와 운영에 관련된 요소들을 코드로 작성하여 Git에서 관리하는 것이다. 대표적인 예로, Kubenetes Manifest 파일을 Git에 저장하고 그 파일을 이용하여 클러스터에 어플리케이션을 배포한다.
GitOps의 장점
- 생산성
Git 레포지토리의 변경을 자동으로 추적하여 kubernetes 클러스터 업데이트를 할 수 있다. 운영에서 배포까지 Git으로 관리할 수 있는 편리성이 제공된다.
- 안정성
GitOps 워크플로를 도입하면 외부에서 이루어진 Kubernetes 클러스트에 대한 변경 감사 로그를 자동으로 검색할 수 있다. 이렇게 하면 “누가, 언제, 무엇을 했는지"가 로그로 남아 있으므로 문제 해결이 더 쉬워진다.
- 신뢰성
사람의 수동으로 인한 커맨드 실수를 방지할 수 있고, 롤백의 경우도 Git을 통해 관리 재현성 높은 오퍼레이션이 가능하다.
- 보안성
일반적인 CI/CD 툴을 자격 증명이 된 kubectl을 사용해 클러스터 배포하기 때문에 자격 증명이 노출된다는 보안성 허점이 있다.
반면에 GitOps는 클러스터를 변경하기 위해 Pull을 사용하여 자격 증명을 외부에 공개하지 않고 배포할 수 있는 보안성 이점이 있다.
GitOps 도구
- Argo CD
Arogo CD에서는 알기 쉬운 GUI를 제공한다. 수동 Sync 등 모든 조작을 GUI에서 할 수 있다.
- Flux CD
GitOps를 제시한 Weaveworks사의 도구로 제작이 간단하고 경량이지만, GUI를 제공하지 않는다.
- Jenkins X
Jenkins에서 나온 도구로, 이 도구에서는 CI/CD에 대응한 파이프라인 자체를 구축 가능하다.( Argo CD와 Flux CD는 CD 기능만 가능하다)
GitOps 배포 전략 2가지
- Push Pipeline
푸시 기반 배포 전략은 Jenkins, CircleCI 또는 Travis CI와 같은 널리 사용되는 CI/CD 도구로 구현된다. 애플리케이션 코드가 업데이트 될 때마다, CI 시스템으로 시작하여 일련의 인코딩된 스크립트를 거치거나 수동으로 'kubectl'을 사용하여 Kubernetes 클러스터에 변경 사항을 적용한다. 간단한 아키텍처로 배포를 할 수 있지만, 클러스터 외부에서 작업하기 때문에 자격 증명이 노출되는 보안상 문제가 있다.
- pull pipeline
배포하려는 클러스터에 위치한 별도의 오퍼레이터가 배포 역할을 대신하는 구조이다. 해당 오퍼레이터는 Git Repo의 Manifest와 배포 환경을 지속적으로 비교하다가 차이가 발생할 경우, Git Repo의 Manifest를 기준으로 클러스터를 유지시켜 준다. Pull 방식의 파이프라인는 GitOps 도구에서 이미지를 가져오고 자격 증명은 클러스터 내부에 보관되어, 보안 정보가 외부에 노출되지 않고 실행할 수 있다.
ArgoCD를 사용하여 SpringBoot 서버 배포하기
이제 아래 무식한 영어 프로젝트를 , AWS EKS 내부에 있는 ArgoCD과 Github에 저장되어 있는 HelmChart 파일을 연동하여 클러스터 배포하는 방식에 대해서 알아본다.
전체과정은 아래와 같다.
- 무식한 영어 프로젝트 코드 업데이트 깃 허브 커밋
- 젠킨스 빌드 (업데이트 된 프로젝트 파일 깃에서 가져와서, 해당 프로젝트 도커 이미지 생성 도커 허브에 올리기, 그리고 헬름 차트에 수정된 도커 이미지 이름으로 수정)
- ArgoCD 적용 (깃 허브에 저장되어 있는 헬름 차트 변화 감지 → GitOps 스스로 클러스터에 변화된 내용 적용)
2. 젠킨스 빌드 코드 설명
위에서 설명한 과정을 빌드하는 젠킨스 코드는 아래와 같다. 젠킨스를 적용하는 방법에 대해 좀 더 자세히 알고 싶으면 아래 글을 참고하면 좋다.
Springboot(gradle) Jenkins 설정으로 Ubuntu 자동 배포하기
pipeline {
agent any
environment {
registryCredential = 'DockerHub_IdPwd'
//젠킨스 빌드 버전마다 이미지를 새롭게 만들기 위해 이미지 뒤에 빌드 넘버를 붙인다.
apiImageName = 'hwangdy/api:'+ "${env.BUILD_NUMBER}"
plusImageName = 'hwangdy/plus:'+ "${env.BUILD_NUMBER}"
uiImageName = 'hwangdy/ui:'+ "${env.BUILD_NUMBER}"
dockerImage = ''
}
stages {
// git에서 영어 프로젝트 가져오기
stage('Prepare') {
steps {
git url: '<https://github.com/dae0hwang/Ignorant_English_Service>', branch: 'master'
}
}
// 1 API 서버 진행
// gradle build
stage('API Bulid Gradle') {
agent any
steps {
echo 'Bulid Gradle'
//이부분
dir ('../argo-english/API') {
bat 'gradlew clean build'
}
}
}
// docker build
stage('API Bulid Docker') {
agent any
steps {
echo 'Bulid Docker'
dir ('../argo-english/API') {
script {
dockerImage = docker.build "${apiImageName}"
}
}
}
}
// docker push
stage('API Push Docker') {
steps {
echo 'Push Docker'
script {
docker.withRegistry('', registryCredential) {
dockerImage.push()
}
}
}
}
// 2 PLUS 서버 진행
// ... 생략
// 3 UI 서버 진행
// ... 생략
// git에서 HelmChart 가져오기
stage('Prepare Helm') {
steps {
dir ('../argo-english@tmp') {
git url: '<https://github.com/dae0hwang/helm-chart>', branch: 'master'
}
}
}
//value.yaml 파일을 변경하기
stage('update Helm') {
steps {
dir ('../argo-english@tmp/helm-english') {
script {
def filename = 'values.yaml'
def data = readYaml file: filename
data.image.api= "${apiImageName}"
data.image.ui= "${uiImageName}"
data.image.plus= "${plusImageName}"
writeYaml file: filename, data: data, overwrite: true
}
}
}
}
//변경된 HelmChart 파일 깃허브에 업데이트하기
stage('push Helm to git') {
steps {
dir ('../argo-english@tmp') {
withCredentials([gitUsernamePassword(credentialsId: 'git-hub-credential', gitToolName: 'git-tool')]) {
bat 'git add .'
bat 'git config --global user.email "geungan9@gmail.com"'
bat 'git config --global user.name "dae0hwang"'
bat "git commit -m argo"
bat 'git push --set-upstream origin master'
}
}
}
}
}
}
3. EKS - ArgoCD 적용
- 먼저 AWS CLI를 사용하여 window local과 eks를 연결한다.
#aws access 토큰으로 로그인하기
aws configure
자신의 acess key ID와 secrete key region 정보를 입력하여 접속한다.
#해당 region에 생성한 eks name 입력하여 eks 연결하기
#aws eks --region (리전입력) update-kubeconfig --name (생성한eks이름)
aws eks --region ap-northeast-2 update-kubeconfig --name eks
그러면 .kube config 파일이 생성된다.
이 이후로 kubectl을 통해서 eks 조작이 가능하다.
- ArgoCD 다운로드
EKS에 ArgoCD가 실행될 수 있도록 적용한다.
#namespace 생성
kubectl create namespace argocd
#다운로드
kubectl apply -n argocd -f <https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml>
#외부 접속을 하기 위해 service를 loadbalance type으로 변경
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
#argocd에 입장할 비밀번호 확인 아이디는 "admin"이다.
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo
- ArgoCD application 등록하기
해당 내용으로 ArgoCD를 적용하게 되면, HelmChart가 있는 깃허브에 내용이 없데이트 될 때마다 클러스터에서 실행되고 있는 인스턴스와 비교하여 새롭게 인스턴스 배포를 적용한다.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: english
spec:
destination:
name: ''
namespace: default
server: '<https://kubernetes.default.svc>'
source:
path: helm-english
repoURL: '<https://github.com/dae0hwang/helm-chart>'
targetRevision: master
helm:
valueFiles:
- values.yaml
sources: []
project: default
syncPolicy:
automated:
prune: false
selfHeal: false
'리눅스 인프라 > Docker, Jenkins, Kubernates' 카테고리의 다른 글
클라우드 서비스 공부 내용 블로그 정리 (0) | 2023.09.07 |
---|---|
Rolling update와 Blue/Green 배포 패턴에 대한 이해, Argocd(Rollouts)을 사용한 Blue/Green 배포 방법 (0) | 2023.06.27 |
AWS VPC에 대한 이해와 VPC 내 private 통신하기 (0) | 2023.06.25 |
Kubernetes - LoadBalancing 사용하여 Spring Boot 서버 운영하기 (0) | 2023.06.08 |
kubernetes 구성 요소에 대한 이해 (0) | 2023.06.08 |