학습 내용

5-1. Container 정리와 Single / Multi Container Pod

Pod 개념

  • Kubernetes에서 배포 가능한 가장 작은 단위
  • 1개 이상의 컨테이너를 포함
  • 같은 Pod 내 컨테이너는 네트워크(localhost)와 스토리지 공유

Pod 동작 flow

kubectl apply → apiserver → etcd 저장
→ scheduler → 최적 노드 선택
→ kubelet → containerd → 컨테이너 실행
→ kubelet → apiserver에 상태 보고

Single Container Pod

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
  - name: nginx
    image: nginx:1.25
    ports:
    - containerPort: 80

Multi Container Pod

apiVersion: v1
kind: Pod
metadata:
  name: multi-pod
spec:
  containers:
  - name: web
    image: nginx
    ports:
    - containerPort: 80
  - name: sidecar
    image: busybox
    command: ["sh", "-c", "while true; do date >> /shared/log.txt; sleep 5; done"]
    volumeMounts:
    - name: shared-data
      mountPath: /shared
  volumes:
  - name: shared-data
    emptyDir: {}

5-2. livenessProbe로 Self-healing Pod 만들기

kubelet이 컨테이너 상태를 주기적으로 체크해 비정상 시 자동 재시작

Probe 종류

종류설명
httpGetHTTP GET 요청으로 상태 확인
tcpSocketTCP 포트 연결 확인
exec명령 실행 후 종료 코드 확인
spec:
  containers:
  - name: nginx
    image: nginx
    livenessProbe:
      httpGet:
        path: /
        port: 80
      initialDelaySeconds: 5   # 첫 체크 대기 시간
      periodSeconds: 10         # 체크 주기
      failureThreshold: 3       # 실패 허용 횟수
# exec 방식
livenessProbe:
  exec:
    command:
    - cat
    - /tmp/healthy
  initialDelaySeconds: 5
  periodSeconds: 5

5-3, 4. Init Container & Infra Container

Init Container

메인 컨테이너 시작 전 순차적으로 실행되는 초기화 컨테이너

  • 완료되어야 다음 Init Container 또는 메인 컨테이너 실행
  • DB 연결 대기, 설정 파일 생성 등에 사용
spec:
  initContainers:
  - name: init-db
    image: busybox
    command: ["sh", "-c", "until nslookup db-service; do echo waiting; sleep 2; done"]
  - name: init-config
    image: busybox
    command: ["sh", "-c", "echo 'config ready' > /config/ready"]
    volumeMounts:
    - name: config
      mountPath: /config
  containers:
  - name: app
    image: myapp
    volumeMounts:
    - name: config
      mountPath: /config
  volumes:
  - name: config
    emptyDir: {}

Infra Container (pause container)

  • Pod 생성 시 자동으로 같이 생성되는 숨겨진 컨테이너
  • Pod의 네트워크 네임스페이스(IP)를 소유하고 유지
  • docker ps 로 확인하면 pause 이미지로 표시됨
  • 사용자가 직접 제어하지 않음

5-5. Static Pod (feat. kubelet daemon)

API server 없이 kubelet이 직접 관리하는 Pod

핵심 동작 방식

  • 각 노드의 /etc/kubernetes/manifests/ 에 YAML 추가/삭제 시 kubelet이 즉시 생성/종료
  • kubectl delete pod 로 삭제해도 manifest 파일이 있으면 kubelet이 즉시 재생성
  • kube-apiserver, etcd, scheduler 등 Control plane 컴포넌트가 이 방식으로 실행됨

노드별 적용

  • manifest 경로는 해당 노드에만 적용
  • worker 노드에 Static Pod 추가 → 해당 worker에 SSH 접속 후 파일 배치

경로 확인

# staticPodPath 확인
cat /var/lib/kubelet/config.yaml | grep staticPodPath
# staticPodPath: /etc/kubernetes/manifests
 
ls /etc/kubernetes/manifests/
# etcd.yaml  kube-apiserver.yaml  kube-controller-manager.yaml  kube-scheduler.yaml

Static Pod 생성/삭제

# 생성: manifests 경로에 파일 복사
sudo cp my-static-pod.yaml /etc/kubernetes/manifests/
 
# 삭제: 파일 제거
sudo rm /etc/kubernetes/manifests/my-static-pod.yaml

