본문 바로가기
AI

[책 정리] 인프라 구성 · 배포 with 클로드 코드 - (3)

by interlude-3 2026. 7. 18.

Chapter 5.    무중단 배포

 

배포 위험을 최소화하려면 어떤 방법이 좋을까

 

 

 

기존 Rolling Update

- Rolling Update만으로도 대부분의 경우 서비스 중단 없이 배포할 수 있다.

- 하지만 새 버전에 문제 발생 시 즉시 영향을 차단하기 어렵고,

- 신규 버전으로 전달되는 트래픽을 단계적으로 조절하여 검증할 수 없다.

 

해결 방안

- Argo Rollouts를 이용한 Canary / Blue-Green 배포

- Gateway API를 이용한 트래픽 라우팅

=> 단계적인 트래픽 전환을 통해 안전하게 배포 가능하고, 문제 발생 시 빠른 Rollback이 가능하다.

 

Argo Rollouts 사용

  • 기존 버전과 신규 버전 Pod를 동시에 실행
  • Gateway API를 통해 트래픽 비율을 단계적으로 조절
  • 단계별 검증 후 점진적으로 신규 버전 확대
  • 이상 징후 발생 시 기존 버전으로 즉시 Rollback

+ Gateway API

  • Kubernetes 커뮤니티(SIG-Network)가 표준으로 개발하는 API     
    (** SIG-Network - Kubernetes의 네트워크 기능을 설계·개발·관리하는 공식 커뮤니티 그룹)
  • Kubernetes에서 외부 또는 내부 트래픽이 애플리케이션으로 들어오는 방식을 선언적으로 관리
  • Argo Rollouts가 지정한 비율(10%, 30% 등)에 따라 실제 사용자 트래픽을 기존 버전과 신규 버전으로 분산

기존 Ingress 트래픽 흐름

Client
   │
Ingress
   │
Service
   │
Pod

 

Gateway API 트래픽 흐름

Client
   │
Gateway
   │
HTTPRoute
   ├── Service A (90%)
   └── Service B (10%)

 

Gateway API  vs  Istio

 

- 카나리/블루그린 배포만 필요, ingress 대체를 위한 표준 API, 단순하고 가벼운 구성 => Gateway API 선택

- 서비스 메시 필요, 서비스간 통신 제어 필요 => Istio 선택

 

 

5장에서는 Gateway API와 Argo Rollouts를 이용해

트래픽 기반 무중단 배포 환경을 구축하고, Blue-Green 배포를 구현한다.

 

 

 

Q. Canary / Blue-Green 방식은 서비스가 안끊기나?

A. Rolling Update뿐만 아니라 Canary, Blue-Green도 애플리케이션이 실제 요청을 처리할 준비가 되기 전에 트래픽을 받으면 일시적인 오류가 발생할 수 있다.
다만 Canary와 Blue-Green은 소량의 트래픽만 먼저 전송하거나(Canary), 전체 전환 전에 충분히 검증한 뒤(Blue-Green) 트래픽 전환이 가능하므로, 이러한 초기화 문제를 사전에 발견하고 전체 사용자에게 영향을 주기 전에 대응할 수 있다는 장점이 있다.

 

1. Gateway API 구축 (외부 진입점 생성)

 

Gateway API 주요 구성 리소스

 

1) GatewayClass

  • Gateway 구현체를 정의
  • 예: Istio, Cilium, NGINX Gateway Fabric

2) Gateway

  • 실제 트래픽 진입 지점
  • Listener(HTTP, HTTPS 등)를 정의

3) HTTPRoute

  • 요청을 어떤 Service로 보낼지 정의
  • Path, Header, Weight 기반 라우팅 가능

 

Gateway API 구축 진행 순서

a. GatewayClass 리소스 존재 여부 확인 (Gateway API 활성화 여부 확인, 실습에서는 GKE Gateway 사용)

b. Gateway 리소스 생성 (외부 IP + HTTP listeners 정의)

c. HTTPRoute 리소스 생성 (어떤 경로의 요청을 어떤 서비스로 보낼것인가 정의)

d. HealthCheckPolicy 리소스 생성 <- GKE Gateway에서 health check를 위해 제공하는 확장 리소스

