Ssoon

Argo CD in Practice – 1) GitOps와 쿠버네티스 본문

CICD Study [1기]

Argo CD in Practice – 1) GitOps와 쿠버네티스

구구달스 2025. 10. 19. 15:16

 

🚀 GitOps and Kubernetes

“Declarative configuration과 Control Loop로 자동화된 클라우드 운영을 실현하다.”


🧭 1. GitOps란 무엇인가?

🔹 GitOps의 등장

GitOps라는 용어는 2017년 Weaveworks에서 처음 제안되었으며, 그들은 대표적인 GitOps 툴인 Flux를 개발했습니다.
GitOps는 빠르게 DevOps 이후의 차세대 운영 패러다임으로 자리 잡으며, “Operations via Pull Request”라는 개념으로 확산되었습니다.

즉, GitOps는 개발에서 사용하는 Git 기반 협업, 버전관리, CI/CD의 개념을 운영과 인프라 자동화에 적용한 것입니다.

"GitOps는 선언적 구성과 자동화된 동기화(Closed Loop)를 통해 인프라 상태를 Git으로 제어하는 운영 방식이다."


🔹 GitOps Working Group의 정의

GitOps Working Group(CNCF 산하)은 GitOps를 정의하는 5가지 원칙을 제시했습니다.

  1. Declarative Configuration – 명령형이 아닌 선언형으로 목표 상태를 정의
  2. Version-Controlled Immutable Storage – Git과 같은 버전관리 시스템에서 변경 이력 관리
  3. Automated Delivery – 수동 배포 없이 자동으로 변경사항 반영
  4. Software Agents – 클러스터의 상태를 모니터링하고 자동으로 조정하는 Agent
  5. Closed Loop – 실제 상태를 지속적으로 감시하며 선언된 상태와 일치하도록 유지

GitOps의 핵심은 “선언적 상태(Declarative State)”와 “자동 동기화(Control Loop)”입니다.
Git에 선언된 설정이 시스템의 진리(Single Source of Truth)가 되고, Agent가 자동으로 이를 반영합니다.


☸️ 2. Kubernetes와 GitOps

🔹 Kubernetes의 탄생

Kubernetes는 2014년 Google에서 내부 오케스트레이터 Borg의 경험을 바탕으로 오픈소스화되었고,
**CNCF(Cloud Native Computing Foundation)**의 첫 번째 시드 프로젝트로 성장했습니다.

CNCF는 오픈 거버넌스를 통해 특정 기업이 아닌 커뮤니티 중심의 의사결정 구조를 가지고 있습니다.
이 덕분에 Kubernetes는 빠르게 표준 오케스트레이션 플랫폼으로 자리 잡았습니다.


🔹 Kubernetes의 아키텍처

Kubernetes는 Control PlaneData Plane으로 구성됩니다.

🧩 Control Plane

  • API Server: 클러스터의 모든 요청이 통하는 중앙 진입점
  • etcd: 클러스터 상태(State)를 저장하는 Key-Value Database
  • Controller Manager: 상태를 지속적으로 감시하고 동기화하는 여러 Controller 관리
  • Scheduler: Pod를 어느 Node에 배치할지 결정
  • Cloud Controller Manager: 클라우드 환경과의 연동 담당

⚙️ Data Plane

  • Kubelet: Node와 API Server 간 통신 담당
  • Container Runtime: (Docker, containerd 등) 실제 컨테이너 실행
  • Kube-Proxy: 네트워크 트래픽 관리 및 Service 연결 처리

"Kubernetes의 중심은 API Server이며, 모든 구성요소는 이를 통해서만 통신한다."


🌐 3. Kubernetes API의 동작 원리

🔹 REST API Server

  • Kubernetes는 HTTP REST API를 기반으로 작동합니다.
  • 모든 동작(create, get, update, delete)은 API Server를 통해 이루어집니다.
  • 사용자는 kubectl 명령어를 통해 API를 호출하며, 실제 내부에서는 HTTPS 요청으로 전달됩니다.
kubectl get pods --v=9
  • 를 실행하면, 내부적으로는 GET /api/v1/pods 요청이 전송됩니다.

"kubectl은 단순한 CLI가 아니라, Kubernetes API를 호출하는 클라이언트다."


🔁 4. Controller Manager와 Control Loop

Kubernetes의 핵심 개념은 Control Loop입니다.

