/ [pdf]



1. Pod

    / [pdf]

์•„๋ž˜์™€ ๊ฐ™์ด goapp.yaml ํŒŒ์ผ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

- Pod ์ƒ์„ฑ ํ•ด๋ณด๊ธฐ

  apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80
  
  kubectl create -f ./nginx.yaml
  

ใ„ดใ„ดssss

  kubectl get pod
  

- POD ์„œ๋น„์Šค ์ ‘์† ๋ฐ ๋กœ๊ทธํ™•์ธ

  • ์ ‘์†์„ ์œ„ํ•œ ํฌํŠธํฌ์›Œ๋”ฉ
  kubectl port-forward nginx-pod 8080:80
  
  • Pod์˜ ๋„คํŠธ์›Œํฌ IP ์กฐํšŒ
  kubectl get po -o wide
  
  • ๋‹ค๋ฅธ ํ„ฐ๋ฏธ๋„์—์„œ curl ์„ ์ด์šฉํ•ด์„œ ํ…Œ์ŠคํŠธ
  curl http://<Pod-IP-Address>:8080
  
  • POD Bash ์ ‘์†
  kubectl exec -it nginx-pod -- bash
  
  • POD ์ด๋ฒคํŠธ ํ™•์ธํ•˜๊ธฐ
  kubectl describe po nginx-pod
  
  • ์ปจํ…Œ์ด๋„ˆ ๋กœ๊ทธ ํ™•์ธ ํ•ด๋ณด๊ธฐ
  kubectl logs nginx-pod
  

- [์—ฐ์Šต๋ฌธ์ œ] 4-1. Pod ์ƒ์„ฑํ•˜๊ธฐ

  1. ์•„๋ž˜ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” Pod๋ฅผ ์ƒ์„ฑํ•˜๋Š” YAML ํŒŒ์ผ์„ ์ž‘์„ฑํ•˜๊ณ , ์‹ค์ œ๋กœ ํด๋Ÿฌ์Šคํ„ฐ์— ๋ฐฐํฌํ•ด๋ณด์„ธ์š”.

    • Pod ์ด๋ฆ„: my-redis
    • ์ปจํ…Œ์ด๋„ˆ ์ด๋ฆ„: redis
    • ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€: redis:7.2
    • ์ปจํ…Œ์ด๋„ˆ๊ฐ€ 6379๋ฒˆ ํฌํŠธ๋กœ ์„œ๋น„์Šค
  2. redis๊ฐ€ ์‹คํ–‰์ค‘์ธ ์ปจํ…Œ์ด๋„ˆ์— bash๋กœ ์ ‘์†ํ›„ ํ”„๋กœ์„ธ์Šค๋ฅผ ์กฐํšŒ ํ•˜์„ธ์š”

  3. ํŒŒ๋“œ์˜ ์ด๋ฒคํŠธ ๋กœ๊ทธ๋ฅผ ํ™•์ธํ•˜์„ธ์š”

  4. redis ์ปจํ…Œ์ด๋„ˆ์˜ ๋กœ๊ทธ๋ฅผ ํ™•์ธํ•˜์„ธ์š”

2. ๋ผ๋ฒจ(Label)๊ณผ ์–ด๋…ธํ…Œ๋‹ˆ์…˜(annotaion)

    / [pdf]



- ๋ผ๋ฒจ(label)

  1. goapp-with-label.yaml ์ด๋ผ ํŒŒ์ผ์— ์•„๋ž˜ ๋‚ด์šฉ์„ ์ถ”๊ฐ€ ํ•˜์—ฌ ์ž‘์„ฑ ํ•ฉ๋‹ˆ๋‹ค.
  apiVersion: v1
kind: Pod
metadata:
  name: goapp-pod
  labels:
    env: prod
    tier: backend
spec:
  containers:
  - image: dangtong/goapp
    name: goapp-container
    ports:
    - containerPort: 8080
      protocol: TCP
  
  1. yaml ํŒŒ์ผ์„ ์ด์šฉํ•ด pod ๋ฅผ ์ƒ์„ฑ ํ•ฉ๋‹ˆ๋‹ค.
  kubectl apply -f ./goapp-with-label.yaml
  
  1. ์ƒ์„ฑ๋œ POD๋ฅผ ์กฐํšŒ ํ•ฉ๋‹ˆ๋‹ค.
  kubectl get po --show-labels
  
  1. label ํƒœ๊ทธ๋ฅผ ์ถœ๋ ฅ ํ™”๋ฉด์— ์ปฌ๋Ÿผ์„ ๋ถ„๋ฆฌํ•ด์„œ ์ถœ๋ ฅ
  kubectl get po -L env -L tier
  
  1. Label ์ถ”๊ฐ€
  kubectl label po goapp-pod app=web
  
  1. label ์ˆ˜์ •
  kubectl label po goapp-pod app=api --overwrite
  
  1. Label ์‚ญ์ œ
  kubectl label po goapp-pod app-
  

- ์–ด๋…ธํ…Œ์ด์…˜(Annotation)

  1. Annotaion ์ถ”๊ฐ€
  kubectl annotate pod goapp-pod maker="dangtong" team="k8s-team"
  
  1. Annotation ํ™•์ธ
  kubectl describe po goapp-pod
  
  1. Annotation ์‚ญ์ œ
  kubectl annotate po goapp-pod maker- team-
  

- [์—ฐ์Šต๋ฌธ์ œ] 4-2. Label ๋ฐ Annotaion ์‹ค์Šต

  • bitnami/apache ์ด๋ฏธ์ง€๋กœ Pod ๋ฅผ ๋งŒ๋“ค๊ณ  tier=FronEnd, app=apache ๋ผ๋ฒจ ์ •๋ณด๋ฅผ ํฌํ•จํ•˜์„ธ์š”

  • Pod ์ •๋ณด๋ฅผ ์ถœ๋ ฅ ํ• ๋•Œ ๋ผ๋ฒจ์„ ํ•จ๊ป˜ ์ถœ๋ ฅ ํ•˜์„ธ์š”

  • app=apache ๋ผ๋ฒจํ‹€ ๊ฐ€์ง„ Pod ๋งŒ ์กฐํšŒ ํ•˜์„ธ์š”

  • ๋งŒ๋“ค์–ด์ง„ Pod์— env=dev ๋ผ๋Š” ๋ผ๋ฒจ ์ •๋ณด๋ฅผ ์ถ”๊ฐ€ ํ•˜์„ธ์š”

  • created_by=kevin ์ด๋ผ๋Š” Annotation์„ ์ถ”๊ฐ€ ํ•˜์„ธ์š”

  • ๋ชจ๋“  ๋ผ๋ฒจ๊ณผ ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ญ์ œ ํ•˜์„ธ์š”

3. Namespace

    / [pdf]



- ํ˜„์žฌ ๋„ค์ž„์ŠคํŽ˜์ด์Šค ์กฐํšŒ

  kubectl get namespace
  
  kubens
  



- ํŠน์ • ๋„ค์ž„์ŠคํŽ˜์ด์Šค์˜ ๋ฆฌ์†Œ์Šค ์กฐํšŒ

  kubectl get po --namespace kube-system
  
  kubectl get po -n kube-system
  



