Pod μμ± νλ‘μ° μμ½ (μ μ μΌμ΄μ€)
kubectl apply β API Server β ETCD β Scheduler β Kubelet β Running
0.1μ΄ 0.1μ΄ 0.5μ΄ 0.1μ΄ 5-30μ΄
κ°μ₯ μ€λ 걸리λ λ¨κ³: μ΄λ―Έμ§ λ€μ΄λ‘λ (5-30μ΄)
μ 체 μμ μκ°: 7-35μ΄ (μ΄λ―Έμ§ ν¬κΈ°μ λ°λΌ)
μ΄ κΈμμ λ°°μ°λ κ²:
k3sλ‘ κ°μΈ νλ‘μ νΈλ₯Ό μ΄μνλ©΄μ μμ±μ΄ κ°μΈνλ‘μ νΈμ΄κ³ μκ·λͺ¨μΈλ° μλκ° μκ°λ³΄λ€ λ§μ΄ κ±Έλ Έλλ° μ΄ μ΄μ λ₯Ό μ°Ύκ³ , k8s νκ²½μμ κ° μμμμ μΌλ§μ λκ° κ±Έλ¦΄κΉ νμΈμ νλ €κ³ νμ΅λλ€.
kubectl get pods --watch
NAME READY STATUS AGE
nginx 0/1 ContainerCreating 30s # β μ μ΄λ κ² μ€λ κ±Έλ €?
κ°λ¨ κ²°λ‘ Β Β» μ΄λ―Έμ§ λ€μ΄λ‘λμ μκ°μ΄ λλΆλΆμ΄λ€. (μ΄λ―Έμ§λ₯Ό μ΅μ ννμ.)
μ΄ κΈμμλ:
kubectl apply -f pod.yaml
β (1) 0.1μ΄
βββββββββββββββββββββββββββββββββββββββ
β API Server β
β - μΈμ¦/μΈκ° νμΈ β
β - YAML κ²μ¦ β
ββββββββββββββββ¬βββββββββββββββββββββββ
β (2) 0.05μ΄
βββββββββββββββββββββββββββββββββββββββ
β ETCD β
β - Pod μ 보 μ μ₯ β
β - status: "Pending" β
ββββββββββββββββ¬βββββββββββββββββββββββ
β (3) 0.5-2μ΄
βββββββββββββββββββββββββββββββββββββββ
β Scheduler β
β - μ ν©ν λ
Έλ μ°ΎκΈ° β
β - nodeName κ²°μ β
ββββββββββββββββ¬βββββββββββββββββββββββ
β (4) 0.1μ΄
βββββββββββββββββββββββββββββββββββββββ
β Kubelet (μ컀 λ
Έλ) β
β - μ΄λ―Έμ§ λ€μ΄λ‘λ β (κ°μ₯ μ€λ!) β
β - 컨ν
μ΄λ μμ± β
ββββββββββββββββ¬βββββββββββββββββββββββ
β (5) 5-30μ΄
Pod Running β
kubectl λͺ λ ΉΒ Β» API Serverλ‘ HTTPS μμ²
# ~/.kube/config νμΌμμ ν΄λ¬μ€ν° μ 보 μ½κΈ°
cat ~/.kube/config
μΆλ ₯:
clusters:
- cluster:
server: https://192.168.1.100:6443 # β API Server μ£Όμ
API Serverκ° νλ μΌ:
1. μΈμ¦ (Authentication)
2. μΈκ° (Authorization - RBAC)
3. κ²μ¦ (Validation)
μ€μ μΈ‘μ :
# time λͺ
λ ΉμΌλ‘ μΈ‘μ
time kubectl apply -f simple-pod.yaml
# μΆλ ₯:
real 0m0.152s # β API Server μλ΅ μκ°
API Serverλ κ²μ¦μ΄ λλλ©΄ ETCDμ μ μ₯νλ€.
ETCDμ μ μ₯λλ λ΄μ© (λ¨μν):
Key: /registry/pods/default/nginx
Value: {
"metadata": {
"name": "nginx",
"namespace": "default"
},
"spec": {
"containers": [...]
},
"status": {
"phase": "Pending" # β μ΄κΈ° μν
}
}
μ€λ¬΄ ν¬μΈνΈ:
**μ§μ ETCD νμΈνκΈ° **
ETCDCTL_API=3 etcdctl get /registry/pods/default/nginx \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
β μ€μ μ μ₯λ λ°μ΄ν°λ₯Ό λ³Ό μ μμ (λλ²κΉ μ μ μ©)
μ΄ λ¨κ³κ° K8sμ ν΅μ¬μ΄λ€. Schedulerκ° μ΄λ λ Έλμ Podλ₯Ό λ°°μΉν μ§ κ²°μ νλ€.
Schedulerμ 2λ¨κ³ μκ³ λ¦¬μ¦:
1λ¨κ³: Filtering (λΆκ°λ₯ν λ Έλ μ μΈ)
λͺ¨λ λ
Έλ κ²μ¬:
ββ CPU λΆμ‘± λ
Έλ μ μΈ
ββ Memory λΆμ‘± λ
Έλ μ μΈ
ββ NodeSelector λΆμΌμΉ μ μΈ
ββ Taint/Toleration λΆμΌμΉ μ μΈ
ββ κ²°κ³Ό: κ°λ₯ν λ
Έλ 리μ€νΈ
2λ¨κ³: Scoring (μ μ λ§€κΈ°κΈ°)
κ° λ
Έλμ μ μ λΆμ¬:
ββ 리μμ€ μ¬μ λ (κ°μ€μΉ 1)
ββ Pod λΆμ°λ (κ°μ€μΉ 1)
ββ Affinity κ·μΉ (κ°μ€μΉ 2)
ββ κ²°κ³Ό: μ΅κ³ μ μ λ
Έλ μ ν
μ€μ μμ:
μ΄κΈ° μν:
- node1: CPU 90%, Memory 80%
- node2: CPU 50%, Memory 60% β μ μ λμ!
- node3: CPU 70%, Memory 85%
Scheduler κ²°μ : node2 μ ν β
μ€μ μΈ‘μ :
# Scheduler κ²°μ μκ° νμΈ
kubectl get events --sort-by='.lastTimestamp' | grep Scheduled
# μΆλ ₯:
0s Normal Scheduled pod/nginx Successfully assigned default/nginx to node2
λλ²κΉ ν:
# μ μ΄ λ
Έλμ λ°°μ λλμ§ νμΈ
kubectl describe pod nginx
# Events μΉμ
:
Events:
Type Reason Message
---- ------ -------
Normal Scheduled Successfully assigned to node2
κ°μ₯ μ€λ 걸리λ λ¨κ³!
Schedulerκ° nodeNameμ node2λ‘ μ€μ νλ©΄, node2μ Kubeletμ΄ Watchλ‘ κ°μ§νλ€.
Kubelet (node2):
"μ΄? ETCDμ λ΄ λ
Έλ μ΄λ¦μ΄ μΆκ°λλ€!"
"μ΄ Podλ₯Ό μ€νν΄μΌκ² λ€!"
μκ°μ΄ μ€λ 걸리λ μμ μ΄μλ€.
nginx μ΄λ―Έμ§ μμ:
docker images nginx
REPOSITORY TAG SIZE
nginx latest 187MB # β μ½ 6μ΄ μμ (λ΄ νκ²½)
μ΄λ―Έμ§ Pull κ³Όμ :
1. λ‘컬μ μ΄λ―Έμ§ μλ? νμΈ (0.1μ΄)
ββ μμΌλ©΄ β μ¦μ 컨ν
μ΄λ μμ± (1-2μ΄)
ββ μμΌλ©΄ β λ€μ΄λ‘λ μμ
2. Docker Hubμμ λ€μ΄λ‘λ
nginx:latest (187MB)
ββ Layer 1: 50MB (2μ΄)
ββ Layer 2: 37MB (1μ΄)
ββ Layer 3: 100MB (3μ΄)
ν©κ³: 6μ΄
3. μμΆ ν΄μ & κ²μ¦ (1μ΄)
4. 컨ν
μ΄λ μμ± (1μ΄)
μ€μ μΈ‘μ :
# λ‘컬μ μ΄λ―Έμ§ μλ μνλ‘ ν
μ€νΈ
docker rmi nginx:latest
# Pod μμ± μκ° μΈ‘μ
kubectl delete pod nginx
time kubectl apply -f nginx-pod.yaml && \
kubectl wait --for=condition=ready pod/nginx --timeout=60s
# μΆλ ₯:
real 0m8.234s # β 8μ΄ μμ (μ΄λ―Έμ§ λ€μ΄ ν¬ν¨)
# μ΄λ―Έμ§ μλ μνλ‘ μ¬μλ
kubectl delete pod nginx
time kubectl apply -f nginx-pod.yaml && \
kubectl wait --for=condition=ready pod/nginx --timeout=60s
# μΆλ ₯:
real 0m2.145s # β 2μ΄! (μ΄λ―Έμ§ μΊμ μ¬μ©)
β μ©λ μ°¨μ΄λ λ§μ΄ λκ³ , μλλ μ°¨μ΄κ° λ§μ΄ λλ€.
Container Runtime (containerd):
1. 컨ν
μ΄λ μμ± (0.5μ΄)
ββ λ€μμ€νμ΄μ€, Cgroup μ€μ
2. λ€νΈμν¬ μ€μ (0.3μ΄)
ββ CNI νλ¬κ·ΈμΈ νΈμΆ
ββ IP ν λΉ (μ: 10.244.1.5)
3. λ³Όλ₯¨ λ§μ΄νΈ (0.2μ΄)
ββ ConfigMap, Secret λ±
4. ENTRYPOINT μ€ν (0.1μ΄)
ββ nginx νλ‘μΈμ€ μμ
Kubeletμ΄ API Serverμ μν λ³΄κ³ :
ETCD μ
λ°μ΄νΈ:
{
"status": {
"phase": "Running", # β Pendingμμ λ³κ²½!
"containerStatuses": [{
"ready": true,
"restartCount": 0,
"state": {
"running": {
"startedAt": "2025-10-13T10:05:30Z"
}
}
}]
}
}
λ¨κ³ | μ»΄ν¬λνΈ | μμ μκ° | λΉκ³ |
---|---|---|---|
1 | API Server | 50-150ms | kubectl μλ΅ |
2 | ETCD | 10-50ms | μ μ₯ |
3 | Scheduler | 100-500ms | λ Έλ μ ν |
4-1 | Kubelet | 100ms | κ°μ§ |
4-2 | Runtime | 5-8μ΄ | μ΄λ―Έμ§ λ€μ΄ β |
4-3 | Runtime | 1-2μ΄ | 컨ν μ΄λ μμ± |
ν©κ³ | Β | 7-12μ΄ | μ΄λ―Έμ§ μμ λ |
ν©κ³ | Β | 2-3μ΄ | μ΄λ―Έμ§ μμ λ β |
μ΄λ―Έμ§ ν¬κΈ°λ³ λΉκ΅ (μ€μΈ‘):
μ΄λ―Έμ§ | ν¬κΈ° | λ€μ΄λ‘λ μκ° | μ 체 μκ° |
---|---|---|---|
nginx:alpine | 42MB | 2μ΄ | 4μ΄ β |
nginx:latest | 187MB | 6μ΄ | 8μ΄ |
python:3.9 | 915MB | 30μ΄ | 32μ΄ |
3κ° ν°λ―Έλλ‘ μ κ³Όμ κ΄μ°° (μ€λ¬΄ νμ μ€ν¬!)
# ν°λ―Έλ 1: Pod μν μ€μκ° λ³΄κΈ°
kubectl get pods --watch
# ν°λ―Έλ 2: μ΄λ²€νΈ μ€μκ° λ³΄κΈ° (κ°μ₯ μ€μ!)
kubectl get events --watch
# ν°λ―Έλ 3: Pod μμ±
kubectl apply -f nginx-pod.yaml
μ€μ μΆλ ₯:
ν°λ―Έλ 1 (Pod μν):
NAME READY STATUS AGE
nginx 0/1 Pending 0s
nginx 0/1 Pending 0s # β Scheduler μλ μ
nginx 0/1 ContainerCreating 2s # β λ
Έλ λ°°μ λ¨
nginx 1/1 Running 8s # β μλ£!
ν°λ―Έλ 2 (μ΄λ²€νΈ):
LAST SEEN TYPE REASON MESSAGE
0s Normal Scheduled Successfully assigned default/nginx to node1
2s Normal Pulling Pulling image "nginx:latest"
7s Normal Pulled Successfully pulled image
8s Normal Created Created container nginx
8s Normal Started Started container nginx
β μ΄λ°μμΌλ‘ μ΄λ€κ² μ€λ걸리λμ§ λͺ¨λν°λ§ν μ μλ€.
ν μ€ λͺ λ ΉμΌλ‘ 보기:
kubectl get events --sort-by='.lastTimestamp' | tail -20
Before (κΈ°λ³Έκ°):
spec:
containers:
- name: nginx
image: nginx:latest
# imagePullPolicy μμ β Alwaysλ‘ λμ
β λ§€λ² μ΄λ―Έμ§ νμΈ, μ½ 8μ΄ μμ
After (μ΅μ ν):
spec:
containers:
- name: nginx
image: nginx:latest
imagePullPolicy: IfNotPresent # λ‘컬 μ°μ !
β λ‘컬 μ΄λ―Έμ§ μ¬μ©, μ½ 2μ΄ μμ β
μ€λ¬΄ μ μ©:
IfNotPresent
(λΉ λ₯Έ μ¬λ°°ν¬)Always
(μ΅μ μ΄λ―Έμ§ 보μ₯)Before:
nginx:latest # 187MB β 6μ΄
After:
nginx:alpine # 42MB β 2μ΄ β
μ€μ λΉκ΅:
# nginx:latest ν
μ€νΈ
time kubectl apply -f nginx-pod.yaml && \
kubectl wait --for=condition=ready pod/nginx --timeout=60s
# real 0m8.234s
# nginx:alpine ν
μ€νΈ
time kubectl apply -f nginx-alpine-pod.yaml && \
kubectl wait --for=condition=ready pod/nginx-alpine --timeout=60s
# real 0m4.156s
β κ±°μ μ λ°!
# λκ° μ΄μνλ©΄ 무쑰건 μ΄κ²λΆν°!
kubectl get events --sort-by='.lastTimestamp'
μ¬λ‘ μμ :
Podκ° 30μ΄μ§Έ ContainerCreatingμΈλ° μμΈμ λͺ¨λ₯Ό λ:
kubectl describe pod my-app
# Events:
Events:
Type Reason Message
Normal Scheduled Successfully assigned to node1
Normal Pulling Pulling image...
Warning Failed Failed to pull image: timeout # β μμΈ!
β λ€νΈμν¬ νμμμ! Registry μ£Όμ νμΈνλ μ€νμμ
λλ²κΉ 체ν¬λ¦¬μ€νΈ:
1. kubectl get pods # μν νμΈ
2. kubectl describe pod <name> # Events νμΈ
3. kubectl logs <name> # μ± λ‘κ·Έ νμΈ
β μ΄ μμλ‘ 90% λ¬Έμ ν΄κ²° κ°λ₯!
λ΄κ° μ μ©ν 3κ°μ§:
nginx:latest β nginx:alpine
187MB β 42MB
imagePullPolicy: IfNotPresent
Harbor μ€μΉ β λ΄λΆλ§μμ 3μ΄ μμ λ€μ΄
κ²°κ³Ό:
Q: βPod μμ±μ΄ λλ¦°λ° μ΄λλ₯Ό νμΈνμκ² μ΄μ?β
A: βλ¨Όμ kubectl get events --watch
λ‘ μ΄λ λ¨κ³μμ μκ°μ΄ 걸리λμ§ νμΈν©λλ€. λλΆλΆ μ΄λ―Έμ§ λ€μ΄λ‘λκ° μμΈμ΄λΌ imagePullPolicy
λ₯Ό IfNotPresent
λ‘ λ°κΎΈκ±°λ alpine μ΄λ―Έμ§λ₯Ό μ¬μ©ν©λλ€. μ€μ λ‘ μ νλ‘μ νΈμμ μ΄ λ°©λ²μΌλ‘ λ°°ν¬ μκ°μ 35μ΄μμ 8μ΄λ‘ μ€μμ΅λλ€.β
Q: βK8sμμ κ°μ₯ μ€μν μ»΄ν¬λνΈλ λκ°μ?β
A: βETCDμ λλ€. μ μΌν λ°μ΄ν°λ² μ΄μ€λΌμ ETCD μμ΄λ μ무κ²λ μλνμ§ μμ΅λλ€. κ·Έλμ μ k3s νκ²½μμλ λ§€μΌ μλμΌλ‘ ETCD λ°±μ μ S3μ μ μ₯νλλ‘ μ€μ νμ΅λλ€.β
time
, kubectl get events --watch
μμ±μΌ: 2025-10-13
νκ²½: k3s v1.28, λ‘컬 3-node cluster