Control Loop는 다음 과정을 반복합니다:

  1. Observe – 현재 상태(Current State) 관찰
  2. Diff – 선언된 상태(Desired State)와 비교
  3. Act – 필요한 조치 수행
  4. Repeat – 상태가 일치할 때까지 반복

이 과정을 담당하는 것이 Controller입니다.

🔹 대표적인 Controller들

  • ReplicaSet Controller: 지정된 수의 Pod 유지
  • Deployment Controller: 버전 업데이트 및 롤백
  • HorizontalPodAutoscaler (HPA): 부하에 따른 자동 스케일링

"Controller는 시스템의 실제 상태를 선언된 상태로 지속적으로 맞추는 자동조정 메커니즘이다."


⚙️ 5. Imperative vs Declarative API

🔸 Imperative (명령형)

  • 사용자가 직접 구체적인 명령을 내리는 방식입니다.
kubectl create namespace test-imperative
kubectl create deployment nginx-imperative --image=nginx -n test-imperative
  • 명확하지만, 복잡한 리소스를 관리하기 어렵습니다.

🔸 Imperative + Config File

  • YAML 파일을 활용해 명령을 단순화할 수 있습니다.

namespace.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: imperative-config-test
kubectl create -f namespace.yaml
  • 이 방식은 관리가 용이하지만, 리소스가 존재할 경우 replace를 사용해야 하며, 충돌 시 기존 설정이 손실될 수 있습니다.

"Imperative 방식은 단순하지만 유지보수성이 떨어진다."


🔸 Declarative (선언형)

  • Declarative 방식에서는 “무엇을 할지”가 아닌 “어떤 상태를 원할지”를 정의합니다.
kubectl apply -f declarative-files/
  • 파일에 상태를 선언해두면, apply 명령으로 실제 상태를 자동으로 일치시킵니다.

namespace.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: declarative-files
  labels:
    namespace: declarative-files

"Declarative는 Kubernetes의 철학이며, GitOps의 핵심 원리다."


🧩 6. GitOps Operator 만들기

  • 간단한 GitOps Operator를 직접 구현
  • Operator는 Git Repository의 변경사항을 주기적으로 동기화하여 클러스터에 적용하는 역할을 합니다.

🔹 구현 순서

  1. Git Repository를 ClonePull로 최신화
  2. YAML Manifest를 kubectl apply로 적용
  3. 이 과정을 일정 주기로 반복 (Control Loop)

"이 간단한 Operator는 Argo CD의 기본 원리를 그대로 구현한 것이다."


  • kind k8s 배포
(⎈|N/A:N/A) ssoon@DESKTOP-72C919S:~$ kind create cluster --name myk8s --image kindest/node:v1.32.8 --config - <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  extraPortMappings:
  - containerPort: 30000
    hostPort: 30000
  - containerPort: 30001
    hostPort: 30001
  - containerPort: 30002
    hostPort: 30002
  - containerPort: 30003
    hostPort: 30003
EOF
Creating cluster "myk8s" ...
 ✓ Ensuring node image (kindest/node:v1.32.8) 🖼
 ✓ Preparing nodes 📦
 ✓ Writing configuration 📜
 ✓ Starting control-plane 🕹️
 ✓ Installing CNI 🔌
 ✓ Installing StorageClass 💾
Set kubectl context to "kind-myk8s"
You can now use your cluster with:

kubectl cluster-info --context kind-myk8s

Have a question, bug, or feature request? Let us know! https://kind.sigs.k8s.io/#community 🙂
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ k get node
NAME                  STATUS   ROLES           AGE   VERSION
myk8s-control-plane   Ready    control-plane   26s   v1.32.8
  • Go 설치
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ sudo apt install golang-go -y
[sudo] password for ssoon:
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
...
  • 배포할 매니페스트 파일
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch01$ tree basic-gitops-operator
basic-gitops-operator
├── go.mod
├── go.sum
└── main.go

1 directory, 3 files