- ๋„ค์ž„์ŠคํŽ˜์ด์Šค ์ƒ์„ฑ

  1. YAML ํŒŒ์ผ ์ž‘์„ฑ : first-namespace.yaml ์ด๋ฆ„์œผ๋กœ ํŒŒ์ผ ์ž‘์„ฑ
  apiVersion: v1
kind: Namespace
metadata:
  name: first-namespace
  
  1. YAML ํŒŒ์ผ์„ ์ด์šฉํ•œ ๋„ค์ด์ŠคํŽ˜์ด์Šค ์ƒ์„ฑ
  kubectl create -f first-namespace.yaml
  
  1. ์ƒ์„ฑ๋œ ๋„ค์ž„์ŠคํŽ˜์ด์Šค ํ™•์ธ
  kubectl get ns
  
  1. ๋ช…๋ น์–ด ์ด์šฉํ•œ ๋„ค์ž„์ŠคํŽ˜์ด์Šค ์ƒ์„ฑ
  kubectl create ns second-namespace
  



- ๋„ค์ž„์ŠคํŽ˜์ด์Šค ์ด๋™

๊ธฐ๋ณธ์ ์œผ๋กœ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์—์„œ ์ง€์› ํ•˜๋Š” ๋ฐฉ๋ฒ•

  kubectl config set-context --current --namespace=<namespace-name>
  

kubens ๋ฅผ ์„ค์น˜ํ•˜๋ฉด ๋„ค์ž„์ŠคํŽ˜์ด์Šค ๋ชฉ๋ก,ํ˜„์žฌ ๋„ค์ž„์ŠคํŽ˜์ด์Šค ํ™•์ธ ํ•˜๊ณ , ๋‹ค๋ฅธ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋กœ ์ด๋™ ๊ฐ€๋Šฅ

  kubens
  
  kubens kube-system
  



- ๊ธฐํƒ€ ๋„ค์ž„์ŠคํŽ˜์ด์Šค ๊ด€๋ จ

  • ๋ชจ๋“  ๋„ค์ž„์ŠคํŽ˜์ด์Šค์˜ Pod ์กฐํšŒ
  kubectl get po -A
  
  • ๋ชจ๋“  ๋„ค์ž„์ŠคํŽ˜์ด์Šค์˜ ๋ฆฌ์†Œ์Šค ์กฐํšŒ
  kubectl get all -A
  
  • ํŠน์ • ๋„ค์ž„์ŠคํŽ˜์ด์Šค์—์„œ์˜ ๋ฆฌ์†Œ์Šค ์กฐํšŒ
  kubectl get po -n kube-system
  
  • ๋„ค์ž„์ŠคํŽ˜์ด์Šค ๋ ˆ๋ฒจ ๋ฆฌ์†Œ์Šค ์กฐํšŒ
  kubectl api-resources --namespaced=true
  
  • ๋„ค์ž„์ŠคํŽ˜์ด์Šค๊ฐ€ ์•„๋‹Œ ๋ฆฌ์†Œ์Šค ์กฐํšŒ
  kubectl api-resources --namespaced=false
  

- ๋„ค์ž„์ŠคํŽ˜์ด์Šค ์‚ญ์ œ

  kubectl delete ns first-namespace second-namespace
  



4. Probe

    / [pdf]



- Liveness Probe ํ…Œ์ŠคํŠธ

์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์‚ด์•„์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ , ์‹คํŒจ ์‹œ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์žฌ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

HTTP Liveness Probe

  • Liveness Probe ์ƒ์„ฑ
    liveness prove๋Š” Pod์— ์ง€์ •๋œ ์ฃผ์†Œ์— Health Check ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ณ  ์‹คํŒจํ•  ๊ฒฝ์šฐ Pod๋ฅผ ๋‹ค์‹œ ์‹œ์ž‘ ํ•ฉ๋‹ˆ๋‹ค.
    ์ด๋•Œ ์ค‘์š”ํ•œ ์ ์€ ๋‹จ์ˆœํžˆ ๋‹ค์‹œ ์‹œ์ž‘๋งŒ ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋กœ ๋ถ€ํ„ฐ ์ด๋ฏธ์ง€๋ฅผ ๋‹ค์‹œ ๋ฐ›์•„ Pod ๋ฅผ ๋‹ค์‹œ ์‹œ์ž‘ ํ•ฉ๋‹ˆ๋‹ค.
  apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-http
spec:
  containers:
  - name: liveness
    image: k8s.gcr.io/liveness
    args:
    - /server
    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
        httpHeaders:
        - name: Custom-Header
          value: Awesome
      initialDelaySeconds: 3
      periodSeconds: 3
  

K8s.gcr.io/liveness ์ด๋ฏธ์ง€๋Š” liveness ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด ๋งŒ๋“ค์–ด์ง„ ์ด๋ฏธ์ง€ ์ž…๋‹ˆ๋‹ค.
์ž์„ธํ•œ ์‚ฌํ•ญ์€ gihub ์˜ liveness ์„ ์ฐธ๊ณ  ํ•˜์„ธ์š”
Go ์–ธ์–ด๋กœ ์ž‘์„ฑ ๋˜์—ˆ์œผ๋ฉฐ, ์ฒ˜์Œ 10์ดˆ ๋™์•ˆ์€ ์ •์ƒ์ ์ธ ์„œ๋น„์Šค๋ฅผ ํ•˜์ง€๋งŒ, 10์ดˆ ํ›„์—๋Š” ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ ์‹œํ‚ต๋‹ˆ๋‹ค. ์ฝ”๋“œ๋ฅผ ์ž์„ธํžˆ ๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
    duration := time.Now().Sub(started)
    if duration.Seconds() > 10 {
        w.WriteHeader(500)
        w.Write([]byte(fmt.Sprintf("error: %v", duration.Seconds())))
    } else {
        w.WriteHeader(200)
        w.Write([]byte("ok"))
    }
})
  
  • pod ์ƒ์„ฑ
  kubectl create -f ./liveness-probe-pod.yaml
  
  • pod ํ™•์ธ
  kubectl create -f ./liveness-probe-pod.yaml
  
  • pod ์ด๋ฒคํŠธ ๋กœ๊ทธ ํ™•์ธ
  kubectl describe pod liveness-http
  

Command Liveness Probe

liveness-command-pod.yaml

  apiVersion: v1
kind: Pod
metadata:
  name: liveness-command-pod
spec:
  containers:
  - name: liveness-command
    image: busybox:latest
    command: ["/bin/sh", "-c", "touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600"]
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 5
      periodSeconds: 5
  
  • pod ์ƒ์„ฑ
  kubectl create -f ./liveness-command-pod.yaml
  
  • pod ํ™•์ธ
  kubectl create -f ./liveness-command-pod.yaml
  
  • pod ์ด๋ฒคํŠธ ๋กœ๊ทธ ํ™•์ธ
  kubectl describe pod liveness-command-pod
  

- Readiness Probe

์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์š”์ฒญ์„ ๋ฐ›์„ ์ค€๋น„๊ฐ€ ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ , ์‹คํŒจ ์‹œ ์„œ๋น„์Šค ์—”๋“œํฌ์ธํŠธ์—์„œ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

