IMG-LOGO
공지사항 :

Kubernetes FastAPI + PostgreSQL + Redis + Nginx를 실제 Kubernetes 클러스터에 배포

lmkfox - 2026-09-07 07:32:08 5 Views 0 Comment

Kubernetes 실전 운영

FastAPI + PostgreSQL + Redis + Nginx를 실제 Kubernetes 클러스터에 배포하기

지금까지 Kubernetes의 Pod, Deployment, Service, ConfigMap, Secret, PVC, Helm을 각각 살펴봤다면 이제 이 기술들을 하나의 실제 서비스에 적용해 볼 차례다.

이번 실습에서는 다음과 같은 웹 서비스를 Kubernetes에 구축한다.

                         Internet
                            |
                            v
                     [ HTTPS :443 ]
                            |
                            v
                     [ Kubernetes ]
                            |
                         Ingress
                            |
                            v
                         Nginx
                            |
                            v
                    FastAPI Service
                            |
                 +----------+----------+
                 |                     |
                 v                     v
            FastAPI Pod            FastAPI Pod
                 |                     |
                 +----------+----------+
                            |
                +-----------+-----------+
                |                       |
                v                       v
          PostgreSQL                  Redis
                |
                v
               PVC

그리고 다음 기능까지 적용한다.

Ingress
HTTPS
Helm
ConfigMap
Secret
PVC
Resource Request / Limit
HPA
Health Check
로그 확인
장애 테스트
Rollback

이 정도까지 구성하면 단순한 Kubernetes 실습을 넘어 실제 운영 환경의 기본적인 형태를 이해할 수 있다.


1. 최종 아키텍처

전체 구조부터 이해하는 것이 중요하다.

                         Client
                           |
                           | HTTPS
                           v
                    +-------------+
                    |   Ingress   |
                    +-------------+
                           |
                           v
                    +-------------+
                    |    Nginx    |
                    +-------------+
                           |
                           | HTTP
                           v
                  +-------------------+
                  | FastAPI Service   |
                  +-------------------+
                           |
               +-----------+-----------+
               |                       |
               v                       v
        +-------------+         +-------------+
        | FastAPI Pod |         | FastAPI Pod |
        +-------------+         +-------------+
               |
         +-----+-----+
         |           |
         v           v
 +-------------+  +---------+
 | PostgreSQL  |  |  Redis  |
 +-------------+  +---------+
         |
         v
       PVC

여기서 각각의 역할은 다음과 같다.

구성요소 역할
Ingress 외부 HTTP/HTTPS 요청 진입점
Nginx Reverse Proxy
FastAPI Backend API
PostgreSQL 영구 데이터 저장
Redis Cache / Session
ConfigMap 일반 설정
Secret 비밀번호 등 민감 정보
PVC 데이터 영구 저장
HPA Pod 자동 확장
Helm 전체 애플리케이션 패키징

2. Kubernetes 클러스터 준비

실제 운영에서는 다음과 같은 Kubernetes 환경을 사용할 수 있다.

Kubernetes Cluster

Control Plane
     |
     +----------------+
     |                |
     v                v
 Worker Node 1    Worker Node 2
     |                |
     +--------+-------+
              |
          Applications

학습 환경이라면 다음과 같은 환경에서도 실습할 수 있다.

Minikube
Kind
K3s
RKE2
Kubernetes on Rocky Linux
Cloud Kubernetes

실습 전에 Kubernetes 연결을 확인한다.

kubectl cluster-info

Node 확인:

kubectl get nodes

예:

NAME       STATUS   ROLES
master     Ready    control-plane
worker01   Ready    <none>
worker02   Ready    <none>

모든 Node가 Ready 상태인지 확인한다.


3. Namespace 생성

운영 환경에서는 애플리케이션을 별도의 Namespace에서 관리하는 것이 좋다.

kubectl create namespace myapp

확인:

kubectl get namespace

이후 대부분의 리소스는:

namespace: myapp

에서 실행한다.


4. FastAPI Docker Image 만들기

먼저 FastAPI 애플리케이션을 Docker Image로 만들어야 한다.

프로젝트:

backend/
├── app/
│   ├── main.py
│   └── database.py
├── requirements.txt
└── Dockerfile

간단한 FastAPI 코드:

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def root():
    return {
        "message": "Kubernetes FastAPI"
    }


