본문 바로가기

컨테이너 오케스트레이션과 실무

Kubernetes의 Pod·Deployment·Service·HPA가 컨테이너 배포·복구·확장을 자동화하는 구조를 이해합니다.

컨테이너 하나를 실행하는 것은 간단합니다.

그러나 수백, 수천 개의 컨테이너를 여러 서버에 걸쳐 배포하고, 장애 시 자동 복구하고, 트래픽에 따라 확장하려면 오케스트레이션(Orchestration) 도구가 필요합니다.

Kubernetes는 이 문제를 해결하는 사실상의 표준입니다.


Kubernetes 아키텍처

Kubernetes(K8s)는 구글의 Borg 운영 경험을 바탕으로 개발되어 오픈소스로 공개된 컨테이너 오케스트레이션 시스템입니다.

구성 요소역할
API Server클러스터 제어 API의 진입점, kubectl과 통신
etcd클러스터 상태를 저장하는 분산 키-값 저장소
Scheduler새 Pod를 어떤 Node에 배치할지 결정
Controller Manager원하는 상태와 현재 상태를 맞추는 컨트롤 루프
kubelet각 Node에서 Pod를 실제로 실행·관리
kube-proxyService의 가상 IP 전달 규칙을 구현

Kubernetes 핵심 개념

Pod

Kubernetes의 최소 배포 단위입니다.

하나 이상의 컨테이너를 묶은 그룹입니다.

pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: web-pod
  labels:
    app: web
spec:
  containers:
  - name: nginx
    image: nginx:1.25-alpine
    ports:
    - containerPort: 80
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"

같은 Pod 안의 컨테이너는 네트워크(localhost)를 공유하며, 함께 마운트한 볼륨을 공유할 수 있습니다. 각 이미지의 루트 파일 시스템까지 자동으로 공유하지는 않습니다.

애플리케이션 컨테이너 옆에 로그 수집기나 프록시를 함께 배치하는 사이드카(Sidecar) 패턴이 대표적입니다.

Deployment

Pod의 선언적 관리를 담당합니다.

이 템플릿의 Pod 3개를 유지하라고 선언하면 컨트롤러가 현재 상태를 원하는 상태로 맞추도록 반복해서 동작합니다.

deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1        # 업데이트 중 추가 Pod 수
      maxUnavailable: 0   # 롤아웃으로 허용하는 unavailable Pod 수: 0
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: nginx
        image: nginx:1.25-alpine
        resources:
          requests:
            cpu: "250m"
        ports:
        - containerPort: 80

컨테이너 실패는 kubelet이 재시작 정책에 따라 같은 Pod 안에서 복구할 수 있습니다. Deployment가 관리하는 Pod가 사라지면 ReplicaSet 컨트롤러가 새 UID의 대체 Pod를 만듭니다. 기존 Pod 자체가 다른 노드로 이동하는 것은 아닙니다.

이미지를 변경하면 롤링 업데이트로 점진적으로 교체합니다. 이 예산이 외부 장애 중 가용 Pod 3개를 보장하지는 않으며, 종료 중인 Pod까지 세면 일시적으로 4개를 넘을 수도 있습니다.

이전 리비전과 이미지가 남아 있으면 롤백을 요청할 수 있지만 복구 완료는 별도로 확인해야 합니다.

kubectl_commands.sh
# 배포
kubectl apply -f deployment.yaml

# 상태 확인
kubectl get pods -o wide
kubectl describe pod web-deployment-xxx

# 스케일링
kubectl scale deployment web-deployment --replicas=5

# 롤링 업데이트
kubectl set image deployment/web-deployment nginx=nginx:1.26-alpine

# 롤백
kubectl rollout undo deployment/web-deployment
kubectl rollout history deployment/web-deployment

Pod 검사 실패가 바꾸는 상태

startupProbe를 정의한 정상 경로이다. readiness 실패 기준을 충족한다. 각 단계의 값과 전환 이유를 비교합니다.

Kubernetes · 검사와 상태

Readiness 실패는 트래픽 준비 상태를 바꾸며 컨테이너를 재시작하지 않습니다