์‹ค์Šต ์˜ˆ์ œ 1: HTTP Readiness Probe

  apiVersion: v1
kind: Pod
metadata:
  name: readiness-http-pod
spec:
  containers:
  - name: readiness-http
    image: nginx:latest
    ports:
    - containerPort: 80
    readinessProbe:
      httpGet:
        path: /
        port: 80
      initialDelaySeconds: 5
      periodSeconds: 3
      timeoutSeconds: 2
      failureThreshold: 2
  

์‹ค์Šต ์˜ˆ์ œ 2: TCP Readiness Probe

  apiVersion: v1
kind: Pod
metadata:
  name: readiness-tcp-pod
spec:
  containers:
  - name: readiness-tcp
    image: redis:7.2
    ports:
    - containerPort: 6379
    readinessProbe:
      tcpSocket:
        port: 6379
      initialDelaySeconds: 5
      periodSeconds: 10
  

- Startup Probe

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ดˆ๊ธฐ ์‹œ์ž‘ ์‹œ๊ฐ„์ด ๊ธด ๊ฒฝ์šฐ ์‚ฌ์šฉํ•˜๋ฉฐ, ์‹œ์ž‘ ํ”„๋กœ๋ธŒ๊ฐ€ ์„ฑ๊ณตํ•  ๋•Œ๊นŒ์ง€ ๋‹ค๋ฅธ ํ”„๋กœ๋ธŒ๋“ค์€ ๋น„ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค.

์‹ค์Šต ์˜ˆ์ œ: Startup Probe with Liveness

  apiVersion: v1
kind: Pod
metadata:
  name: startup-probe-pod
spec:
  containers:
  - name: startup-app
    image: nginx:latest
    ports:
    - containerPort: 80
    startupProbe:
      httpGet:
        path: /
        port: 80
      failureThreshold: 30
      periodSeconds: 10
    livenessProbe:
      httpGet:
        path: /
        port: 80
      periodSeconds: 5
    readinessProbe:
      httpGet:
        path: /
        port: 80
      periodSeconds: 3
  

- [์—ฐ์Šต๋ฌธ์ œ] 4-3. Probe ์‹ค์Šต

1. Liveness Probe ์‹ค์Šต

์•„๋ž˜ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” Pod๋ฅผ ์ƒ์„ฑํ•˜์„ธ์š”:

  • Pod ์ด๋ฆ„: liveness-demo
  • ์ด๋ฏธ์ง€: nginx:latest
  • Liveness probe: HTTP GET /health (ํฌํŠธ 80)
  • ์ดˆ๊ธฐ ์ง€์—ฐ: 10์ดˆ, ์ฃผ๊ธฐ: 5์ดˆ, ํƒ€์ž„์•„์›ƒ: 3์ดˆ, ์‹คํŒจ ์ž„๊ณ„๊ฐ’: 3

2. Readiness Probe ์‹ค์Šต

์•„๋ž˜ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” Pod๋ฅผ ์ƒ์„ฑํ•˜์„ธ์š”:

  • Pod ์ด๋ฆ„: readiness-demo
  • ์ด๋ฏธ์ง€: redis:7.2
  • Readiness probe: TCP ์†Œ์ผ“ (ํฌํŠธ 6379)
  • ์ดˆ๊ธฐ ์ง€์—ฐ: 5์ดˆ, ์ฃผ๊ธฐ: 10์ดˆ

3. Probe ์ƒํƒœ ํ™•์ธ ๋ช…๋ น์–ด

  # Pod ์ƒํƒœ ํ™•์ธ
kubectl get po

# Pod ์ƒ์„ธ ์ •๋ณด ํ™•์ธ (Probe ์ƒํƒœ ํฌํ•จ)
kubectl describe po <pod-name>

# Pod ๋กœ๊ทธ ํ™•์ธ
kubectl logs <pod-name>

# Pod ์ด๋ฒคํŠธ ํ™•์ธ
kubectl get events --sort-by='.lastTimestamp'
  

4. Probe ํ…Œ์ŠคํŠธ ๋ฐฉ๋ฒ•

  # 1. Pod ์ƒ์„ฑ
kubectl apply -f liveness-demo.yaml

# 2. Pod ์ƒํƒœ ๋ชจ๋‹ˆํ„ฐ๋ง
kubectl get po -w

# 3. Pod ์ƒ์„ธ ์ •๋ณด ํ™•์ธ
kubectl describe po liveness-demo

# 4. Pod ๋กœ๊ทธ ํ™•์ธ
kubectl logs liveness-demo

# 5. Pod ์‚ญ์ œ
kubectl delete po liveness-demo
  

- Probe ์„ค์ • ์˜ต์…˜ ์„ค๋ช…

๊ณตํ†ต ์˜ต์…˜:

  • initialDelaySeconds: ์ปจํ…Œ์ด๋„ˆ ์‹œ์ž‘ ํ›„ ์ฒซ ๋ฒˆ์งธ ํ”„๋กœ๋ธŒ ์‹คํ–‰๊นŒ์ง€ ๋Œ€๊ธฐ ์‹œ๊ฐ„
  • periodSeconds: ํ”„๋กœ๋ธŒ ์‹คํ–‰ ์ฃผ๊ธฐ
  • timeoutSeconds: ํ”„๋กœ๋ธŒ ํƒ€์ž„์•„์›ƒ ์‹œ๊ฐ„
  • failureThreshold: ์‹คํŒจ ์ž„๊ณ„๊ฐ’ (์ด ํšŸ์ˆ˜๋งŒํผ ์‹คํŒจํ•˜๋ฉด ์‹คํŒจ๋กœ ๊ฐ„์ฃผ)
  • successThreshold: ์„ฑ๊ณต ์ž„๊ณ„๊ฐ’ (Readiness/Startup probe์—์„œ๋งŒ ์‚ฌ์šฉ)

ํ”„๋กœ๋ธŒ ํƒ€์ž…:

  1. httpGet: HTTP GET ์š”์ฒญ
  2. tcpSocket: TCP ์†Œ์ผ“ ์—ฐ๊ฒฐ
  3. exec: ๋ช…๋ น์–ด ์‹คํ–‰

5. Replication Controller

    / [pdf]



- Replication Controller ์ƒ์„ฑ

  apiVersion: v1
kind: ReplicationController
metadata:
  name: goapp-rc
spec:
  replicas: 3
  selector:
    app: goapp
  template:
    metadata:
      name: goapp-pod
      labels:
        tier: forntend
        app: goapp
        env: prod
        priority:  high
    spec:
      containers:
      - name: goapp-container
        image: dangtong/goapp
        ports:
        - containerPort: 8080
  

- ์ƒ์„ฑ ํ™•์ธ

  kubectl get po,rc
  

- Pod ์‚ญ์ œํ›„ ๋ณ€ํ™˜ ํ™•์ธ

  kubectl delete pod goapp-rc-<random-hash>
  

- Pod ์ •๋ณด ์ถœ๋ ฅ

  kubectl get pod --show-labels
  

- Pod ๋ผ๋ฒจ ๋ณ€๊ฒฝ ๋ฐ ํ˜„์ƒ ํ™•์ธ

  kubectl label pod goapp-rc-szv2r app=goapp-exit --overwrite
  
  kubectl get po
  