(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch01$ tree basic-gitops-operator-config
basic-gitops-operator-config
├── deployment.yaml
└── namespace.yaml

1 directory, 2 files

 

  •  go run main.go 명령어로 GitOps 오퍼레이터를 실행
  • Go 모듈 다운로드
    • 필요한 라이브러리들이 자동으로 다운로드됩니다 (go-git, go-billy, go-diff 등).
  • Git 리포지토리 동기화 시작
    • Git에서 리소스(manifests)를 가져옵니다.
  • Kubernetes에 리소스 적용 시도
    • 먼저 namespace/nginx를 생성합니다.
    • 바로 이어서 deployment.yaml을 적용하려 했지만, nginx 네임스페이스가 아직 준비되지 않아 오류 발생:이는 네임스페이스 생성 직후 바로 deployment를 적용하려다 생긴 타이밍 문제입니다.
  • 5초 후 재시도
    • 다시 시도하니 deployment.apps/nginx가 정상적으로 생성됩니다.
    • 이후 반복되는 동기화에서는 변경 사항이 없으므로 unchanged로 표시됩니다.
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~/argo-cd-in-practice/ch01/basic-gitops-operator$ go run main.go
go: downloading github.com/go-git/go-git/v5 v5.4.2
go: downloading github.com/go-git/go-billy/v5 v5.3.1
go: downloading github.com/sergi/go-diff v1.1.0
go: downloading github.com/imdario/mergo v0.3.12
go: downloading github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7
go: downloading github.com/mitchellh/go-homedir v1.1.0
go: downloading github.com/emirpasic/gods v1.12.0
go: downloading github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99
go: downloading github.com/go-git/gcfg v1.5.0
go: downloading golang.org/x/sys v0.0.0-20210616094352-59db8d763f22
go: downloading github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351
go: downloading github.com/xanzy/ssh-agent v0.3.0
go: downloading golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b
go: downloading golang.org/x/net v0.0.0-20210520170846-37e1c6afe023
go: downloading gopkg.in/warnings.v0 v0.1.2
start repo sync
Enumerating objects: 1261, done.
Counting objects: 100% (125/125), done.
Compressing objects: 100% (32/32), done.
Total 1261 (delta 99), reused 97 (delta 93), pack-reused 1136 (from 1)
start manifests apply
namespace/nginx created
Error from server (NotFound): error when creating "/home/ssoon/argo-cd-in-practice/ch01/basic-gitops-operator/tmp/ch01/basic-gitops-operator-config/deployment.yaml": namespaces "nginx" not found
manifests apply error: exit status 1
 next sync in 5s
start repo sync
start manifests apply
deployment.apps/nginx created
namespace/nginx unchanged

 next sync in 5s
start repo sync
start manifests apply
deployment.apps/nginx unchanged
namespace/nginx unchanged
...
  • 생성 확인
(⎈|kind-myk8s:N/A) ssoon@DESKTOP-72C919S:~$ kubectl get deploy,pod -n nginx
NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx   1/1     1            1           52s

NAME                         READY   STATUS    RESTARTS   AGE
pod/nginx-5869d7778c-6qq9z   1/1     Running   0          52s

 


🏗️ 7. IaC (Infrastructure as Code)와 GitOps

🔹 공통점

  • 둘 다 코드로 인프라를 정의하고 Git에 버전관리한다는 점에서 매우 유사합니다.

🔹 차이점

항목 IaC GitOps

적용 방식 Push (CI/CD Pipeline이 배포) Pull (Agent가 자동 동기화)
주요 도구 Terraform, Ansible, CloudFormation Argo CD, Flux
실행 주체 Pipeline Controller / Operator
접근 권한 CI 시스템이 Production 접근 Agent가 내부에서 수행
방식 Imperative / Declarative 모두 가능 Declarative 전용

"IaC는 코드를 통한 자동화이고, GitOps는 지속적 동기화와 보안 중심의 자동화이다."


📌 핵심 요약

  • GitOps는 Git을 단일 진리 소스로 삼아 선언적 구성자동화된 제어 루프를 통해 운영을 자동화하는 방법론이다.
  • Kubernetes는 이러한 GitOps를 실현하기 위한 완벽한 기반을 제공하며, API Server와 Controller Manager가 중심 역할을 한다.
  • Imperative → Declarative → GitOps는 자연스러운 진화의 단계이다.
  • Argo CD 같은 GitOps Operator는 Git 변경사항을 클러스터에 자동 반영하여 **“Continuous Reconciliation”**을 수행한다.
  • IaC는 GitOps의 기반 철학이며, GitOps는 그 위에 자동화와 보안성을 더한 진보된 운영 모델이다.

“GitOps는 선언형 인프라의 완성형이다.
Git이 코드의 중심이었다면, 이제는 운영의 중심이 된다.”

Comments