probe를 정의한 경우에 적용됩니다. startup과 liveness는 실패 임계값에서 컨테이너 종료와 재시작 정책에 연결되고, readiness는 Service 트래픽 준비 상태를 바꿉니다.

startup가 바꾸는 상태와 조건startupProbe를 정의한 경우의 세 분기다. 성공 전에는 readiness/liveness를 시작하지 않는다. 실패 임계값 미도달에서는 시작 검사를 계속하며, 도달 시 컨테이너를 종료하고 재시작 정책에 따른다. 종료가 Pod 전체 삭제나 무조건 재시작을 뜻하지 않는다.startupProbe결과·실패 횟수성공준비·생존 검사시작실패 · 임계 미도달시작 검사 계속다른 검사 대기실패 · 임계 도달컨테이너 종료재시작 정책 적용성공실패·미도달실패·도달
startup가 바꾸는 상태와 조건startupProbe를 정의한 경우의 세 분기다. 성공 전에는 readiness/liveness를 시작하지 않는다. 실패 임계값 미도달에서는 시작 검사를 계속하며, 도달 시 컨테이너를 종료하고 재시작 정책에 따른다. 종료가 Pod 전체 삭제나 무조건 재시작을 뜻하지 않는다.startupProbe결과·실패 횟수성공준비·생존 검사시작실패 · 임계 미도달시작 검사 계속다른 검사 대기실패 · 임계 도달컨테이너 종료재시작 정책 적용성공실패·미도달실패·도달
readiness가 바꾸는 상태와 조건readinessProbe를 정의한 경우다. 성공 응답만으로 여러 컨테이너·readiness gates·Service 선택자 등 다른 조건을 무시하지 않는다. 준비 실패 기준을 충족하면 Ready=false로 일반 Service 트래픽 준비 대상에서 제외하며 이 검사 실패 자체는 컨테이너 재시작 명령이 아니다.readinessProbe유효한 판정준비 응답 성공다른 Ready 조건 확인실패 기준 충족Pod Ready=false일반 Service트래픽 대상 제외성공실패
readiness가 바꾸는 상태와 조건readinessProbe를 정의한 경우다. 성공 응답만으로 여러 컨테이너·readiness gates·Service 선택자 등 다른 조건을 무시하지 않는다. 준비 실패 기준을 충족하면 Ready=false로 일반 Service 트래픽 준비 대상에서 제외하며 이 검사 실패 자체는 컨테이너 재시작 명령이 아니다.readinessProbe유효한 판정준비 응답 성공다른 Ready 조건 확인실패 기준 충족Pod Ready=false일반 Service트래픽 대상 제외성공실패
liveness가 바꾸는 상태와 조건livenessProbe를 정의한 경우다. 성공하거나 실패 임계값에 아직 도달하지 않은 정상 실행 경로와, 실패 임계값 도달 뒤 컨테이너 종료·재시작 정책 적용 경로를 구분한다. 일시 부하와 timeout/failureThreshold 설계는 기존 지원 설명의 조건을 보존한다.livenessProbe실패 임계값?임계값 미도달컨테이너 계속 실행다음 검사실패 임계값 도달컨테이너 종료재시작 정책 적용미도달도달
liveness가 바꾸는 상태와 조건livenessProbe를 정의한 경우다. 성공하거나 실패 임계값에 아직 도달하지 않은 정상 실행 경로와, 실패 임계값 도달 뒤 컨테이너 종료·재시작 정책 적용 경로를 구분한다. 일시 부하와 timeout/failureThreshold 설계는 기존 지원 설명의 조건을 보존한다.livenessProbe실패 임계값?임계값 미도달컨테이너 계속 실행다음 검사실패 임계값 도달컨테이너 종료재시작 정책 적용미도달도달
Pod 검사 실패가 바꾸는 상태
검사실패했을 때다른 검사와의 관계
시작 검사설정된 실패 임계값에 이르면 컨테이너 종료·재시작 정책 적용startupProbe가 성공하기 전에는 readiness와 liveness 검사를 시작하지 않음
준비 검사Pod의 Ready 상태가 false가 되어 일반 Service 트래픽 대상에서 제외검사 실패 자체로 컨테이너를 재시작하지 않음
생존 검사실패 임계값에 이르면 컨테이너 종료·재시작 정책 적용일시적 부하를 실패로 오판하지 않도록 임계값 설계
시작 검사
실패했을 때: 설정된 실패 임계값에 이르면 컨테이너 종료·재시작 정책 적용
다른 검사와의 관계: startupProbe가 성공하기 전에는 readiness와 liveness 검사를 시작하지 않음
준비 검사
실패했을 때: Pod의 Ready 상태가 false가 되어 일반 Service 트래픽 대상에서 제외
다른 검사와의 관계: 검사 실패 자체로 컨테이너를 재시작하지 않음
생존 검사
실패했을 때: 실패 임계값에 이르면 컨테이너 종료·재시작 정책 적용
다른 검사와의 관계: 일시적 부하를 실패로 오판하지 않도록 임계값 설계