- Pod ์ด๋ฏธ์ง€ ๋ณ€๊ฒฝ

  kubectl edit rc goapp-rc
  

์ด๋ฏธ์ง€ ๋ถ€๋ถ„์„ ์ฐพ์•„์„œ goapp-v2๋กœ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.

  template:
  metadata:
    creationTimestamp: null
    labels:
      app: goapp
    name: goapp-pod
  spec:
    containers:
    - image: dangtong/goapp-v2 # ์ด๋ถ€๋ถ„์„ ๋ณ€๊ฒฝ ํ•ฉ๋‹๋‹ค.(๊ธฐ์กด : dangtong/goapp)
      imagePullPolicy: Always
      name: goapp-container
  

- Pod ์‚ญ์ œํ•˜๊ณ  ์ ์šฉ

  • Pod ์กฐํšŒ
  kubectl get pod
  

‘‘‘bash
kubectl delete pod goapp-rc-

  
```bash
kubectl get po -o wide
  

- Pod ์Šค์ผ€์ผ์•„์›ƒ

  kubectl scale rc goapp-rc --replicas=5
  
  kubectl get po 
  

- Replication Controller ์‚ญ์ œ

  • Pod ๋Š” ๊ทธ๋ž˜๋„ ๋‘๊ณ  Replication Controller ๋งŒ์‚ญ์ œ
  kubectl delete rc goapp-rc --cascade=orphan
  
  • ๋ชจ๋‘ ์‚ญ์ œ
  kubectl delete rc goapp-rc
  

6. Replica Set

    / [pdf]



- ReplicaSet ์ƒ์„ฑ

Selector ๋ฅผ ์ž‘์„ฑ ํ• ๋•Œ ForntEnd ์ด๊ณ  ์šด์˜๊ณ„ ์ด๋ฉด์„œ ์ค‘์š”๋„๊ฐ€ High ์ธ POD ์— ๋Œ€ํ•ด RS ๋ฅผ ์ƒ์„ฑ ํ•ฉ๋‹ˆ๋‹ค.

  apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: frontend
  labels:
    app: guestbook
    tier: frontend
spec:
  replicas: 3
  selector:
    matchLabels:
      tier: frontend
    matchExpressions:
      - {key: env, operator: In, values: [prod]}
      - {key: priority, operator: NotIn, values: [low]}
  template:
    metadata:
      labels:
        tier: frontend
        env: prod
        priority: high
    spec:
      containers:
      - name: nginx-frontend
        image: nginx:1.29
        ports:
        - containerPort: 80
  
  kubectl apply -f ./rs.yml
  

- RS ํ™•์ธ

  kubectl get po -o wide
  
  kubectl get rs -o wide
  
  kubectl get po --show-labels
  

- [์—ฐ์Šต๋ฌธ์ œ] 4-4. RC,RS ์ƒ์„ฑ ์‹ค์Šต

  1. Nginx:1.14.2 Pod 3๊ฐœ๋กœ ๊ตฌ์„ฑ๋œ Replication Controller๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”

  2. Replication Controller๋งŒ ์‚ญ์ œํ•˜์„ธ์š” (Pod๋Š” ์œ ์ง€)

  3. ๋‚จ๊ฒจ์ง„ Nginx Pod๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ReplicaSet์„ ์ž‘์„ฑํ•˜๋˜ replica 4๊ฐœ๋กœ ๊ตฌ์„ฑํ•˜์„ธ์š”

  4. Nginx Pod๋ฅผ 6๊ฐœ๋กœ Scale Out ํ•˜์„ธ์š”

  5. ์ „์ฒด ๊ณผ์ • ํ™•์ธ ๋ช…๋ น์–ด

7. DeamonSet

- DaemonSet ์ƒ์„ฑ

  apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: goapp-on-ssd
spec:
  selector:
    matchLabels:
      app: goapp-pod
  template:
    metadata:
      labels:
        app: goapp-pod
    spec:
      nodeSelector:
        disk: ssd
      containers:
      - name: goapp-container
        image: dangtong/goapp
  
  kubectl apply -f ./ds.yaml
  
  kubectl get po,ds
  

์กฐํšŒ ํ•˜๋ฉด Pod ๋„ ์กด์žฌํ•˜์ง€ ์•Š๊ณ  ๋ฐ๋ชฌ์…‹ ์ •๋ณด๋ฅผ ์กฐํšŒ ํ•ด๋„ ๋ชจ๋‘ 0 ์œผ๋กœ ๋‚˜์˜ต๋‹๋‹ค. ๋…ธ๋“œ์— disk=ssd ๋ผ๋ฒจ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ, ์กฐ๊ฑด์„ ๋งŒ์กฑ ์‹œํ‚ค๊ธฐ ์œ„ํ•ด Label ์„ ๋…ธ๋“œ์— ์ถ”๊ฐ€ ํ•ฉ๋‹ˆ๋‹ค.

- ๋…ธ๋“œ๋ผ๋ฒจ ์ถ”๊ฐ€

  • ํ˜„์žฌ ๋…ธ๋“œ ๋ชฉ๋ก ์กฐํšŒ
  kubectl get no 
  
  • ํŠน์ • ๋…ธ๋“œ์— Label ์ถ”๊ฐ€
  kubectl label node <node-name> disk=ssd
  
  kubectl get ds -o wide
  

8. Deployment

    / [pdf]



Deployment๋Š” Pod์™€ ReplicaSet์— ๋Œ€ํ•œ ์„ ์–ธ์  ์—…๋ฐ์ดํŠธ๋ฅผ ์ œ๊ณตํ•˜๋ฉฐ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ฐฐํฌ์™€ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

- ๊ธฐ๋ณธ Deployment ์ƒ์„ฑ

1. nginx Deployment ์ƒ์„ฑ

  apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.29
        ports:
        - containerPort: 80
  

2. Deployment ์ƒ์„ฑ ๋ฐ ํ™•์ธ

  kubectl apply -f nginx-deployment.yaml
kubectl get deployment
kubectl get pods -l app=nginx
  

- Deployment ์—…๋ฐ์ดํŠธ

1. Change Cause๋ฅผ ํฌํ•จํ•œ ์ด๋ฏธ์ง€ ์—…๋ฐ์ดํŠธ

  # kubectl set image ๋ช…๋ น์–ด ์‚ฌ์šฉ (change cause ํฌํ•จ)
kubectl set image deployment/nginx-deployment nginx=nginx:1.14.2 --record

# ๋˜๋Š” YAML ํŒŒ์ผ ์ˆ˜์ • ํ›„ ์ ์šฉ (change cause ํฌํ•จ)
kubectl apply -f nginx-deployment-v2.yaml --record
  

์ฐธ๊ณ : --record ํ”Œ๋ž˜๊ทธ๋Š” ์ตœ์‹  Kubernetes ๋ฒ„์ „์—์„œ deprecated๋˜์—ˆ์Šต๋‹ˆ๋‹ค. Change cause๋ฅผ ์ถ”์ ํ•˜๋ ค๋ฉด kubectl annotate๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”:

  # Annotate๋ฅผ ์‚ฌ์šฉํ•œ change cause ์„ค์ • (๊ถŒ์žฅ ๋ฐฉ๋ฒ•)
kubectl annotate deployment/nginx-deployment kubernetes.io/change-cause="Update to nginx 1.30 for performance improvements"
  

2. ์—…๋ฐ์ดํŠธ ๊ณผ์ • ํ™•์ธ

  # ์—…๋ฐ์ดํŠธ ์ƒํƒœ ํ™•์ธ
kubectl rollout status deployment/nginx-deployment

# ์—…๋ฐ์ดํŠธ ์ด๋ ฅ ํ™•์ธ (change cause ํฌํ•จ)
kubectl rollout history deployment/nginx-deployment

# ์ƒ์„ธ ์ด๋ ฅ ํ™•์ธ
kubectl rollout history deployment/nginx-deployment --revision=2

# ์ƒ์„ธ ์ •๋ณด ํ™•์ธ
kubectl describe deployment nginx-deployment
  

3. Change Cause ํ™•์ธ ์˜ˆ์ œ

  # ์ด๋ ฅ ํ™•์ธ (change cause ํ‘œ์‹œ)
kubectl rollout history deployment/nginx-deployment

# ์ถœ๋ ฅ ์˜ˆ์‹œ:
# REVISION  CHANGE-CAUSE
# 1         kubectl apply --filename=nginx-deployment.yaml --record=true
# 2         kubectl set image deployment/nginx-deployment nginx=nginx:1.30 --record=true
# 3         kubectl set image deployment/nginx-deployment nginx=nginx:1.31 --record=true
  

- Deployment ๋กค๋ฐฑ

1. ์ด์ „ ๋ฒ„์ „์œผ๋กœ ๋กค๋ฐฑ

  # ์ด์ „ ๋ฒ„์ „์œผ๋กœ ๋กค๋ฐฑ
kubectl rollout undo deployment/nginx-deployment

# ํŠน์ • ๋ฒ„์ „์œผ๋กœ ๋กค๋ฐฑ
kubectl rollout undo deployment/nginx-deployment --to-revision=2
  

2. ๋กค๋ฐฑ ํ™•์ธ

  # ๋กค๋ฐฑ ์ƒํƒœ ํ™•์ธ
kubectl rollout status deployment/nginx-deployment

# ๋กค๋ฐฑ ์ด๋ ฅ ํ™•์ธ
kubectl rollout history deployment/nginx-deployment
  

- Deployment ์Šค์ผ€์ผ๋ง

1. Replica ์ˆ˜ ๋ณ€๊ฒฝ

  # ์Šค์ผ€์ผ ์•„์›ƒ
kubectl scale deployment nginx-deployment --replicas=5

# ์Šค์ผ€์ผ ์ธ
kubectl scale deployment nginx-deployment --replicas=2
  

2. ์Šค์ผ€์ผ๋ง ํ™•์ธ

  kubectl get deployment nginx-deployment
kubectl get pods -l app=nginx
  

- Deployment ์ „๋žต

1. Rolling Update (๊ธฐ๋ณธ)

  • Deployment ์ƒ์„ฑ
  apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.29
        ports:
        - containerPort: 80
  
  • ์ด๋ฏธ์ง€ ์—…๋ฐ์ดํŠธ
  kubectl set image deployment/nginx-deployment nginx=nginx:1.14.2 --record
  
  • ๋กค๋ง ์—…๋ฐ์ดํŠธ ์ƒํƒœ ํ™•์ธ
  kubectl rollout status deployment/nginx-deployment
  
  kubectl get po -w
  
  kubectl get po
  

2. Recreate ์ „๋žต

  apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment-recreate
spec:
  replicas: 3
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.29
        ports:
        - containerPort: 80
  

- [์—ฐ์Šต๋ฌธ์ œ] 4-5. Deployment ์‹ค์Šต

1. ๊ธฐ๋ณธ Deployment ์ƒ์„ฑ

์•„๋ž˜ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” Deployment๋ฅผ ์ƒ์„ฑํ•˜์„ธ์š”:

  • Deployment ์ด๋ฆ„: httpd-deployment
  • ์ด๋ฏธ์ง€: httpd:2.4
  • Replica: 3๊ฐœ
  • ํฌํŠธ: 80

2. Deployment ์—…๋ฐ์ดํŠธ (Change Cause ํฌํ•จ)

์ƒ์„ฑ๋œ Deployment์˜ ์ด๋ฏธ์ง€๋ฅผ httpd:latest๋กœ ์—…๋ฐ์ดํŠธํ•˜๊ณ  change cause๋ฅผ ๊ธฐ๋กํ•˜์„ธ์š”.

3. Deployment ์Šค์ผ€์ผ๋ง

Deployment๋ฅผ 5๊ฐœ replica๋กœ ์Šค์ผ€์ผ ์•„์›ƒํ•˜์„ธ์š”.

4. Deployment ๋กค๋ฐฑ (Change Cause ํ™•์ธ)

  • rollout ํžˆ์Šคํ† ๋ฆฌ๋ฅผ ํ™•์•ˆํ•˜์„ธ์š”
  • version 2 ์˜ ์ƒ์„ธ ์ƒํƒœ๋ฅผ ํ™•์ธํ•˜์„ธ์š”
  • ์ด์ „ ๋ฒ„์ „์œผ๋กœ ๋กค๋ฐฑํ•˜๊ณ  change cause๋ฅผ ํ™•์ธํ•˜์„ธ์š”.

5. Deployment ๊ด€๋ฆฌ ๋ช…๋ น์–ด (Change Cause ํฌํ•จ)

- Deployment ์‚ฌ์šฉ ์‚ฌ๋ก€

  1. ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜: nginx, Apache ๋“ฑ
  2. API ์„œ๋ฒ„: REST API, GraphQL ๋“ฑ
  3. ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค: ๊ฐ ์„œ๋น„์Šค๋ณ„ ๋…๋ฆฝ์  ๋ฐฐํฌ
  4. ๋ฐฐ์น˜ ์ž‘์—…: ์ฃผ๊ธฐ์  ์‹คํ–‰๋˜๋Š” ์ž‘์—…

- ์ •๋ฆฌ

  # ๋ฆฌ์†Œ์Šค ์‚ญ์ œ
kubectl delete deployment nginx-deployment
kubectl delete deployment nginx-deployment-recreate
kubectl delete deployment httpd-deployment
  

9. StatefulSet

    / [pdf]




StatefulSet ์€ ๋””์Šคํฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์Šคํ† ๋ฆฌ์ง€๋ฅผ ํ•™์Šตํ•œ ํ›„์— ๋ฐฐ์šฐ๋„๋ก ํ• ๊ป˜์š”!

- ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ด๋ฏธ์ง€ ์ž‘์„ฑ

  // docker/app.js
const http = require('http');
const os = require('os');
const fs = require('fs');

const dataFile = "/var/data/kubia.txt";
const port  = 8080;

// ํŒŒ์ผ ์กด์žฌ  ์œ /๋ฌด ๊ฒ€์‚ฌ
function fileExists(file) {
  try {
    fs.statSync(file);
    return true;
  } catch (e) {
    return false;
  }
}

var handler = function(request, response) {
//  POST ์š”์ฒญ์ผ ๊ฒฝ์šฐ BODY์— ์žˆ๋Š” ๋‚ด์šฉ์„ ํŒŒ์ผ์— ๊ธฐ๋ก ํ•จ
  if (request.method == 'POST') {
    var file = fs.createWriteStream(dataFile);
    file.on('open', function (fd) {
      request.pipe(file);
      console.log("New data has been received and stored.");
      response.writeHead(200);
      response.end("Data stored on pod " + os.hostname() + "\n");
    });
// GET ์š”์ฒญ์ผ ๊ฒฝ์šฐ ํ˜ธ์ŠคํŠธ๋ช…๊ณผ ํŒŒ์ผ์— ๊ธฐ๋ก๋œ ๋‚ด์šฉ์„ ๋ฐ˜ํ™˜ ํ•จ
  } else {
    var data = fileExists(dataFile) ? fs.readFileSync(dataFile, 'utf8') : "No data posted yet";
    response.writeHead(200);
    response.write("You've hit " + os.hostname() + "\n");
    response.end("Data stored on this pod: " + data + "\n");
  }
};

var www = http.createServer(handler);
www.listen(port);
  

- ๋„์ปค ์ด๋ฏธ์ง€ ๋งŒ๋“ค๊ธฐ

  # docker/Dockerfile
FROM node:7
ADD app.js /app.js
ENTRYPOINT ["node", "app.js"]
  
  
docker build <Docker-ID>/nodejs:sfs . --push
docker buildx build  --platform linux/amd64,linux/arm64  -t <Docker-ID>/nodejs:sfs . --push
docker login -u <Docker-ID>
docker push <Docker-ID>/nodejs:sfs
  

- StatefulSet ์ƒ์„ฑ

  # kubetemp/sts.yml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: nodejs-sfs
spec:
  selector:
    matchLabels:
      app: nodejs-sfs
  serviceName: nodejs-sfs
  replicas: 2
  template:
    metadata:
      labels:
        app: nodejs-sfs
    spec:
      containers:
      - name: nodejs-sfs
        image: <Your-Docker-ID>/nodejs:sfs
        ports:
        - name: http
          containerPort: 8080
        volumeMounts:
        - name: data
          mountPath: /var/data
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      resources:
        requests:
          storage: 1Mi
      accessModes:
      - ReadWriteOnce
      storageClassName: gp2
  
  kubectl apply -f ./sts.yml
  
  kubectl get po -w
  

- LoadBalancer ์ƒ์„ฑ

  # kubetemp/lb.yml
apiVersion: v1
kind: Service
metadata:
    name: nodesjs-sfs-lb
    annotations:
      service.beta.kubernetes.io/aws-load-balancer-type: external
      service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
      service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
spec:
    type: LoadBalancer
    sessionAffinity: None
    ports:
    - port: 80
      targetPort: 8080
    selector:
        app: nodejs-sfs
  
  kubectl apply -f ./lb.yml
  
  • ์„œ๋น„์Šค ํ™•์ธ
  kubectl get svc
  
  • ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ ํ™œ์„ฑ ์ƒํƒœ ํ™•์ธ (State ํ•ญ๋ชฉ ํ™•์ธ)
  aws elbv2 describe-load-balancers
  
  • ๋ฐ์ดํƒ€ ์กฐํšŒ
  curl http://<public-domain>
  
  • ๋ฐ์ดํ„ฐ ์ž…๋ ฅ
  curl -X POST -d "hi, my name is dangtong-1" <public-domain>
curl -X POST -d "hi, my name is dangtong-2" <public-domain>
curl -X POST -d "hi, my name is dangtong-3" <public-domain>
curl -X POST -d "hi, my name is dangtong-4" <public-domain>
curl -X POST -d "hi, my name is dangtong-5" <public-domain>
  

๋ฐ์ดํ„ฐ ์ž…๋ ฅ์„ ๋ฐ˜๋ณตํ•˜์— ๋‘๊ฐœ ๋…ธ๋“œ ๋ชจ๋“œ์— ๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ๋‘ ์ €์žฅ ํ•ฉ๋‹ˆ๋‹ค. ์–‘์ชฝ ๋…ธ๋“œ์— ์–ด๋–ค ๋ฐ์ดํ„ฐ๊ฐ€ ์ž…๋ ฅ ๋˜์—ˆ๋Š”์ง€ ๊ธฐ์–ต ํ•˜๊ณ  ๋‹ค์Œ ๋‹จ๊ณ„๋กœ ๋„˜์–ด ๊ฐ‘๋‹ˆ๋‹ค.


10. StatefulSet ์—ฐ์Šต๋ฌธ์ œ

์—ฐ์Šต๋ฌธ์ œ์šฉ ๋„ค์ž„์ŠคํŽ˜์ด์Šค ์ƒ์„ฑ

  kubectl create namespace statefulset-lab
kubectl config set-context --current --namespace=statefulset-lab
  

์—ฐ์Šต๋ฌธ์ œ 1: ๊ธฐ๋ณธ StatefulSet ์ƒ์„ฑ

๋ฌธ์ œ

์•„๋ž˜ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” StatefulSet์„ ์ƒ์„ฑํ•˜์„ธ์š”:

ํ™•์ธ ๋ช…๋ น์–ด

  # StatefulSet ์ƒํƒœ ํ™•์ธ
kubectl get statefulset

# Pod ์ƒํƒœ ํ™•์ธ
kubectl get pods

# PVC ํ™•์ธ (AWS EBS ๋ณผ๋ฅจ ํ™•์ธ)
kubectl get pvc
kubectl describe pvc www-web-0

# EBS ๋ณผ๋ฅจ ํ™•์ธ (AWS CLI)
aws ec2 describe-volumes --filters "Name=tag:kubernetes.io/cluster/*,Values=owned" --query 'Volumes[*].[VolumeId,Size,State]' --output table

# Pod ์ด๋ฆ„ ํŒจํ„ด ๊ด€์ฐฐ
kubectl get pods -l app=nginx

# StorageClass ํ™•์ธ
kubectl get storageclass
kubectl describe storageclass gp2

# ๋ฌธ์ œ ํ•ด๊ฒฐ: PVC ๋ฐ”์ธ๋”ฉ ์ƒํƒœ ํ™•์ธ
kubectl get pvc -o wide
kubectl describe pvc www-web-0

# EBS CSI Driver ์ƒํƒœ ํ™•์ธ
kubectl get pods -n kube-system | grep ebs-csi
kubectl logs -n kube-system deployment/ebs-csi-controller

# ๋…ธ๋“œ์— EBS CSI Driver ์„ค์น˜ ํ™•์ธ
kubectl get pods -n kube-system | grep ebs-csi-node
  

ํ™•์ธ ์‚ฌํ•ญ

  • StatefulSet์ด ์ •์ƒ์ ์œผ๋กœ ์ƒ์„ฑ๋จ
  • Pod ์ด๋ฆ„์ด web-0, web-1, web-2 ํŒจํ„ด์œผ๋กœ ์ƒ์„ฑ๋จ
  • ๊ฐ Pod๋งˆ๋‹ค ๊ณ ์œ ํ•œ PVC๊ฐ€ ์ƒ์„ฑ๋จ
  • Pod๊ฐ€ ์ˆœ์„œ๋Œ€๋กœ ์ƒ์„ฑ๋จ (0๋ฒˆ๋ถ€ํ„ฐ ์‹œ์ž‘)

์—ฐ์Šต๋ฌธ์ œ 2: StatefulSet๊ณผ Headless Service ์—ฐ๋™

๋ฌธ์ œ

๊ธฐ์กด StatefulSet๊ณผ ์—ฐ๋™๋˜๋Š” Headless Service๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ๊ฐœ๋ณ„ Pod์— ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ํ™•์ธํ•˜์„ธ์š”.

์š”๊ตฌ์‚ฌํ•ญ:

  • Service ์ด๋ฆ„: nginx
  • ํฌํŠธ: 80
  • Headless Service (clusterIP: None)
  • Selector: app=nginx

DNS ํ…Œ์ŠคํŠธ ๋ช…๋ น์–ด

  # Service ๋ฐฐํฌ
kubectl apply -f nginx-headless-service.yaml

# DNS ์กฐํšŒ ํ…Œ์ŠคํŠธ
kubectl run test-dns --image=busybox --rm -it --restart=Never -- nslookup nginx

# ๊ฐœ๋ณ„ Pod DNS ์กฐํšŒ
kubectl run test-pod-dns --image=busybox --rm -it --restart=Never -- nslookup web-0.nginx.statefulset-lab.svc.cluster.local
kubectl run test-pod-dns --image=busybox --rm -it --restart=Never -- nslookup web-1.nginx.statefulset-lab.svc.cluster.local
kubectl run test-pod-dns --image=busybox --rm -it --restart=Never -- nslookup web-2.nginx.statefulset-lab.svc.cluster.local
  

์—ฐ์Šต๋ฌธ์ œ 3: ์˜๊ตฌ ์Šคํ† ๋ฆฌ์ง€์™€ ๋ฐ์ดํ„ฐ ์ง€์†์„ฑ

๋ฌธ์ œ

StatefulSet์˜ ์˜๊ตฌ ์Šคํ† ๋ฆฌ์ง€ ํŠน์„ฑ์„ ํ™•์ธํ•˜๊ณ  ๋ฐ์ดํ„ฐ ์ง€์†์„ฑ์„ ํ…Œ์ŠคํŠธํ•˜์„ธ์š”.

3-1. ๋ฐ์ดํ„ฐ ์“ฐ๊ธฐ ๋ฐ ํ™•์ธ

  # ๊ฐ Pod์— ๊ณ ์œ ํ•œ ๋ฐ์ดํ„ฐ ์“ฐ๊ธฐ
kubectl exec web-0 -- sh -c "echo 'Data from web-0 at $(date)' > /usr/share/nginx/html/index.html"
kubectl exec web-1 -- sh -c "echo 'Data from web-1 at $(date)' > /usr/share/nginx/html/index.html"
kubectl exec web-2 -- sh -c "echo 'Data from web-2 at $(date)' > /usr/share/nginx/html/index.html"

# ๊ฐ Pod์˜ ๋ฐ์ดํ„ฐ ํ™•์ธ
kubectl exec web-0 -- cat /usr/share/nginx/html/index.html
kubectl exec web-1 -- cat /usr/share/nginx/html/index.html
kubectl exec web-2 -- cat /usr/share/nginx/html/index.html
  

3-2. Pod ์žฌ์‹œ์ž‘ ํ›„ ๋ฐ์ดํ„ฐ ์ง€์†์„ฑ ํ™•์ธ

  # web-0 Pod ์‚ญ์ œ (์žฌ์‹œ์ž‘ ์‹œ๋ฎฌ๋ ˆ์ด์…˜)
kubectl delete pod web-0

# Pod ์žฌ์ƒ์„ฑ ๋Œ€๊ธฐ
kubectl wait --for=condition=ready pod web-0

# ๋ฐ์ดํ„ฐ ์ง€์†์„ฑ ํ™•์ธ
kubectl exec web-0 -- cat /usr/share/nginx/html/index.html
  

3-3. StatefulSet ์Šค์ผ€์ผ๋ง ํ…Œ์ŠคํŠธ

  # StatefulSet์„ 5๊ฐœ๋กœ ํ™•์žฅ
kubectl scale statefulset web --replicas=5

# ์ƒˆ๋กœ์šด Pod๋“ค์˜ ๋ฐ์ดํ„ฐ ํ™•์ธ
kubectl exec web-3 -- cat /usr/share/nginx/html/index.html
kubectl exec web-4 -- cat /usr/share/nginx/html/index.html

# ๋‹ค์‹œ 3๊ฐœ๋กœ ์ถ•์†Œ
kubectl scale statefulset web --replicas=3
  

์—ฐ์Šต๋ฌธ์ œ 4: ๊ณ ๊ธ‰ StatefulSet ๊ตฌ์„ฑ

๋ฌธ์ œ

ํ™˜๊ฒฝ๋ณ€์ˆ˜, ๋ฆฌ์†Œ์Šค ์ œํ•œ, ํ—ฌ์Šค์ฒดํฌ๋ฅผ ํฌํ•จํ•œ ๊ณ ๊ธ‰ StatefulSet์„ ๊ตฌ์„ฑํ•˜์„ธ์š”.

์š”๊ตฌ์‚ฌํ•ญ:

  • StatefulSet ์ด๋ฆ„: web-advanced
  • Service ์ด๋ฆ„: nginx-advanced
  • ํ™˜๊ฒฝ๋ณ€์ˆ˜: NGINX_HOST, NGINX_PORT
  • ๋ฆฌ์†Œ์Šค ์ œํ•œ: CPU 500m, Memory 128Mi
  • Liveness Probe: HTTP GET /, 30์ดˆ ์ดˆ๊ธฐ์ง€์—ฐ, 10์ดˆ ์ฃผ๊ธฐ
  • Readiness Probe: HTTP GET /, 5์ดˆ ์ดˆ๊ธฐ์ง€์—ฐ, 5์ดˆ ์ฃผ๊ธฐ
  • PVC: www (1Gi), config (100Mi) - StorageClass: gp2

๋ฐฐํฌ ๋ฐ ํ…Œ์ŠคํŠธ

  # ๊ธฐ์กด StatefulSet ์‚ญ์ œ
kubectl delete statefulset web
kubectl delete service nginx

# ์ƒˆ๋กœ์šด StatefulSet ๋ฐฐํฌ
kubectl apply -f advanced-statefulset.yaml
kubectl apply -f nginx-advanced-service.yaml

# ์ƒํƒœ ํ™•์ธ
kubectl get statefulset
kubectl get pods
kubectl get pvc

# EBS ๋ณผ๋ฅจ ํ™•์ธ
kubectl describe pvc www-web-advanced-0
kubectl describe pvc config-web-advanced-0

# AWS EBS ๋ณผ๋ฅจ ์ƒํƒœ ํ™•์ธ
aws ec2 describe-volumes --filters "Name=tag:kubernetes.io/cluster/*,Values=owned" --query 'Volumes[*].[VolumeId,Size,State,VolumeType]' --output table

# ํ—ฌ์Šค์ฒดํฌ ํ…Œ์ŠคํŠธ
kubectl logs web-advanced-0
kubectl describe pod web-advanced-0
kubectl exec web-advanced-0 -- env | grep NGINX

# ๋ฆฌ์†Œ์Šค ์‚ฌ์šฉ๋Ÿ‰ ํ™•์ธ
kubectl top pods -l app=nginx-advanced
  

ํ™•์ธ ์‚ฌํ•ญ

  • ๊ณ ๊ธ‰ StatefulSet์ด ์ •์ƒ ๋ฐฐํฌ๋จ
  • ํ™˜๊ฒฝ๋ณ€์ˆ˜๊ฐ€ ์ •์ƒ ์„ค์ •๋จ
  • ๋ฆฌ์†Œ์Šค ์ œํ•œ์ด ์ ์šฉ๋จ
  • ํ—ฌ์Šค์ฒดํฌ๊ฐ€ ์ •์ƒ ์ž‘๋™ํ•จ
  • ์—ฌ๋Ÿฌ PVC๊ฐ€ ์ƒ์„ฑ๋จ

์—ฐ์Šต๋ฌธ์ œ 5: StatefulSet ์—…๋ฐ์ดํŠธ ์ „๋žต

๋ฌธ์ œ

StatefulSet์˜ ๋กค๋ง ์—…๋ฐ์ดํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ณ  ๋ถ€๋ถ„ ์—…๋ฐ์ดํŠธ๋ฅผ ํ…Œ์ŠคํŠธํ•˜์„ธ์š”.

5-1. ๋กค๋ง ์—…๋ฐ์ดํŠธ ์ˆ˜ํ–‰

  # ์ด๋ฏธ์ง€๋ฅผ nginx:1.22๋กœ ์—…๋ฐ์ดํŠธ
kubectl set image statefulset/web-advanced nginx=nginx:1.22

# ์—…๋ฐ์ดํŠธ ์ง„ํ–‰ ์ƒํ™ฉ ํ™•์ธ
kubectl rollout status statefulset/web-advanced

# Pod ์ƒํƒœ ํ™•์ธ
kubectl get pods -l app=nginx-advanced
  

5-2. ๋ถ€๋ถ„ ์—…๋ฐ์ดํŠธ ํ…Œ์ŠคํŠธ

  # partition์„ 1๋กœ ์„ค์ •ํ•˜์—ฌ web-0๋งŒ ์—…๋ฐ์ดํŠธ
kubectl patch statefulset web-advanced -p '{"spec":{"updateStrategy":{"rollingUpdate":{"partition":1}}}}'

# ์ด๋ฏธ์ง€๋ฅผ nginx:1.23์œผ๋กœ ์—…๋ฐ์ดํŠธ
kubectl set image statefulset/web-advanced nginx=nginx:1.23

# ์—…๋ฐ์ดํŠธ๋œ Pod ํ™•์ธ
kubectl get pods -l app=nginx-advanced
  

5-3. ๋กค๋ฐฑ ํ…Œ์ŠคํŠธ

  # ์ด์ „ ๋ฒ„์ „์œผ๋กœ ๋กค๋ฐฑ
kubectl rollout undo statefulset/web-advanced

# ๋กค๋ฐฑ ์ƒํƒœ ํ™•์ธ
kubectl rollout status statefulset/web-advanced
  

ํ™•์ธ ์‚ฌํ•ญ

  • ๋กค๋ง ์—…๋ฐ์ดํŠธ๊ฐ€ ์ˆœ์„œ๋Œ€๋กœ ์ง„ํ–‰๋จ
  • ๋ถ€๋ถ„ ์—…๋ฐ์ดํŠธ๊ฐ€ ์ •์ƒ ์ž‘๋™ํ•จ
  • ๋กค๋ฐฑ์ด ์ •์ƒ์ ์œผ๋กœ ์ˆ˜ํ–‰๋จ
  • ์—…๋ฐ์ดํŠธ ์ค‘์—๋„ ์„œ๋น„์Šค๊ฐ€ ์ค‘๋‹จ๋˜์ง€ ์•Š์Œ

์—ฐ์Šต๋ฌธ์ œ ์ •๋ฆฌ

์ตœ์ข… ํ™•์ธ ์‚ฌํ•ญ

  • StatefulSet์˜ ๊ธฐ๋ณธ ๊ฐœ๋… ์ดํ•ด
  • Headless Service์™€์˜ ์—ฐ๋™
  • ์˜๊ตฌ ์Šคํ† ๋ฆฌ์ง€์˜ ๋™์ž‘ ๋ฐฉ์‹
  • ๊ณ ๊ธ‰ ๊ตฌ์„ฑ ์š”์†Œ ์ ์šฉ
  • ์—…๋ฐ์ดํŠธ ์ „๋žต ์ดํ•ด

์ •๋ฆฌ ๋ช…๋ น์–ด

  # ๋ชจ๋“  ๋ฆฌ์†Œ์Šค ์‚ญ์ œ
kubectl delete statefulset --all
kubectl delete service --all
kubectl delete pvc --all

# EBS ๋ณผ๋ฅจ ์ •๋ฆฌ ํ™•์ธ (์‚ญ์ œ๋˜์ง€ ์•Š์€ ๋ณผ๋ฅจ์ด ์žˆ์„ ์ˆ˜ ์žˆ์Œ)
aws ec2 describe-volumes --filters "Name=tag:kubernetes.io/cluster/*,Values=owned" --query 'Volumes[*].[VolumeId,Size,State]' --output table

# ๋„ค์ž„์ŠคํŽ˜์ด์Šค ์‚ญ์ œ
kubectl delete namespace statefulset-lab

# AWS EBS ๋ณผ๋ฅจ ์ˆ˜๋™ ์‚ญ์ œ (ํ•„์š”์‹œ)
# aws ec2 delete-volume --volume-id vol-xxxxxxxxx
  

ํ˜น์‹œ๋‚˜ ์‹œ๊ฐ„ ๋‚จ์œผ๋ฉด ์ถ”๊ฐ€ ๋„์ „!!!

๋„์ „ 1: MySQL StatefulSet ๊ตฌ์„ฑ

MySQL StatefulSet์„ ๊ตฌ์„ฑํ•˜๊ณ  ๋ฐ์ดํ„ฐ ์ง€์†์„ฑ์„ ํ™•์ธํ•ด๋ณด์„ธ์š”.

๋„์ „ 2: Redis Cluster ๊ตฌ์„ฑ

Redis Cluster๋ฅผ StatefulSet์œผ๋กœ ๊ตฌ์„ฑํ•ด๋ณด์„ธ์š”.

๋„์ „ 3: ๋ชจ๋‹ˆํ„ฐ๋ง ์ถ”๊ฐ€

Prometheus์™€ Grafana๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ StatefulSet ๋ชจ๋‹ˆํ„ฐ๋ง์„ ๊ตฌ์„ฑํ•ด๋ณด์„ธ์š”.


๐Ÿ”— ์ฐธ๊ณ  ์ž๋ฃŒ