e. proxy-only 서브넷 확인
   (GKE Gateway에서 사용하는 Google 관리형 프록시의 전용 서브넷. 기존 VPC 서브넷과 겹치지 않게 설정)

f. 외부 접속 테스트

 

더보기

** gke cluster 설치 시 --gateway-api=standard 옵션을 추가하여 이미 설치되어 있음

 

 

2. Blue/Green 배포 테스트 (안전한 배포)

 

Argo Rollouts 장점

  • Canary와 Blue-Green을 모두 지원한다.
  • Gateway API, Istio, NGINX, ALB 등 다양한 트래픽 관리 도구와 연동할 수 있다.
  • ArgoCD와 함께 사용하는 사례가 많아 GitOps 환경과 잘 어울린다.

Argo Rollouts vs Flagger

  • 배포 과정을 직접 제어하고 싶다면 → Argo Rollouts
  • 메트릭을 기반으로 자동 Canary를 운영하고 싶다면 → Flagger

 

Argo Rollouts 구축 진행 순서

a. Argo Rollouts Controller 설치

b. kubectl argo rollouts 플러그인 설치

c. Deployment에서 Rollout으로 전환

d. 'notiflex-api-preview' Service 생성  ->  새 버전(Green)을 미리 확인하는 용도. 외부IP 필요X

e. 새로운 이미지 (v0.2.0) 빌드 및 Blue/Green 배포 테스트

f. auto-promote 동작 확인

 

 

3. 새 버전 배포 후 실제 전환 과정 확인

 

 


 

Chapter 6.    엔터프라이즈를 위한 기반 정비

 

 

서비스 안정성과 운영 효율성을 위해 Cache, Secret, 배포 관리 체계 개선

 

 

1) Cache

 

Cache가 없는 경우

기존에는 API 서버에서 자주 조회하는 데이터를 Pod 내부 메모리에 저장하여 사용

  • Pod마다 메모리 공간이 독립적이므로 캐시를 서로 공유할 수 없다.
  • 동일한 요청이 다른 Pod로 전달되면 다시 Database를 조회하게 된다.
  • Pod 재시작 시 캐시가 모두 초기화된다.
  • API 요청이 증가할수록 Database 부하와 응답 시간이 함께 증가한다.

 

해결 방법

공통으로 사용할 수 있는 외부 Cache 도입

  • 모든 Pod가 동일한 Cache를 조회
  • Database 조회 횟수 감소
  • API 응답 속도 향상
  • Pod 재시작과 관계없이 Cache 유지

 

Valkey 설치

Redis 라이선스 변경 이후 Linux Foundation 산하에서 개발되는 오픈소스 In-Memory Key-Value Store

  • Redis 프로토콜과 호환
  • 대부분의 Redis Client를 그대로 사용 가능
  • Kubernetes 및 Cloud Native 환경에서 채택 증가
  • 고성능 Cache, Session, Queue, Rate Limit 등에 활용

 

2) Secret 관리

 

기존 Secret 관리 방식

애플리케이션 설정 파일 또는 Kubernetes Manifest에 민감한 정보를 직접 관리

  • Access Key, Secret Key 등이 YAML에 포함
  • Secret 변경 시 Manifest 수정 및 재배포 필요
  • 개발/운영 환경별 Secret 관리가 복잡
  • 권한 관리 및 감사(Audit)가 어려움

 

해결 방법

중앙화된 Secret 관리 도입

  • Secret을 안전하게 암호화하여 저장
  • 애플리케이션은 실행 시 Secret 조회
  • 환경별 Secret 일관성 유지
  • Secret 변경 시 애플리케이션 수정 최소화

 

Google Secret Manager 설치

GCP 환경에서 별도 Secret 서버를 운영하지 않아도 되어 운영 부담이 적고, IAM 기반으로 손쉽게 권한 관리 가능

Google Secret Manager HashiCorp Vault
GCP 완전관리형 서비스 직접 구축 및 운영 필요
IAM과 연동한 권한 관리 별도 인증 방식(AppRole, Token 등) 구성
별도 HA 구성 불필요 HA 및 Storage 백엔드 구성 필요
운영 부담이 적음 기능은 다양하지만 운영 복잡도 높음

 

 

3) 점진적 배포

 

기존 방식