앞의 YAML에는 probe가 없습니다. 애플리케이션 응답 상태를 검사하려면 대상에 맞는 probe를 별도로 정의해야 합니다.

이 예의 조건

  • 본문과 전체 도표의 예를 따라 시작 검사 대기부터 준비 실패까지 진행합니다.
관계도의 보충 설명
전체 도표의 표기·관계·조건
구분전체 도표의 내용
제목startup이 바꾸는 상태와 조건
표의 값시작 검사. 실패했을 때: 설정된 실패 임계값에 이르면 컨테이너 종료·재시작 정책 적용. 다른 검사와의 관계: startupProbe가 성공하기 전에는 readiness와 liveness 검사를 시작하지 않음. 준비 검사. 실패했을 때: Pod의 Ready 상태가 false가 되어 일반 Service 트래픽 대상에서 제외. 다른 검사와의 관계: 검사 실패 자체로 컨테이너를 재시작하지 않음. 생존 검사. 실패했을 때: 실패 임계값에 이르면 컨테이너 종료·재시작 정책 적용. 다른 검사와의 관계: 일시적 부하를 실패로 오판하지 않도록 임계값 설계.
예의 값과 변화
관찰·상황값·보충 정보변화·이유
시작 검사 대기

startupProbe를 정의한 정상 경로이다.

  • 검사·Pod 상태 1: startup 아직 성공 전
  • 검사·Pod 상태 2: readiness/liveness 대기
  • 시작 검사를 계속
startup 성공

다른 검사 시작 조건이 충족된다.

  • 검사·Pod 상태 1: startup 성공
  • 검사·Pod 상태 2: readiness/liveness 시작
  • 준비 판단 가능
준비 실패

readiness 실패 기준을 충족한다.

  • 검사·Pod 상태 1: Pod Ready=false
  • 검사·Pod 상태 2: 일반 Service 트래픽 대상 제외
  • 컨테이너는 이 실패만으로 재시작 안 함; liveness 종료 조건은 별도

Pod 검사 실패가 바꾸는 상태

startupProbe를 정의한 정상 경로이다. readiness 실패 기준을 충족한다. 각 단계의 값과 전환 이유를 비교합니다.

Kubernetes · 검사와 상태

Readiness 실패는 트래픽 준비 상태를 바꾸며 컨테이너를 재시작하지 않습니다

probe를 정의한 경우에 적용됩니다. startup과 liveness는 실패 임계값에서 컨테이너 종료와 재시작 정책에 연결되고, readiness는 Service 트래픽 준비 상태를 바꿉니다.