@app.get("/health")
def health():
    return {
        "status": "ok"
    }

/health API는 Kubernetes Health Check에 사용한다.


5. Dockerfile

FROM python:3.12-slim

WORKDIR /app

COPY requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt

COPY app ./app

EXPOSE 8000

CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

Image 생성:

docker build -t myapp-backend:1.0.0 .

실제 Kubernetes 클러스터가 여러 Node로 구성되어 있다면 모든 Node에서 Image를 사용할 수 있도록 Container Registry에 Push하는 것이 일반적이다.

예:

Docker Registry
       |
       +-- myapp-backend:1.0.0
       +-- myapp-backend:1.1.0
       +-- myapp-backend:1.2.0

6. PostgreSQL 구성

PostgreSQL은 데이터가 중요한 서비스다.

이번 실습에서는 Kubernetes의 PVC를 사용한다.

PostgreSQL
     |
     v
PersistentVolumeClaim
     |
     v
PersistentVolume
     |
     v
Storage

PVC:

apiVersion: v1
kind: PersistentVolumeClaim

metadata:
  name: postgres-pvc
  namespace: myapp

spec:
  accessModes:
    - ReadWriteOnce

  resources:
    requests:
      storage: 20Gi

생성:

kubectl apply -f postgres-pvc.yaml

확인:

kubectl get pvc -n myapp

7. PostgreSQL Secret

DB 비밀번호는 Secret으로 관리한다.

apiVersion: v1
kind: Secret

metadata:
  name: postgres-secret
  namespace: myapp

type: Opaque

stringData:
  POSTGRES_USER: appuser
  POSTGRES_PASSWORD: change-this-password
  POSTGRES_DB: appdb

적용:

kubectl apply -f postgres-secret.yaml

확인:

kubectl get secret -n myapp

주의할 점이 있다.

kubectl get secret

으로는 실제 Secret 값이 그대로 보이지 않지만, Kubernetes Secret을 단순히 "암호화된 비밀번호 저장소"라고 생각하면 안 된다.

운영 환경에서는 별도의 Secret Management 시스템을 사용하는 것도 고려해야 한다.


8. PostgreSQL Deployment

apiVersion: apps/v1
kind: Deployment

metadata:
  name: postgres
  namespace: myapp

spec:
  replicas: 1

  selector:
    matchLabels:
      app: postgres

  template:
    metadata:
      labels:
        app: postgres

    spec:
      containers:
        - name: postgres

          image: postgres:17

          ports:
            - containerPort: 5432

          env:
            - name: POSTGRES_USER
              valueFrom:
                secretKeyRef:
                  name: postgres-secret
                  key: POSTGRES_USER

            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: postgres-secret
                  key: POSTGRES_PASSWORD

            - name: POSTGRES_DB
              valueFrom:
                secretKeyRef:
                  name: postgres-secret
                  key: POSTGRES_DB

          volumeMounts:
            - name: postgres-data
              mountPath: /var/lib/postgresql/data

      volumes:
        - name: postgres-data
          persistentVolumeClaim:
            claimName: postgres-pvc

9. PostgreSQL Service

FastAPI에서 PostgreSQL에 접근하려면 Service가 필요하다.

apiVersion: v1
kind: Service

metadata:
  name: postgres
  namespace: myapp

spec:
  selector:
    app: postgres

  ports:
    - port: 5432
      targetPort: 5432

Kubernetes 내부에서는:

postgres:5432

로 접근할 수 있다.


10. ConfigMap

애플리케이션 설정과 비밀번호를 분리해야 한다.

예를 들어:

apiVersion: v1
kind: ConfigMap

metadata:
  name: backend-config
  namespace: myapp

data:
  APP_ENV: "production"
  REDIS_HOST: "redis"
  REDIS_PORT: "6379"
  DB_HOST: "postgres"
  DB_PORT: "5432"
  DB_NAME: "appdb"

여기에는 비밀번호를 넣지 않는다.

구분하면 다음과 같다.

ConfigMap
  |
  +-- DB_HOST
  +-- DB_PORT
  +-- REDIS_HOST
  +-- APP_ENV


Secret
  |
  +-- DB_PASSWORD
  +-- API_KEY
  +-- JWT_SECRET

11. Redis 배포

Redis Deployment:

apiVersion: apps/v1
kind: Deployment

