학습 내용
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: 80Multi 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 종류
| 종류 | 설명 |
|---|---|
| httpGet | HTTP GET 요청으로 상태 확인 |
| tcpSocket | TCP 포트 연결 확인 |
| 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: 55-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.yamlStatic Pod 생성/삭제
# 생성: manifests 경로에 파일 복사
sudo cp my-static-pod.yaml /etc/kubernetes/manifests/
# 삭제: 파일 제거
sudo rm /etc/kubernetes/manifests/my-static-pod.yaml5-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=cpu5-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: passwordPod 실행 패턴
| 패턴 | 설명 | 사용 예 |
|---|---|---|
| 단일 컨테이너 | 가장 일반적인 형태 | 웹서버, 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 세 가지 방법