5-6. Pod Resource 할당 (CPU/Memory Requests, Limits)

spec:
  containers:
  - name: app
    image: nginx
    resources:
      requests:           # 스케줄링 기준 (최소 보장)
        cpu: "250m"       # 1 CPU = 1000m
        memory: "64Mi"
      limits:             # 사용 상한 (초과 시 OOM Kill)
        cpu: "500m"
        memory: "128Mi"
# 노드 리소스 확인
kubectl describe node worker-1 | grep -A5 "Allocated resources"
 
# Pod 리소스 사용량
kubectl top pod
kubectl top pod --sort-by=cpu

5-7. Pod 환경변수 설정과 실행 패턴

spec:
  containers:
  - name: app
    image: nginx
    # 직접 설정
    env:
    - name: DB_HOST
      value: "mysql-service"
    - name: DB_PORT
      value: "3306"
    # ConfigMap에서 가져오기
    - name: APP_CONFIG
      valueFrom:
        configMapKeyRef:
          name: my-config
          key: config-key
    # Secret에서 가져오기
    - name: DB_PASSWORD
      valueFrom:
        secretKeyRef:
          name: my-secret
          key: password

Pod 실행 패턴

패턴설명사용 예
단일 컨테이너가장 일반적인 형태웹서버, API
Sidecar메인 + 보조 컨테이너로그 수집, 프록시
Init + 메인초기화 후 메인 실행DB 대기, 설정 생성
Multi Container여러 컨테이너 협업마이크로서비스

실습 명령어 모음

# Pod 생성 및 확인
kubectl apply -f pod.yaml
kubectl get pods -o wide
kubectl describe pod my-pod
 
# livenessProbe 상태 확인
kubectl describe pod my-pod | grep -A10 "Liveness"
 
# Init Container 로그
kubectl logs my-pod -c init-db
 
# Static Pod 확인
ls /etc/kubernetes/manifests/
cat /var/lib/kubelet/config.yaml | grep staticPodPath
 
# 리소스 사용량
kubectl top pod
kubectl top node

문제 정답

문제 1 — node01에 Static Pod mydb 생성

핵심 포인트: Static Pod는 node01에 SSH 접속해서 직접 manifest 파일을 배치해야 함

bash

# 1. node01의 staticPodPath 확인
ssh node01
cat /var/lib/kubelet/config.yaml | grep staticPodPath
# staticPodPath: /etc/kubernetes/manifests
 
# 2. manifest 파일 작성
# /etc/kubernetes/manifests/mydb.yaml
apiVersion: v1
kind: Pod
metadata:
  name: mydb
  namespace: default
spec:
  containers:
  - name: mydb
    image: redis
 
# 3. 확인 (master에서)
kubectl get pods
# mydb-node01   1/1   Running   0   ...

채점 조건 확인:

  • staticPodPath 경로에 파일 배치 → kubelet이 자동 생성/재시작
  • Pod 이름이 mydb-node01로 표시됨 (Static Pod는 노드명이 자동으로 suffix로 붙음)

문제 2 — 조건에 맞는 Pod myweb 생성

# 1. namespace product 생성 (없을 경우)
kubectl create namespace product
 
# 2. YAML 생성
#  myweb.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myweb
  namespace: product
spec:
  containers:
  - name: myweb
    image: nginx:1.14
    env:
    - name: DB
      value: "mydb"
    resources:
      requests:
        cpu: "200m"
        memory: "500Mi"
      limits:
        cpu: "1"
        memory: "1Gi"
 
# 3. 적용
kubectl apply -f myweb.yaml
 
# 4. 확인
kubectl get pod myweb -n product
kubectl describe pod myweb -n product

체크리스트

  • Single / Multi Container Pod YAML 작성
  • Pod 동작 flow (kubectl → apiserver → scheduler → kubelet) 설명
  • livenessProbe 3가지 방식 (httpGet, tcpSocket, exec)
  • Init Container 동작 순서 이해
  • Infra(pause) Container 역할
  • Static Pod 경로 및 생성/삭제 방법
  • cat /var/lib/kubelet/config.yaml | grep staticPodPath 로 경로 확인
  • Requests vs Limits 차이
  • 환경변수 직접/ConfigMap/Secret 세 가지 방법

참고 링크