startup가 바꾸는 상태와 조건startupProbe를 정의한 경우의 세 분기다. 성공 전에는 readiness/liveness를 시작하지 않는다. 실패 임계값 미도달에서는 시작 검사를 계속하며, 도달 시 컨테이너를 종료하고 재시작 정책에 따른다. 종료가 Pod 전체 삭제나 무조건 재시작을 뜻하지 않는다.startupProbe결과·실패 횟수성공준비·생존 검사시작실패 · 임계 미도달시작 검사 계속다른 검사 대기실패 · 임계 도달컨테이너 종료재시작 정책 적용성공실패·미도달실패·도달
startup가 바꾸는 상태와 조건startupProbe를 정의한 경우의 세 분기다. 성공 전에는 readiness/liveness를 시작하지 않는다. 실패 임계값 미도달에서는 시작 검사를 계속하며, 도달 시 컨테이너를 종료하고 재시작 정책에 따른다. 종료가 Pod 전체 삭제나 무조건 재시작을 뜻하지 않는다.startupProbe결과·실패 횟수성공준비·생존 검사시작실패 · 임계 미도달시작 검사 계속다른 검사 대기실패 · 임계 도달컨테이너 종료재시작 정책 적용성공실패·미도달실패·도달
readiness가 바꾸는 상태와 조건readinessProbe를 정의한 경우다. 성공 응답만으로 여러 컨테이너·readiness gates·Service 선택자 등 다른 조건을 무시하지 않는다. 준비 실패 기준을 충족하면 Ready=false로 일반 Service 트래픽 준비 대상에서 제외하며 이 검사 실패 자체는 컨테이너 재시작 명령이 아니다.readinessProbe유효한 판정준비 응답 성공다른 Ready 조건 확인실패 기준 충족Pod Ready=false일반 Service트래픽 대상 제외성공실패
readiness가 바꾸는 상태와 조건readinessProbe를 정의한 경우다. 성공 응답만으로 여러 컨테이너·readiness gates·Service 선택자 등 다른 조건을 무시하지 않는다. 준비 실패 기준을 충족하면 Ready=false로 일반 Service 트래픽 준비 대상에서 제외하며 이 검사 실패 자체는 컨테이너 재시작 명령이 아니다.readinessProbe유효한 판정준비 응답 성공다른 Ready 조건 확인실패 기준 충족Pod Ready=false일반 Service트래픽 대상 제외성공실패
liveness가 바꾸는 상태와 조건livenessProbe를 정의한 경우다. 성공하거나 실패 임계값에 아직 도달하지 않은 정상 실행 경로와, 실패 임계값 도달 뒤 컨테이너 종료·재시작 정책 적용 경로를 구분한다. 일시 부하와 timeout/failureThreshold 설계는 기존 지원 설명의 조건을 보존한다.livenessProbe실패 임계값?임계값 미도달컨테이너 계속 실행다음 검사실패 임계값 도달컨테이너 종료재시작 정책 적용미도달도달
liveness가 바꾸는 상태와 조건livenessProbe를 정의한 경우다. 성공하거나 실패 임계값에 아직 도달하지 않은 정상 실행 경로와, 실패 임계값 도달 뒤 컨테이너 종료·재시작 정책 적용 경로를 구분한다. 일시 부하와 timeout/failureThreshold 설계는 기존 지원 설명의 조건을 보존한다.livenessProbe실패 임계값?임계값 미도달컨테이너 계속 실행다음 검사실패 임계값 도달컨테이너 종료재시작 정책 적용미도달도달
Pod 검사 실패가 바꾸는 상태
검사실패했을 때다른 검사와의 관계
시작 검사설정된 실패 임계값에 이르면 컨테이너 종료·재시작 정책 적용startupProbe가 성공하기 전에는 readiness와 liveness 검사를 시작하지 않음
준비 검사Pod의 Ready 상태가 false가 되어 일반 Service 트래픽 대상에서 제외검사 실패 자체로 컨테이너를 재시작하지 않음
생존 검사실패 임계값에 이르면 컨테이너 종료·재시작 정책 적용일시적 부하를 실패로 오판하지 않도록 임계값 설계
시작 검사
실패했을 때: 설정된 실패 임계값에 이르면 컨테이너 종료·재시작 정책 적용
다른 검사와의 관계: startupProbe가 성공하기 전에는 readiness와 liveness 검사를 시작하지 않음
준비 검사
실패했을 때: Pod의 Ready 상태가 false가 되어 일반 Service 트래픽 대상에서 제외
다른 검사와의 관계: 검사 실패 자체로 컨테이너를 재시작하지 않음
생존 검사
실패했을 때: 실패 임계값에 이르면 컨테이너 종료·재시작 정책 적용
다른 검사와의 관계: 일시적 부하를 실패로 오판하지 않도록 임계값 설계