metadata:
  name: redis
  namespace: myapp

spec:
  replicas: 1

  selector:
    matchLabels:
      app: redis

  template:
    metadata:
      labels:
        app: redis

    spec:
      containers:
        - name: redis
          image: redis:7

          ports:
            - containerPort: 6379

Service:

apiVersion: v1
kind: Service

metadata:
  name: redis
  namespace: myapp

spec:
  selector:
    app: redis

  ports:
    - port: 6379
      targetPort: 6379

FastAPI에서는:

redis://redis:6379

로 Redis에 연결한다.


12. FastAPI Deployment

이제 핵심인 FastAPI를 배포한다.

apiVersion: apps/v1
kind: Deployment

metadata:
  name: backend
  namespace: myapp

spec:
  replicas: 2

  selector:
    matchLabels:
      app: backend

  template:
    metadata:
      labels:
        app: backend

    spec:
      containers:
        - name: backend

          image: myregistry/myapp-backend:1.0.0

          ports:
            - containerPort: 8000

          envFrom:
            - configMapRef:
                name: backend-config

          resources:
            requests:
              cpu: 250m
              memory: 256Mi

            limits:
              cpu: 1
              memory: 512Mi

          readinessProbe:
            httpGet:
              path: /health
              port: 8000

            initialDelaySeconds: 5
            periodSeconds: 10

          livenessProbe:
            httpGet:
              path: /health
              port: 8000

            initialDelaySeconds: 15
            periodSeconds: 20

13. Resource Request와 Limit

운영 Kubernetes에서 매우 중요한 부분이다.

resources:
  requests:
    cpu: 250m
    memory: 256Mi

  limits:
    cpu: 1
    memory: 512Mi

의미는 다음과 같다.

requests
    |
    +-- Kubernetes 스케줄링 기준

limits
    |
    +-- 사용할 수 있는 최대 자원

CPU:

250m = 0.25 CPU
1    = 1 CPU

Memory:

256Mi
512Mi

이 값을 설정하지 않으면 특정 Pod가 CPU나 Memory를 과도하게 사용할 가능성이 있다.

운영 환경에서는 애플리케이션 특성에 맞게 Request와 Limit을 설정하는 것이 중요하다.


14. FastAPI Service

apiVersion: v1
kind: Service

metadata:
  name: backend
  namespace: myapp

spec:
  selector:
    app: backend

  ports:
    - port: 8000
      targetPort: 8000

  type: ClusterIP

Service를 통해:

backend:8000

으로 접근할 수 있다.


15. Nginx 배포

Nginx는 Reverse Proxy 역할을 한다.

Client
   |
   v
Nginx
   |
   v
FastAPI

Nginx 설정:

