개요
이 시리즈는 코드로 인프라를 구축하는 IaC(Infrastructure as Code)를 이해하기 위해 작성했다.
AWS의 EKS 클러스터를 코드로 구축하고 ArgoCD를 이용해 클러스터 내 어플리케이션을 배포한다.
인프라 구성 방법을 개개인의 노하우와 숙련도가 아닌 자산으로 코드로 남길 수 있도록 한다.
목표
- Gitops의 개념과 필요성에 대해 알아본다
- Gitops를 통해 클러스터 내 환경을 빠르게 구축하는 방법을 알아본다.
여정
이 글에서는 완전히 실행 가능한 코드를 다루고 있지 않습니다!
대신 충분한 힌트는 드리고 있으니 양해 부탁드립니다!
클러스터 생성하면 끝 아닌가요?
아니다!
어플리케이션 자동 배포를 신경쓰지 않는다면
아래와 같은 상황에 직면하게 될 것이다.
클러스터가 1개라면? → 어플리케이션 N개 배포
클러스터가 9개라면? → 어플리케이션 N개 * 9번 배포
환경변수가 50개인데 운영환경이 3종류라면? ...
어플리케이션 설정이 제대로 되었는지 확인하는 것만으로 엄청난 시간이 소요된다.
그것도 배포, 삭제할 때마다 발생한다!
결국 IaC로 클러스터를 빠르게 생성하게 되었어도,
어플리케이션 배포에서 병목현상이 발목을 잡게된다.
그럼 어떻게 해야되나요?
이렇게 어플리케이션 배포에 관한 모든 것을
선언형 코드로 작성하여 관리하고 프로비저닝하는 방법을 GitOps라고 한다.
(위브웍스(WeaveWorks)에서 만든 단어이다!)
핵심 아이디어는 크게 두가지이다.
- 배포에 관련된 모든 것을 선언형 기술서 형태로 작성하여 Config Repository에서 관리
- Config Repository의 선언형 기술서와 운영 환경 간 차이가 없도록 유지하는 자동화 시스템 구성
쉽게 말해서, Git 레포지토리와 CD 도구(ArgoCD, Tekton 등)의 조합으로 실천할 수 있다는 뜻이다.
여기서 중요한 것은, 선언형 기술서를 단 Git 한곳,
즉, 단일 진실 공급원(Single Source Of Truth, SSOT)에서만 관리하도록 해야한다는 점이다.
이렇게하면, Git을 사용할 때 누렸던 강력하고 익숙한 기능을 클러스터 운영에도 활용할 수 있게 된다.
적용 예시
예를 들어 Git 레포지토리에 Argo CD를 적용한다고 해보자.
ArgoCD에서 제공하는 쿠버네티스 리소스를 활용하면 쉽게 구현할 수 있다.
먼저, 제일 간단한 리소스부터 보도록 하자.
apiVersion: v1
kind: Secret
metadata:
name: airflow-helm
labels:
argocd.argoproj.io/secret-type: repository
stringData:
name: "airflow"
url: "https://airflow.apache.org"
type: "helm"
---
apiVersion: v1
kind: Secret
metadata:
name: gitops-repo
labels:
argocd.argoproj.io/secret-type: repository
stringData:
insecure: "true" # Ignore validity of server's TLS certificate. Defaults to "false"
forceHttpBasicAuth: "true" # Skip auth method negotiation and force usage of HTTP basic auth. Defaults to "false"
enableLfs: "true" # Enable git-lfs for this repository. Defaults to "false"
type: "git"
url: ""
password: ""
username: ""
ArgoCD에서 Repository는 Secret에 어노테이션을 추가한 형태로 동작한다.
주로 Helm이나 Git Repository를 등록할 수 있다.
Private Repository라면, 접근 시, Credential이 필요하다.
이 때 파일 내에 직접 정보를 적어넣는 것은 권장되지 않는다.
주로 이를 해결하기 위해 사용되는 방법은 Kustomize와 Helm이다.
이를 통해서 Secret을 유동적으로 생성할 수 있다.
다음은 이 Repository를 사용할 AppProject를 생성해보자.
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: gitops-project
finalizers:
- resources-finalizer.argocd.argoproj.io // 삭제방지
spec:
description: "gitops-project"
sourceRepos:
- https://github.com/example/repo1.git // 여기서 Repository 등록가능
- https://github.com/example/repo2.git
- "*" // 전부 허용도 가능하다
destinations:
- namespace: '*'
server: https://kubernetes.default.svc
clusterResourceWhitelist:
...
namespaceResourceBlacklist:
...
namespaceResourceWhitelist:
...
roles:
...
AppProject는 클러스터 내에서 어플리케이션이 속할 그룹과도 같다.
AppProject에 속한 어플리케이션들은 지정한 행동만 수행할 수 있다.
AppProject는 아래와 같은 속성을 가진다.
- sourceRepos : clone할 repository주소
- destinations : 배포할 클러스터 주소
- clusterResourceWhitelist : 클러스터 단위의 리소스 중 허용할 동작
- clusterResourceWhitelist : 클러스터 단위의 리소스 중 거부할 동작
- namespaceResourceBlacklist : 네임스페이스 단위의 리소스 중 거부할 동작
- namespaceResourceWhitelist :네임스페이스 단위의 리소스 중 허용할 동작
- roles : 해당 프로젝트가 허용된 동작 내에서 권한을 설정한 역할
보통 default라는 기본 프로젝트가 생성되어 있으며, 모든 동작을 허용한다.
물론 단일 사용자라면 default 프로젝트를 사용하거나, 동작을 전부 허용해도 무방하지만,
여러 사용자가 사용한다면, 허용/거부 동작과 Role 구분까지 마치는 것을 권장한다.
이제 이 프로젝트를 사용하여 GipOps Application을 작성한다.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: gitops
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: gitops-project
sources:
- repoURL: https://github.com/example/gitops-repo.git
targetRevision: main
path: apps
destination:
server: https://kubernetes.default.svc
namespace: default
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
이렇게 작성한 첫번째 Application은 아래와 같은 의미를 지닌다.
- gitops-repo 주소에서
- main 브랜치 내의
- apps 경로의 yaml 파일을 배포한다. (두번째 Application)
해당 yaml 파일은 두번째 Application이 되고,
실제로 어플리케이션을 배포할지 작성하면 완성이다.
이렇게 Application이 다시 Application을 배포하는 패턴을 Apps Of Apps 패턴이라고 한다.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: apps-of-apps
spec:
project: gitops-project
sources:
- repoURL: https://github.com/example/repo1.git
targetRevision: main
path: /
- repoURL: https://github.com/example/repo2.git
targetRevision: release
path: /public
마무리
지금까지 Gitops의 개념과 필요성에 대해 학습하고
이를 통해 ArgoCD로 실제 클러스터에 배포하는 방법을 알아보았다.
이렇게해서 코드로 구축하는 인프라, IaC 시리즈를 마무리하려고 한다.
부디 반복노동에서 벗어나서 서비스에 집중할 수 있는 환경이 되길 기원드린다!
참고자료
데브옵스의 확장 모델 – 깃옵스[GitOps] 이해하기 | 인사이트리포트 | 삼성SDS (samsungsds.com)
Declarative Setup - Argo CD - Declarative GitOps CD for Kubernetes (argo-cd.readthedocs.io)
'DevOps' 카테고리의 다른 글
[쿠.짤] 쿠버네티스 짤팁 | KinD로 Local Kubernetes 구축하기 (0) | 2024.01.03 |
---|---|
[쿠.짤] 쿠버네티스 짤팁 | 자원 요구사항을 정의하자! (QoS, Priority Class, Resource Quota, LimitRange) (0) | 2023.12.22 |
코드로 클러스터 구축하기 - (3) 클러스터 생성 (0) | 2023.08.10 |
코드로 클러스터 구축하기 - (2) 네트워크 생성 (0) | 2023.08.10 |
코드로 클러스터 구축하기 - (1) AWS 네트워크 기본 개념 (0) | 2023.08.10 |