앞의 YAML에는 probe가 없습니다. 애플리케이션 응답 상태를 검사하려면 대상에 맞는 probe를 별도로 정의해야 합니다.

이 예의 조건

  • 본문과 전체 도표의 예를 따라 시작 검사 대기부터 준비 실패까지 진행합니다.

관계도의 보충 설명

전체 도표의 표기·관계·조건
구분전체 도표의 내용
제목startup이 바꾸는 상태와 조건
표의 값시작 검사. 실패했을 때: 설정된 실패 임계값에 이르면 컨테이너 종료·재시작 정책 적용. 다른 검사와의 관계: startupProbe가 성공하기 전에는 readiness와 liveness 검사를 시작하지 않음. 준비 검사. 실패했을 때: Pod의 Ready 상태가 false가 되어 일반 Service 트래픽 대상에서 제외. 다른 검사와의 관계: 검사 실패 자체로 컨테이너를 재시작하지 않음. 생존 검사. 실패했을 때: 실패 임계값에 이르면 컨테이너 종료·재시작 정책 적용. 다른 검사와의 관계: 일시적 부하를 실패로 오판하지 않도록 임계값 설계.
예의 값과 변화
관찰·상황값·보충 정보변화·이유
시작 검사 대기

startupProbe를 정의한 정상 경로이다.

  • 검사·Pod 상태 1: startup 아직 성공 전
  • 검사·Pod 상태 2: readiness/liveness 대기
  • 시작 검사를 계속
startup 성공

다른 검사 시작 조건이 충족된다.

  • 검사·Pod 상태 1: startup 성공
  • 검사·Pod 상태 2: readiness/liveness 시작
  • 준비 판단 가능
준비 실패

readiness 실패 기준을 충족한다.

  • 검사·Pod 상태 1: Pod Ready=false
  • 검사·Pod 상태 2: 일반 Service 트래픽 대상 제외
  • 컨테이너는 이 실패만으로 재시작 안 함; liveness 종료 조건은 별도

Service

Pod는 생성·소멸을 반복하므로 IP가 바뀝니다.

Service는 안정적인 네트워크 엔드포인트를 제공합니다.

service.yaml
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  type: ClusterIP
  selector:
    app: web
  ports:
  - port: 80
    targetPort: 80
  • ClusterIP: 클러스터 내부에서 접근할 Service 주소를 제공합니다.
  • NodePort: 노드 주소의 포트로 접근할 수 있게 합니다. 실제 접근은 방화벽·라우팅 정책에도 달려 있습니다.
  • LoadBalancer: 구현 환경의 로드 밸런서를 요청합니다. 내부 또는 외부 노출 여부는 제공자 설정에 달려 있습니다.
  • Ingress: HTTP/HTTPS 라우팅 규칙을 별도 리소스로 정의합니다.

Ingress Controller가 라우팅 규칙을 구현합니다. 또한 위 Service는 app: web 레이블을 선택하므로 같은 네임스페이스에 앞의 단독 web-pod도 만들었다면 그 Pod까지 대상이 될 수 있습니다.

HPA (Horizontal Pod Autoscaler)

트래픽에 따라 자동으로 Pod 수를 조절합니다.

hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web-deployment
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

여기서 70%는 Pod의 CPU request 대비 사용 비율을 평균한 목표입니다. Deployment에 CPU request를 설정했으며, 별도로 리소스 메트릭 API가 필요합니다. HPA는 누락 지표·허용 오차·안정화 정책도 반영하므로 임계값을 넘는 즉시 늘리거나 줄이는 단순 스위치는 아닙니다.

HPA가 관리하는 replicas와 수동 scale 또는 YAML 재적용으로 지정한 replicas는 충돌할 수 있으므로 확장 제어의 주체를 정해야 합니다.


HPA 목표의 분모와 간단한 계산