server {
    listen 80;

    location / {
        proxy_pass http://backend:8000;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

이 설정을 ConfigMap으로 관리할 수 있다.


16. Nginx ConfigMap

apiVersion: v1
kind: ConfigMap

metadata:
  name: nginx-config
  namespace: myapp

data:
  default.conf: |
    server {
        listen 80;

        location / {
            proxy_pass http://backend:8000;
        }
    }

Nginx Deployment:

apiVersion: apps/v1
kind: Deployment

metadata:
  name: nginx
  namespace: myapp

spec:
  replicas: 2

  selector:
    matchLabels:
      app: nginx

  template:
    metadata:
      labels:
        app: nginx

    spec:
      containers:
        - name: nginx

          image: nginx:1.27

          ports:
            - containerPort: 80

          volumeMounts:
            - name: nginx-config
              mountPath: /etc/nginx/conf.d/default.conf
              subPath: default.conf

      volumes:
        - name: nginx-config
          configMap:
            name: nginx-config

17. Nginx Service

apiVersion: v1
kind: Service

metadata:
  name: nginx
  namespace: myapp

spec:
  selector:
    app: nginx

  ports:
    - port: 80
      targetPort: 80

  type: ClusterIP

이제 외부에서 직접 Nginx Pod에 접근하지 않는다.

외부 진입점은 Ingress가 담당한다.


18. Ingress란?

Ingress는 외부 HTTP/HTTPS 요청을 Kubernetes Service로 연결하는 역할을 한다.

Internet
    |
    v
Ingress
    |
    v
Nginx Service
    |
    v
Nginx Pod
    |
    v
FastAPI Service

예를 들어:

api.example.com

으로 접속하면:

api.example.com
       |
       v
Ingress
       |
       v
nginx:80

으로 전달한다.


19. Ingress Controller 설치

Ingress 리소스만 생성한다고 실제 요청을 처리하는 것은 아니다.

Ingress Controller가 필요하다.

대표적인 구현이:

NGINX Ingress Controller
Traefik
HAProxy
Kong
Cloud Load Balancer

등이다.

실습 환경에서는 NGINX Ingress Controller 또는 사용하는 Kubernetes 배포판에서 제공하는 Ingress Controller를 설치할 수 있다.

설치 후:

kubectl get pods -A

로 Controller가 정상적으로 실행되는지 확인한다.


20. Ingress 설정

예:

apiVersion: networking.k8s.io/v1
kind: Ingress

metadata:
  name: myapp-ingress
  namespace: myapp

spec:
  ingressClassName: nginx

  rules:
    - host: api.example.com

      http:
        paths:
          - path: /
            pathType: Prefix

            backend:
              service:
                name: nginx
                port:
                  number: 80

이제:

https://api.example.com

이라는 요청이 Kubernetes로 들어오게 된다.


21. HTTPS 적용

운영 환경에서는 HTTP보다 HTTPS를 사용하는 것이 일반적이다.

구조:

Client
   |
   | HTTPS :443
   v
Ingress
   |
   | HTTP
   v
Nginx
   |
   v
FastAPI

TLS 인증서는 Kubernetes Secret으로 관리할 수 있다.

apiVersion: v1
kind: Secret

metadata:
  name: myapp-tls
  namespace: myapp

type: kubernetes.io/tls

data:
  tls.crt: ...
  tls.key: ...

Ingress:

spec:
  tls:
    - hosts:
        - api.example.com
      secretName: myapp-tls

실제 운영에서는 인증서 자동 발급과 갱신을 위해 Cert-Manager + Let's Encrypt 조합을 많이 사용한다.


22. HPA란?

HPA는 Horizontal Pod Autoscaler다.

쉽게 말하면:

CPU 증가
   |
   v
Pod 증가

반대로:

CPU 감소
   |
   v
Pod 감소

하도록 자동 조절한다.

예:

평상시

FastAPI
  |
  +-- Pod 1
  +-- Pod 2


트래픽 증가

FastAPI
  |
  +-- Pod 1
  +-- Pod 2
  +-- Pod 3
  +-- Pod 4
  +-- Pod 5

23. HPA 설정

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler

metadata:
  name: backend-hpa
  namespace: myapp

spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: backend

  minReplicas: 2
  maxReplicas: 10

  metrics:
    - type: Resource

      resource:
        name: cpu

        target:
          type: Utilization
          averageUtilization: 70

의미:

최소 Pod = 2
최대 Pod = 10

CPU 평균 사용률 > 70%
        |
        v
Pod 증가

HPA를 사용하려면 Kubernetes Metrics API가 정상적으로 제공되어야 한다.

일반적인 Kubernetes 실습 환경에서는 Metrics Server를 설치한다.

확인:

kubectl top pods -n myapp

정상적으로 CPU/Memory가 표시되는지 확인한다.


24. HPA 확인

kubectl get hpa -n myapp

예:

NAME          TARGETS    MINPODS   MAXPODS   REPLICAS
backend-hpa   15%/70%    2         10        2

트래픽이 증가하면:

REPLICAS
2
 ↓
4
 ↓
6
 ↓
8

처럼 증가할 수 있다.


25. 전체 상태 확인

운영 중에는 다음 명령어를 자주 사용한다.

kubectl get pods -n myapp
kubectl get svc -n myapp
kubectl get deployment -n myapp
kubectl get ingress -n myapp
kubectl get pvc -n myapp
kubectl get hpa -n myapp

전체를 한 번에 확인하려면:

kubectl get all -n myapp

26. Pod 로그 확인

장애가 발생하면 가장 먼저 로그를 확인한다.

kubectl logs deployment/backend -n myapp

특정 Pod:

kubectl logs backend-xxxx -n myapp

실시간 로그:

kubectl logs -f backend-xxxx -n myapp

이전 컨테이너 로그:

kubectl logs backend-xxxx -n myapp --previous

--previous는 컨테이너가 재시작된 경우 이전 컨테이너의 로그를 확인할 때 매우 유용하다.


27. Nginx 로그 확인

kubectl logs deployment/nginx -n myapp

접속 문제가 발생했다면 Nginx 로그를 확인한다.

Client
  |
  v
Ingress
  |
  v
Nginx
  |
  v
FastAPI

어느 구간에서 문제가 발생했는지를 찾아야 한다.


28. Pod 상태 확인

kubectl describe pod backend-xxxx -n myapp

특히 마지막 부분의:

Events:

를 확인해야 한다.

예:

FailedScheduling
FailedMount
ImagePullBackOff
Back-off restarting failed container
Unhealthy

등의 메시지가 나타날 수 있다.

Kubernetes 장애 분석에서 describe는 매우 중요한 명령이다.


29. ImagePullBackOff 장애 테스트

일부러 잘못된 Image를 지정해 보자.

image:
  repository: myregistry/myapp-backend
  tag: "999.999"

배포:

helm upgrade myapp ./myapp -n myapp

Pod를 확인한다.

kubectl get pods -n myapp

다음과 같이 나타날 수 있다.

backend-xxxx   0/1   ImagePullBackOff

원인을 확인한다.

kubectl describe pod backend-xxxx -n myapp

Events에서 Image를 가져오지 못한 원인을 확인한다.


30. CrashLoopBackOff 장애 테스트

이번에는 애플리케이션이 시작하자마자 종료되도록 만들어 본다.

예를 들어 잘못된 환경변수를 설정하거나 애플리케이션 실행 명령을 잘못 지정한다.

결과:

backend-xxxx
0/1
CrashLoopBackOff

로그:

kubectl logs backend-xxxx -n myapp

재시작 횟수:

kubectl get pod -n myapp

예:

NAME          READY   STATUS             RESTARTS
backend-xxx   0/1     CrashLoopBackOff   7

이 경우:

kubectl logs
kubectl describe pod

두 가지를 함께 확인한다.


31. Readiness Probe 장애 테스트

FastAPI의 /health를 일시적으로 잘못된 경로로 변경한다.

readinessProbe:
  httpGet:
    path: /wrong-health
    port: 8000

Pod 자체는 실행된다.

STATUS: Running

하지만:

READY: 0/1

이 될 수 있다.

이것은 매우 중요한 개념이다.

Running
    ≠
Traffic 받을 준비 완료

즉:

Pod Running
      |
      v
Readiness 성공?
      |
   +--+--+
   |     |
  Yes    No
   |      |
Traffic   Traffic
허용      차단

32. Liveness Probe 장애

Liveness Probe가 실패하면 Kubernetes가 컨테이너를 재시작할 수 있다.

확인:

kubectl get pods -n myapp

재시작 횟수가 증가하는지 확인한다.

RESTARTS
0
1
2
3

이때:

kubectl describe pod

에서 Probe 실패 이벤트를 확인한다.


33. PostgreSQL 장애 테스트

PostgreSQL Pod를 삭제해 보자.

kubectl delete pod postgres-xxxx -n myapp

Deployment에서 관리하고 있다면 새로운 Pod가 생성된다.

kubectl get pods -n myapp

데이터가 PVC에 저장되어 있다면 새로운 Pod가 기존 Persistent Volume을 다시 연결할 수 있다.

PostgreSQL Pod
     |
     X
    장애
     |
     v
새 PostgreSQL Pod
     |
     v
기존 PVC
     |
     v
기존 데이터

이것이 Kubernetes에서 Persistent Storage가 중요한 이유다.

단, Pod 재생성 테스트가 데이터베이스 백업이나 고가용성을 보장하는 것은 아니다.

운영 환경에서는 별도의 백업과 복구 전략이 반드시 필요하다.


34. Redis 장애 테스트

Redis Pod를 삭제한다.

kubectl delete pod -l app=redis -n myapp

새로운 Redis Pod가 생성되는지 확인한다.

kubectl get pods -n myapp

Redis를 단순 캐시 용도로 사용한다면 재생성에 따른 데이터 손실을 허용할 수 있다.

반대로 중요한 데이터를 Redis에 저장한다면 별도의 Persistence와 고가용성 설계를 해야 한다.


35. Helm으로 전체 애플리케이션 관리

실제 운영에서는 개별 YAML을 하나씩 적용하는 것보다 Helm Chart로 관리하는 것이 편리하다.

myapp/
├── Chart.yaml
├── values.yaml
├── values-dev.yaml
├── values-prod.yaml
└── templates/
    ├── backend.yaml
    ├── backend-service.yaml
    ├── postgres.yaml
    ├── postgres-service.yaml
    ├── redis.yaml
    ├── redis-service.yaml
    ├── nginx.yaml
    ├── nginx-service.yaml
    ├── ingress.yaml
    ├── configmap.yaml
    ├── secret.yaml
    ├── pvc.yaml
    └── hpa.yaml

배포:

helm install myapp ./myapp \
  -n myapp \
  --create-namespace \
  -f values-prod.yaml

업데이트:

helm upgrade myapp ./myapp \
  -n myapp \
  -f values-prod.yaml

36. 운영 배포 전 검사

운영 환경에 바로 배포하지 않는 것이 좋다.

먼저:

helm lint ./myapp

그리고:

helm template myapp ./myapp \
  -f values-prod.yaml

결과를 확인한다.

그 다음:

helm upgrade --install myapp ./myapp \
  -n myapp \
  --create-namespace \
  -f values-prod.yaml \
  --dry-run

환경과 Helm 버전에 따라 --dry-run 출력에는 클러스터 조회가 필요한 리소스의 검증 차이가 있을 수 있으므로 실제 배포 전 최종 검증도 수행해야 한다.


37. 배포 상태 확인

helm status myapp -n myapp

그리고:

kubectl get pods -n myapp
kubectl get svc -n myapp
kubectl get ingress -n myapp
kubectl get pvc -n myapp
kubectl get hpa -n myapp

전체 상태를 확인한다.


38. Helm Rollback

운영 배포에서 가장 중요한 기능 중 하나다.

배포 이력을 확인한다.

helm history myapp -n myapp

예:

REVISION   STATUS
1          deployed
2          deployed
3          deployed

3번 배포에서 장애가 발생했다면:

helm rollback myapp 2 -n myapp

그리고:

helm status myapp -n myapp

으로 확인한다.

운영에서 중요한 것은 "장애가 발생하지 않게 만드는 것"뿐만 아니라 장애가 발생했을 때 빠르게 이전 정상 상태로 돌아가는 것이다.


39. 실제 운영 장애 대응 순서

운영 서버에서 API 접속 장애가 발생했다고 가정해 보자.

가장 먼저 전체 상태를 확인한다.

kubectl get pods -n myapp

문제가 있는 Pod가 있다면:

kubectl describe pod <pod-name> -n myapp

로그 확인:

kubectl logs <pod-name> -n myapp

Deployment:

kubectl get deployment -n myapp

Service:

kubectl get svc -n myapp

Ingress:

kubectl get ingress -n myapp

Endpoint:

kubectl get endpoints -n myapp

또는 환경에 따라 EndpointSlice를 확인한다.

kubectl get endpointslice -n myapp

그리고 애플리케이션 내부에서 직접 테스트한다.

kubectl exec -it <backend-pod> -n myapp -- curl http://localhost:8000/health

40. 장애 분석의 기본 흐름

실무에서는 다음 순서가 매우 유용하다.

사용자 접속 실패
       |
       v
Ingress 확인
       |
       v
Nginx 확인
       |
       v
Service 확인
       |
       v
Endpoint 확인
       |
       v
Pod 상태 확인
       |
       v
Application Log
       |
       v
DB / Redis 연결 확인

즉 단순히:

kubectl logs

만 보는 것이 아니다.

어느 계층에서 문제가 발생했는지 찾는 것이 핵심이다.


41. 운영 환경에서 추가해야 할 것

실제 서비스라면 여기서 끝나지 않는다.

다음 기능들을 추가하는 것이 좋다.

Monitoring
Logging
Alerting
Backup
RBAC
NetworkPolicy
PodDisruptionBudget
Security Context
Image Security Scan
ResourceQuota
NetworkPolicy
Secret Management

모니터링:

Prometheus
Grafana

로그:

Loki
ELK / EFK

알림:

Alertmanager
Slack
Email

등을 사용할 수 있다.


42. 최종 운영 아키텍처

최종적으로 다음과 같은 형태를 생각하면 된다.

                         Internet
                            |
                            | HTTPS
                            v
                   +----------------+
                   | Ingress        |
                   +----------------+
                            |
                            v
                   +----------------+
                   | Nginx          |
                   +----------------+
                            |
                            v
                   +----------------+
                   | FastAPI Service|
                   +----------------+
                            |
             +--------------+--------------+
             |                             |
             v                             v
       +-----------+                 +-----------+
       | FastAPI   |                 | FastAPI   |
       | Pod       |                 | Pod       |
       +-----------+                 +-----------+
             |
        +----+----+
        |         |
        v         v
 PostgreSQL     Redis
     |
     v
    PVC


          Kubernetes Operations
          ---------------------

          Helm
          HPA
          ConfigMap
          Secret
          Health Check
          Monitoring
          Logging
          Backup
          Rollback

43. 실무에서 기억해야 할 핵심 명령어

Pod:

kubectl get pods -n myapp

로그:

kubectl logs -f <pod> -n myapp

상세 정보:

kubectl describe pod <pod> -n myapp

Deployment:

kubectl get deployment -n myapp

Service:

kubectl get svc -n myapp

Ingress:

kubectl get ingress -n myapp

PVC:

kubectl get pvc -n myapp

HPA:

kubectl get hpa -n myapp

리소스:

kubectl top pods -n myapp

Helm:

helm list -n myapp
helm status myapp -n myapp
helm history myapp -n myapp

Rollback:

helm rollback myapp 2 -n myapp

44. 전체 실습 순서

이번 실습을 실제로 진행한다면 다음 순서가 가장 좋다.

1. Kubernetes Cluster 준비
          |
          v
2. Namespace 생성
          |
          v
3. Docker Image 생성
          |
          v
4. Container Registry Push
          |
          v
5. PostgreSQL + PVC
          |
          v
6. Redis
          |
          v
7. ConfigMap / Secret
          |
          v
8. FastAPI Deployment
          |
          v
9. FastAPI Service
          |
          v
10. Nginx
          |
          v
11. Ingress
          |
          v
12. HTTPS
          |
          v
13. HPA
          |
          v
14. Helm Package
          |
          v
15. DEV 배포
          |
          v
16. PROD 배포
          |
          v
17. 장애 테스트
          |
          v
18. 로그 분석
          |
          v
19. Rollback
          |
          v
20. Monitoring / Backup

45. 마무리

이번 실습에서 가장 중요한 것은 Kubernetes 명령어 자체가 아니다.

하나의 서비스를 여러 개의 Kubernetes 리소스로 나누고 이들을 어떻게 연결해서 운영하는지 이해하는 것이다.

FastAPI 하나만 보면 단순하다.

FastAPI

하지만 실제 운영 환경에서는:

Ingress
   |
Nginx
   |
Service
   |
Deployment
   |
Pod
   |
ConfigMap / Secret
   |
PostgreSQL / Redis
   |
PVC

처럼 여러 계층이 연결된다.

여기에:

HPA
Health Check
Resource Limit
Monitoring
Logging
Backup
Rollback

을 추가하면서 비로소 운영 가능한 Kubernetes 서비스에 가까워진다.

특히 시스템 엔지니어 입장에서 중요한 것은 장애가 발생했을 때 다음 질문에 답할 수 있는 것이다.

1. Pod가 정상인가?
2. Container가 정상적으로 시작했는가?
3. Readiness Probe가 성공했는가?
4. Service가 올바른 Pod를 바라보고 있는가?
5. Endpoint가 존재하는가?
6. Nginx가 Backend로 연결되는가?
7. Ingress가 올바른 Service로 전달하는가?
8. HTTPS 인증서가 정상인가?
9. FastAPI가 PostgreSQL에 연결되는가?
10. FastAPI가 Redis에 연결되는가?
11. PVC가 정상적으로 Mount 되었는가?
12. CPU/Memory가 부족하지 않은가?
13. HPA가 정상적으로 동작하는가?
14. 최근 배포에서 문제가 발생하지 않았는가?
15. 필요하다면 Helm Rollback이 가능한가?

이 질문을 순서대로 확인할 수 있다면 Kubernetes 장애 대응 능력은 크게 향상된다.

결국 Kubernetes 운영의 핵심은 배포 자체가 아니라 배포 이후의 안정적인 운영과 장애 대응이다.


댓글