Argo Rollouts와 Gateway API를 이용한 Blue/Green 배포

  • Stable / Preview 환경을 동시에 운영
  • 검증 완료 후 트래픽을 신규 버전으로 한 번에 전환
  • 문제 발생 시 이전 버전으로 Rollback 가능
  • 하지만 트래픽이 한 번에 전환되므로 배포 직후 장애가 발생하면 모든 사용자가 영향을 받을 수 있음

 

해결 방법

Argo Rollouts의 Canary 배포 전략 적용

  • Stable / Canary 버전 동시 운영
  • 트래픽을 단계적으로 신규 버전으로 전환
  • 소수의 사용자에게 먼저 신규 버전 제공
  • 단계별 모니터링 후 점진적으로 트래픽 확대

 

Canary 배포 도입

Canary는 운영 트래픽을 5% → 20% → 50% → 100% 점진적으로 전환

  • 장애 영향 범위 최소화
  • 실제 사용자 환경에서 안정성을 확인하며 배포
  • 성능 및 오류율을 단계적으로 확인
  • 이상 발생 시 적은 영향으로 Rollback 가능

 


 

1. Valkey 설치

 

Valkey 사용 용도

단순히 Database 조회를 줄이기 위한 캐시뿐만 아니라 다음과 같은 다양한 용도로 활용된다.

  • API 응답 캐시(Cache)
  • 사용자 세션(Session) 저장
  • 분산 카운터(Counter)
  • 분산 락(Distributed Lock)
  • 작업 큐(Queue)
  • Rate Limit 관리

이번 장에서는 여러 Pod가 동일한 상태(State)를 공유하는 방법을 이해하기 위해 분산 카운터를 예제로 사용하였다.

Pod 내부 메모리에 id를 저장하면 각 Pod가 서로 다른 값을 관리하게 되어 요청이 다른 Pod로 전달될 때 값의 일관성이 깨진다.

반면 Valkey를 사용하면 모든 Pod가 동일한 id 값을 공유하므로 어떤 Pod가 요청을 처리하더라도 연속된 값을 반환할 수 있다.

 

 

** id 변수값으로 Pod 간 상태 공유 확인하기

 

(Valkey 설치 전 id 변수값 반환)

$ for i in $(seq 1 20); do curl -s http://35.216.16.201/id; echo; done

{"id":24,"pod":"notiflex-api-86bc7c9f87-cjhg8"}

{"id":26,"pod":"notiflex-api-86bc7c9f87-l2lh7"}

{"id":27,"pod":"notiflex-api-86bc7c9f87-l2lh7"}

{"id":25,"pod":"notiflex-api-86bc7c9f87-cjhg8"}

{"id":26,"pod":"notiflex-api-86bc7c9f87-cjhg8"}

{"id":28,"pod":"notiflex-api-86bc7c9f87-l2lh7"}

{"id":27,"pod":"notiflex-api-86bc7c9f87-cjhg8"}

{"id":29,"pod":"notiflex-api-86bc7c9f87-l2lh7"}

{"id":28,"pod":"notiflex-api-86bc7c9f87-cjhg8"}

{"id":29,"pod":"notiflex-api-86bc7c9f87-cjhg8"}

{"id":30,"pod":"notiflex-api-86bc7c9f87-l2lh7"}

{"id":30,"pod":"notiflex-api-86bc7c9f87-cjhg8"}

{"id":31,"pod":"notiflex-api-86bc7c9f87-l2lh7"}

{"id":32,"pod":"notiflex-api-86bc7c9f87-l2lh7"}

{"id":31,"pod":"notiflex-api-86bc7c9f87-cjhg8"}

{"id":32,"pod":"notiflex-api-86bc7c9f87-cjhg8"}

{"id":33,"pod":"notiflex-api-86bc7c9f87-l2lh7"}

{"id":34,"pod":"notiflex-api-86bc7c9f87-l2lh7"}

{"id":33,"pod":"notiflex-api-86bc7c9f87-cjhg8"}

{"id":34,"pod":"notiflex-api-86bc7c9f87-cjhg8"}

(Valkey 설치 후 id 변수값 반환)

$ for i in $(seq 1 20); do curl -s http://35.216.16.201/id; echo; done
{"id":21,"pod":"notiflex-api-846fcf7657-8nfr6"}

{"id":22,"pod":"notiflex-api-846fcf7657-5k4nx"}