CPU request가 모두 250m인 세 Pod가 각각 350m·175m·175m를 사용한다고 가정하면 request 대비 비율은 140%·70%·70%, 평균은 약 93.33%입니다. 목표 70%에 대해 HPA의 기본 비율식을 먼저 적용하면 ceil(3 × 93.33 / 70)인 4를 얻습니다. 실제 컨트롤러는 준비되지 않은 Pod·누락 지표·허용 오차·안정화·변경 한도 등을 함께 처리하므로 이것을 실제 클러스터의 즉시 결과라고 읽지 않습니다.

직접 계산: 현재 네 Pod의 request는 각각 250m, 사용은 각각 350m이며 목표는 70%입니다. 누락·미준비·허용 오차·안정화·변경 정책을 제외한 기본식의 추천 개수를 구하세요. 원 Service와 같은 네임스페이스에 app:web 레이블의 별도 web-pod가 있으면 Deployment 소유가 아니라는 이유만으로 Service 선택에서 제외되나요?

직접 계산한 뒤 풀이 확인

평균은 350/250×100=140%라 ceil(4×140/70)=8입니다. 원 min 2·max 10 범위 안이지만 실제 축소·확장 완료는 선언한 단순 식과 별도입니다. 원 Service selector는 app:web 레이블을 보므로 같은 네임스페이스의 별도 Pod도 선택 대상이 될 수 있습니다. Pod의 controller 소유권과 selector 일치는 서로 다른 조건이며, 준비 상태 등 실제 트래픽 조건도 확인합니다.

컨테이너 네트워킹

Docker 네트워크

리눅스 Docker Engine의 기본 네트워크는 브리지 네트워크입니다.

각 컨테이너는 veth pair로 브리지에 연결됩니다.

기본 브리지의 외부 통신은 NAT 규칙을 이용합니다. 방화벽 백엔드는 구성에 따라 달라집니다.

Kubernetes 네트워크 모델

Kubernetes는 Pod 네트워크에 대해 세 가지 기본 원칙을 전제합니다.

  • 모든 Pod는 NAT 없이 다른 Pod와 직접 통신할 수 있다
  • 모든 Node는 NAT 없이 모든 Pod와 통신할 수 있다
  • Pod가 보는 자기 IP = 다른 Pod가 보는 그 Pod의 IP

CNI(Container Network Interface) 플러그인 등이 Pod 네트워크를 구성합니다. 실제 통신은 NetworkPolicy 등으로 제한할 수 있으며, 일부 구현은 kube-proxy의 기능도 대체합니다.

오버레이(VXLAN 등), 노드 간 라우팅(BGP 등), eBPF 데이터 평면처럼 구현 방식이 다릅니다. Flannel·Calico·Cilium 등이 예이며, Weave도 메시 오버레이 사례로 사용되어 왔습니다. 제품 이름만으로 성능이나 적합한 클러스터 규모를 단정하지 않고 지원 상태와 구성 기능을 확인합니다.


서버리스와 마이크로 VM

서버리스(Serverless)는 개발자가 서버를 관리하지 않고 함수 단위로 코드를 배포하는 모델입니다.

AWS Lambda, Google Cloud Functions, Azure Functions가 대표적입니다.

서버리스라고 서버가 없는 것은 아닙니다.

내부적으로는 컨테이너나 마이크로 VM이 함수 실행 환경을 제공합니다.

AWS Lambda는 Firecracker라는 경량 VM을 사용합니다.

Firecracker는 KVM 기반 마이크로 VM으로 게스트 커널을 별도로 실행하면서 가상 장치 구성을 줄입니다. virtio-net·virtio-block 같은 제한된 장치를 제공하며, 시작 시간과 메모리 비용은 게스트 이미지·호스트·측정 구간에 따라 달라집니다.

서버리스의 가장 큰 도전 과제는 콜드 스타트(Cold Start)입니다.

요청이 없던 함수가 호출되면, 실행 환경을 새로 준비하는 데 수백 ms ~ 수 초가 걸립니다.


인프라 선택 기준

인프라 선택 · 운영 책임

필요한 제어와 직접 관리할 범위로 실행 환경을 비교합니다

장치·게스트 OS·이미지·함수 중 어디까지 제어해야 하는지 확인합니다. 아래 질문은 선택 기준이며 특정 환경의 성능이나 비용 우위를 보장하지 않습니다.

인프라 선택에서 직접 관리하는 범위
환경직접 확인할 범위선택 질문
베어메탈물리 장비·OS·애플리케이션GPU·HPC의 장치 접근과 하드웨어 제어가 필요한가?
가상 머신게스트 OS·가상 자원·애플리케이션게스트 커널 경계와 운영체제 제어가 필요한가?
컨테이너이미지·실행 정책·오케스트레이션공유 커널 전제에서 배포 단위를 표준화할 수 있는가?
서버리스함수 코드·권한·서비스 제약이벤트 모델과 실행·동시성 제한에 작업이 맞는가?
베어메탈
직접 확인할 범위: 물리 장비·OS·애플리케이션
선택 질문: GPU·HPC의 장치 접근과 하드웨어 제어가 필요한가?
가상 머신
직접 확인할 범위: 게스트 OS·가상 자원·애플리케이션
선택 질문: 게스트 커널 경계와 운영체제 제어가 필요한가?
컨테이너
직접 확인할 범위: 이미지·실행 정책·오케스트레이션
선택 질문: 공유 커널 전제에서 배포 단위를 표준화할 수 있는가?
서버리스
직접 확인할 범위: 함수 코드·권한·서비스 제약
선택 질문: 이벤트 모델과 실행·동시성 제한에 작업이 맞는가?

관리형 서비스 사용 여부에 따라 운영 책임이 달라집니다. 한 시스템 안에서도 서로 다른 환경을 함께 사용할 수 있습니다.

데이터베이스는 VM이나 매니지드 서비스로, 애플리케이션 서버는 컨테이너(Kubernetes)로, 이벤트 처리는 서버리스로 구성하는 것이 흔한 패턴입니다.

infra_decision.py
def recommend_infra(workload):
    """워크로드 특성에 따른 인프라 추천"""
    if workload["gpu_required"]:
        return "베어메탈 또는 GPU VM"

    if workload["multi_tenant"]:
        return "VM (강한 격리 필요)"

    if workload["traffic_pattern"] == "spiky":
        if workload["avg_duration_ms"] < 300000:  # 5분 미만
            return "서버리스 (Lambda/Cloud Functions)"
        else:
            return "컨테이너 + HPA"

    if workload["microservices"]:
        return "Kubernetes 컨테이너"

    return "VM (범용)"

위 함수는 입력 키가 갖춰졌다고 가정한 의사결정 예제입니다. 조건 검사 순서가 추천을 결정하며, 5분은 여기서 정한 기준이지 특정 서버리스 서비스의 실행 시간 한도가 아닙니다.


CI/CD와 컨테이너

컨테이너는 CI/CD(지속적 통합/배포) 파이프라인과 자연스럽게 결합됩니다.

cicd_pipeline.sh
# 1. 푸시할 이름으로 이미지 빌드
docker build -t registry.example.com/myapp:${GIT_SHA} .

# 2. 보안 스캐닝
trivy image registry.example.com/myapp:${GIT_SHA}

# 3. 레지스트리에 푸시
docker push registry.example.com/myapp:${GIT_SHA}

# 4. Kubernetes에 배포
kubectl set image deployment/myapp \
  myapp=registry.example.com/myapp:${GIT_SHA}

# 5. 배포 상태 확인
kubectl rollout status deployment/myapp

이미지 태그로 Git 커밋 해시를 사용하면, 어떤 코드 버전이 배포되었는지 추적할 수 있습니다.

태그는 덮어쓸 수 있으므로 내용 고정이 필요하면 이미지 digest를 사용합니다. 파이프라인은 레지스트리 인증, 기존 myapp Deployment, 사용할 도구를 전제합니다. 롤백은 이전 이미지의 보존과 데이터 호환성까지 확인해야 합니다.

다음 장에서는 OS 지식이 실제로 쓰이는 순간들 — 리눅스 필수 명령어, 시스템 모니터링, 면접 주제를 정리하겠습니다.