{"id":23,"pod":"notiflex-api-846fcf7657-8nfr6"}

{"id":24,"pod":"notiflex-api-846fcf7657-5k4nx"}

{"id":25,"pod":"notiflex-api-846fcf7657-8nfr6"}

{"id":26,"pod":"notiflex-api-846fcf7657-5k4nx"}

{"id":27,"pod":"notiflex-api-846fcf7657-5k4nx"}

{"id":28,"pod":"notiflex-api-846fcf7657-8nfr6"}

{"id":29,"pod":"notiflex-api-846fcf7657-5k4nx"}

{"id":30,"pod":"notiflex-api-846fcf7657-8nfr6"}

{"id":31,"pod":"notiflex-api-846fcf7657-5k4nx"}

{"id":32,"pod":"notiflex-api-846fcf7657-8nfr6"}

{"id":33,"pod":"notiflex-api-846fcf7657-5k4nx"}

{"id":34,"pod":"notiflex-api-846fcf7657-8nfr6"}

{"id":35,"pod":"notiflex-api-846fcf7657-5k4nx"}

{"id":36,"pod":"notiflex-api-846fcf7657-8nfr6"}

{"id":37,"pod":"notiflex-api-846fcf7657-5k4nx"}

{"id":38,"pod":"notiflex-api-846fcf7657-5k4nx"}

{"id":39,"pod":"notiflex-api-846fcf7657-8nfr6"}

{"id":40,"pod":"notiflex-api-846fcf7657-5k4nx"}

 

 

2. Google Secret Manager으로 시크릿 관리

 

Vault를 실무에서 많이 쓰는 이유
- 멀티클라우드/온프레미스 혼용 (클라우드별 Secret Manager를 따로 안 쓰고 통합)
- 동적 시크릿이 필요 (예: DB 접속 계정을 요청할 때마다 TTL 있는 임시 계정을 발급받아 회전)
- 이미 플랫폼팀이 Vault를 운영 중인 경우

Notiflex App은 단순 비밀번호(Valkey password) 하나를 안전하게 보관하는 게 목적이므로,

GCP Secret Manager + Workload Identity로 SA 키 파일 없이 CSI Driver가 자동으로 마운트해주는 걸로 충분하다.

 

CSI Driver

CSI(Container Storage Interface)는 Kubernetes에서 외부 리소스를 Pod에 연결하기 위한 표준 인터페이스이다.

단순히 디스크를 관리하는 기술이 아니라, 외부 리소스를 Kubernetes Pod에 연결하는 표준 인터페이스로 활용된다.

 

대표적인 활용 분야는 다음과 같다.

 

1) Storage CSI Driver

외부 스토리지를 Pod에 연결하여 Volume 생성/삭제, mount/unmount, snapshot 등을 수행한다.

  • GCE Persistent Disk
  • AWS EBS
  • Ceph
  • DirectPV

2) Secrets Store CSI Driver

외부 Secret Manager의 Secret을 Pod에 파일 형태로 안전하게 전달한다.

  • Google Secret Manager
  • HashiCorp Vault
  • AWS Secrets Manager
  • Azure Key Vault

 

** Valkey 비밀번호를 GCP Secret Manager로 이관해보기

 

 

3. Canary 배포 도입

(기존 Blue/Green) rollout.yaml

$ kubectl get rollout -n notiflex notiflex-api -oyaml
...
  spec:
    replicas: 2
    selector:
      matchLabels:
        app: notiflex-api
    strategy:
      blueGreen:
        activeService: notiflex-api
        autoPromotionEnabled: true
        autoPromotionSeconds: 30
        previewService: notiflex-api-preview
...

 

(Canary로 변경) rollout.yaml

$ kubectl get rollout -n notiflex notiflex-api -oyaml
...
spec:
  replicas: 2
  selector:
    matchLabels:
      app: notiflex-api
  strategy:
    canary:
      canaryService: notiflex-api-preview
      stableService: notiflex-api
      steps:
      - setWeight: 20
      - pause:
          duration: 30s
      - setWeight: 50
      - pause:
          duration: 30s
      - setWeight: 80
      - pause:
          duration: 30s
...

 


(추가)

 

1. ADR (Architecture Decision Record) 작성 - 아키텍처 결정 기록

 

2. 현재까지 아키텍처 정리