๋กœ์ผ“๐Ÿพ
article thumbnail

 

 

ํ‹€๋ฆฐ ๋ถ€๋ถ„์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์žˆ๋‹ค๋ฉด ์ง€์ ํ•ด์ฃผ์„ธ์š” :)

 

 

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์—์„œ ReplicaSet ์„ ํ†ตํ•ด 3๊ฐœ์˜ ํŒŒ๋“œ๋ฅผ ๋ฐฐํฌํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ด๋ด…์‹œ๋‹ค. ์ด๋•Œ ํ•˜๋‚˜์˜ ํŒŒ๋“œ๋ฅผ ์‚ญ์ œํ•˜๊ฒŒ ๋˜๋ฉด ๊ณง ๋‹ค์‹œ ํŒŒ๋“œ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ์ฆ‰, ํŒŒ๋“œ๊ฐ€ ์ตœ์†Œ 3๊ฐœ ์ด์ƒ์ด ์‹คํ–‰๋˜๋„๋ก ReplicaSet ๋ฅผ ๋ฐฐํฌํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ฃฝ์—ˆ๋˜ ํŒŒ๋“œ๋ฅผ ์ƒˆ๋กญ๊ฒŒ ์†Œ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค. ์ด๋Š” ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์˜ ํŠน์ง• ์ค‘ ํ•˜๋‚˜์ธ Self Healing ์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

ReplicaSet, Deployment ๋“ฑ์—์„œ ๋ช…์‹œํ•˜๋Š” Replica ์˜ ๊ฐฏ์ˆ˜๋Š” ๊ณ ์ •/์ตœ๋Œ€๊ฐ€ ์•„๋‹Œ ์ตœ์†Œ๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
3๊ฐœ๋ผ๊ณ  ๊ฐ€์ •ํ–ˆ์„ ๋•Œ, ๋กค๋ง์—…๋ฐ์ดํŠธ๋‚˜ ๋น„์ž๋ฐœ์ ์ธ ์ข…๋ฃŒ์— ์˜ํ•ด 3๊ฐœ ์ด์ƒ์˜ ํŒŒ๋“œ๊ฐ€ ์กด์žฌํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด์ฃ .

 

๊ทธ๋Ÿผ ์ด๊ฑธ ์ข€ ๋” ์ „๋ฌธ์ ?์œผ๋กœ ์ ‘๊ทผํ•ด๋ด…์‹œ๋‹ค.

 

์šฐ๋ฆฌ๊ฐ€ ์›ํ–ˆ๋˜(Desired) ReplicaSet ์˜ ๊ฐฏ์ˆ˜๋Š” 3๊ฐœ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ํ•˜๋‚˜๊ฐ€ ์ฃฝ์–ด 2๊ฐœ๊ฐ€ ๋˜์—ˆ๋‹ค(Lived)๋Š” ๊ฒƒ์€ ์ด๋ฅผ ์œ„๋ฐ˜ํ•˜๋Š” ํ–‰์œ„์ž…๋‹ˆ๋‹ค. ๋‹ค์‹œ ๋งํ•ด Desired State ์™€ Lived State ๊ฐ€ ๋‹ค๋ฅด๋‹ค๋Š” ๊ฒƒ์ด์ฃ .

 

๊ทธ๋ฆฌ๊ณ  ์ด๋Ÿฌํ•œ ์œ„๋ฐ˜ ์‚ฌํ•ญ์ด ์žˆ๋Š”์ง€ ๋Š˜ ์ฃผ์‹œ(Watch) ํ•˜๊ณ  ์žˆ๋Š” ๋…€์„์ด ์žˆ๋Š”๋ฐ, ๋ฐ”๋กœ ์ปจํŠธ๋กค ํ”Œ๋ ˆ์ธ์˜ ์ปดํฌ๋„ŒํŠธ ์ค‘ ํ•˜๋‚˜์ธ Controller Manager ์ž…๋‹ˆ๋‹ค.

 

Controller Manager ์€ Control Loop ์ด๋ผ๋Š” ํ–‰์œ„๋ฅผ ํ†ตํ•ด ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š”(Desired) ์ƒํƒœ์™€ ํ˜„์žฌ(Lived) ์ƒํƒœ๋ฅผ ๋งž์ณ์ค๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ด๋ ‡๊ฒŒ ์ƒํƒœ๋ฅผ ๋งž์ถฐ์ฃผ๋Š” ํ–‰์œ„๋ฅผ Reconciliation(๋ฆฌ์ปจ์‹ค๋ฆฌ์—์ด์…˜) ์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

 

๋„์‹ํ™”ํ•ด๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ฃ .

https://developers.redhat.com/articles/2021/06/22/kubernetes-operators-101-part-2-how-operators-work

 

Controller Manager ์•ˆ์—์„  Control Loop ์„ ํ†ตํ•ด ๋ฌดํ•œํžˆ ๊ด€๋ จํ•œ ๋ฆฌ์†Œ์Šค๋ฅผ ์ฃผ์‹œ(Watch) ํ•˜๊ณ  ์žˆ๊ณ , ๋งŒ์•ฝ ์ฐจ์ด๋ฅผ ๋ณด์ด๋Š” ๋ฆฌ์†Œ์Šค๊ฐ€ ์žˆ๋‹ค๋ฉด Reconcile(๋ฆฌ์ปจ์‚ฌ์ผ) ์„ ํ†ตํ•ด์„œ ์„œ๋กœ์˜ ์ƒํƒœ๋ฅผ ๋งž์ณ์ค๋‹ˆ๋‹ค.

 

ReplicaSet ์˜ ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋ฅผ ํ•ญ์ƒ ์ฃผ์‹œํ•˜๊ณ  ์žˆ๋‹ค๊ฐ€, ํŒŒ๋“œ๊ฐ€ ํ•˜๋‚˜ ์ฃฝ๋Š”๋‹ค ๋“ฑ์˜ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์›ํ•˜๋Š”(Desired) ์ƒํƒœ๋กœ ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋ฅผ ๋งž์ณ์ฃผ๋Š” ๊ฒƒ์ด์ง€์š”.

ReplicaSet ์™ธ์—๋„ Deployment, DaemonSet, StatefulSet, CronJob, SeviceAccount ๊ฐ€ Controller Manager ์— ์˜ํ•ด ์ฃผ์‹œ(Watch) ๋ฅผ ๋‹นํ•ฉ๋‹ˆ๋‹ค.

 

ํ•œํŽธ, Reconciliation ๋Š” 3๋‹จ๊ณ„๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. Observe (๊ด€์ฐฐ)
  2. Analyze (๋ถ„์„)
  3. Act (์‹คํ–‰)

๊ด€์ฐฐ(Observe) ํ•˜๊ณ  ์žˆ๋Š” ๋ฆฌ์†Œ์Šค์˜ ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ Controller Manager ๋Š” ๊ด€๋ จํ•œ ์ด๋ฒคํŠธ๋ฅผ ์ฃผ์‹œ(Watch) ํ•˜์—ฌ ์‹ค์ œ ์ƒํƒœ(Lived State) ๋ฅผ ์ฐพ์•„, ์›ํ•˜๋Š” ์ƒํƒœ(Desired State) ์˜ ์ฐจ์ด๋ฅผ ๋ถ„์„(Analyze) ํ•˜๊ณ , ์›ํ•˜๋Š” ์ƒํƒœ๋กœ ๊ตฌ๋™๋˜๋„๋ก ์ž‘์—…์„ ์ˆ˜ํ–‰(Act) ํ•ฉ๋‹ˆ๋‹ค.

๊ด€์ธก -> ๋ถ„์„ -> ์‹คํ–‰

"๋‚ด๊ฐ€ ๋Œ์•„์™”๋‹ค!" ๋ผ๊ณ  ํ‘œํ˜„ํ•˜๊ธด ํ–ˆ๋Š”๋ฐ, ์ •ํ™•ํžˆ๋Š” ์ฃฝ์—ˆ๋˜ ์• ๊ฐ€ ์‚ด์•„๋‚˜๋Š”๊ฑด ์•„๋‹ˆ๊ณ  ์ƒˆ๋กญ๊ฒŒ ํŒŒ๋“œ๋ฅผ ๋งŒ๋“  ํ›„์— Deployment ์— ๋งตํ•‘ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค!

 

์ด๋Ÿฐ ํ–‰์œ„๋ฅผ ํ•ด์ฃผ๋Š” ๋…€์„์„ Controller ๋ผ๊ณ  ์ง€์นญํ•˜๋Š”๋ฐ, ์ด์™€ ๋น„์Šทํ•œ ํ–‰์œ„๋ฅผ ํ•˜๋Š” ๋…€์„์ด ํ•˜๋‚˜ ๋” ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

๋ฐ”๋กœ ์˜คํผ๋ ˆ์ดํ„ฐ(Operator) ์ž…๋‹ˆ๋‹ค.

 

๋Œ€ํ‘œ์ ์œผ๋กœ ํ”„๋กœ๋ฉ”ํ…Œ์šฐ์Šค ์˜คํผ๋ ˆ์ดํ„ฐ๊ฐ€ ์กด์žฌํ•˜์ฃ !

 

์‚ฌ์‹ค ์ด ๋‘ ๋…€์„์˜ ํ–‰์œ„๊ฐ€ ๊ต‰์žฅํžˆ ๋น„์Šทํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ช…ํ™•ํ•˜๊ฒŒ ๋‘˜์˜ ์ฐจ์ด๋ฅผ ์„ค๋ช…ํ•˜๊ธด ํž˜๋“ค์ง€๋งŒ, ๋ณดํ†ต CRD(CustomResourceDefinition) ๋ฅผ ํ†ตํ•ด Reconciliation ๋ฅผ ์ˆ˜ํ–‰ํ•œ๋‹ค๋ฉด Operator, CRD ์—†์ด ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ๋ฆฌ์†Œ์Šค๋กœ๋งŒ ์ง„ํ–‰๋˜๋Š” Reconciliation ๋ผ๋ฉด Controller ๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค.

 

https://youtu.be/abHOcr-HTI4?si=af9bjsnO2xc5aBNg

 

๊ทธ๋Ÿฐ๋ฐ ์ด๊ฒƒ๋„ ์• ๋งคํ•œ ๊ฒƒ์ด ArgoCD ๋ฅผ ๋น—๋Œ€์–ด ๋ณด๋ฉด CRD ๋ฅผ ํ†ตํ•œ Reconciliation ์„ ์ง„ํ–‰ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์˜ ์ด๋ฆ„์— Controller ๊ฐ€ ๋ถ™๋Š”๋‹ค๋Š” ๊ฒƒ์ด์ฃ . ArgoCD ๋˜ํ•œ Application ๊ฐ™์€ CRD ๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๋ฐ๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๋ง์ด์ฃ .

 

๊ทธ๋ ‡๊ฒŒ ๊ตฌ๋ถ„ ์ง€์œผ๋ ค๊ณ  ๋…ธ๋ ฅ?ํ•˜์ง€๋Š” ์•Š๋Š”๊ฑฐ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

๊ทธ๋ž˜๋„ ์ฐจ์ด๊ฐ€ ๋” ์„ธ๋ถ€์ ์œผ๋กœ ๊ถ๊ธˆํ•˜๋‹ค๋ฉด ์—ฌ๊ธฐ Overstackflow ๋‹ต๋ณ€์„ ์ฐธ๊ณ ํ•˜์‹œ๋ฉด ์ข‹์„ ๊ฑฐ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

Controller ์™€ Operator ๋น„๊ต

 

๊ทธ๋Ÿผ ์ด์ œ Controller ์™€ Operator ๊ฐ€ ๋ญ”์ง€ ์•Œ์•˜์œผ๋‹ˆ, ์‹ค์ œ๋กœ Controller ๋ฅผ ๊ตฌํ˜„ํ•ด๋ณด์ฃ !

 

To The Code~

 

 

 

๋‚˜๋งŒ์˜ Controller ๋งŒ๋“ค๊ธฐ


ConfigMap ์ด ๋ณ€๊ฒฝ๋  ๊ฒฝ์šฐ, Annotations ์˜ ๋ช…์‹œ๋œ Deployment ์˜ ํŒŒ๋“œ๋“ค์„ Recreate ํ•˜๋Š” Controller ๋ฅผ ๋งŒ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค!

 

myconfig.yaml

apiVersion: v1
data:
  HELLO: "World Twice"
kind: ConfigMap
metadata:
  name: myconfig
  annotations:
    restart-deployment: mypod #-- ํŒŒ๋“œ์˜ Recreate ๋ฅผ ์ง„ํ–‰ํ•  Deployment ์˜ ์ด๋ฆ„

 

mypod.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mypod
  labels:
    app: mypod
    test: test
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mypod
  template:
    metadata:
      labels:
        app: mypod
    spec:
      containers:
        - name: mypod
          image: nginx:1.26
          ports:
            - containerPort: 80
          env:
            - name: HELLO
              valueFrom:
                configMapKeyRef:
                  name: myconfig
                  key: HELLO

 

 

์ฝ”๋“œ๋Š” Go ๋ฅผ ํ†ตํ•ด์„œ ๊ตฌํ˜„ํ–ˆ๊ณ , kubernetes/client-go ์˜ examples ๋ฅผ ํ† ๋Œ€๋กœ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

 

์šฐ์„  ๊ฒฐ๊ณผ๋ถ€ํ„ฐ ๋ณด์—ฌ๋“œ๋ฆฌ์ฃ !

 

์•„๋ž˜ ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด Controller ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

$ go run main.go -kubeconfig="myconfig" -master="myk8surl"

Controller Init

 

๊ทธ๋ฆฌ๊ณ  ํ˜„์žฌ ๋ฐฐํฌ๋˜์–ด์žˆ๋Š” Deployment ์˜ Pod ์—๋Š” myconfig ๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋˜ ๋ฐ์ดํ„ฐ๊ฐ’์„ ํ™˜๊ฒฝ๋ณ€์ˆ˜๋กœ ๋“ค๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

Hello=World Twice

 

๊ทธ๋Ÿผ ์ด์ œ myconfig ์˜ ๋ฐ์ดํ„ฐ๊ฐ’์„ HELLO=World Once ๋กœ ๋ฐ”๊ฟ”์ค๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿฌ์ž Controller ์—์„œ Sync/Add/Update for ConfigMap myconfig ๋กœ๊ทธ๊ฐ€ ํ•˜๋‚˜ ๋” ์ฐํžŒ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์ฃ .

Sync/Add/Update for ConfigMap myconfig ํ•˜๋‚˜๊ฐ€ ๋” ์ฐํž˜

 

๋˜ํ•œ k get configmap -w ์™€ ๊ฒฐ๊ณผ๊ฐ€ ๋™์ผํ•˜๋‹ค๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

k get configmap -w

 

๊ทธ๋ฆฌ๊ณ  ์‹ค์ œ๋กœ ์ˆ˜๋™์œผ๋กœ ํŒŒ๋“œ๋ฅผ ์žฌ์‹œ์ž‘ํ•˜์ง€ ์•Š๊ณ , ์ž๋™์œผ๋กœ ๋ณ€๊ฒฝ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ด๋ด…๋‹ˆ๋‹ค.

Hello=World Once

 

์ž˜ ๋ฐ”๋€ ๊ฒƒ์„ ํ™•์ธํ•ด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!

 

๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•ด๋ดค์œผ๋‹ˆ, ์ด์ œ ์ฝ”๋“œ๋ฅผ ํ•œ๋ฒˆ์”ฉ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค!

์œ„์— ๋นจ๊ฐ„ ๋„ค๋ชจ๋ถ€ํ„ฐ 1,2,3 ... ์”ฉ ์ˆœ์„œ๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค!

 

main.go 199

  1. ListWatch ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค, ์ด ๋…€์„์€ ๋’ค์— ์žˆ์„ Informer ์— ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  2. WorkQueue ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค, ๋’ค์— ์žˆ์„ Informer ์— ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

 

main.go 208

  1. Indexer ์™€ Informer ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  2. ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“œ๋Š” Controller ์˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

Indexer ๋Š” ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ๋ฆฌ์†Œ์Šค์˜ ์ธ๋ฑ์‹ฑ๊ณผ ๋น ๋ฅธ ์กฐํšŒ๋ฅผ ์ง€์›ํ•˜๋Š” ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•˜๋Š”๋ฐ, ์ด๋ฅผ ํ†ตํ•ด ์กฐ๊ฑด์— ๋งž๋Š” ๋ฆฌ์†Œ์Šค๋ฅผ ๋น ๋ฅด๊ฒŒ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

Informer ๋Š” Controller ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š”๋ฐ ํ•„์š”ํ•œ ํ•ต์‹ฌ ๊ฐ์ฒด ์ค‘ ํ•˜๋‚˜๋กœ, ListWatch ๋ฅผ ํ†ตํ•ด ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ๋ฆฌ์†Œ์Šค์˜ ์ƒํƒœ๋ฅผ ์ฃผ์‹œ(Watch) ํ•ฉ๋‹ˆ๋‹ค. Add/Update/Delete ์ด๋ฒคํŠธ์— ๋Œ€ํ•ด ๋ฐ˜์‘ํ•˜์—ฌ ์•Œ๋ ค์ฃผ๋Š”(Inform) ๋…€์„์ž…๋‹ˆ๋‹ค.

 

์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ์‹ค์ œ๋กœ Add/Update/Delete ์ด๋ฒคํŠธ์— ๋Œ€ํ•œ ์ฝ”๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋˜ํ•œ Add/Update/Delete ์ด๋ฒคํŠธ ์•ˆ์„ ๋ณด๋ฉด queue.Add(key) ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”๋ฐ, ์ด๋ฅผ ํ†ตํ•ด ์–ด๋–ค ๋ฆฌ์†Œ์Šค์ธ์ง€ ์•Œ ์ˆ˜ ์žˆ๋Š” key ๋ฅผ queue ์— ์ง‘์–ด๋„ฃ๊ณ , ๋’ค์ชฝ์— ์žˆ์„ ์ฝ”๋“œ์—์„œ pop() ํ•ด์„œ ๊ฐ€์ ธ์˜ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. (๋’ค์ชฝ์—์„œ ๋‹ค๋ฃน๋‹ˆ๋‹ค!)

 

์ฆ‰, ListWatch ๋ฅผ ํ†ตํ•ด k get pods -w ์™€ ๊ฐ™์ด ๋ฌดํ•œ์œผ๋กœ(Control Loop) ๋ฆฌ์†Œ์Šค๋ฅผ ์ฃผ์‹œ(Watch)ํ•ฉ๋‹ˆ๋‹ค.

 

main.go 237

  1. Indexer ์— ์ถ”๊ฐ€์ ์ธ ๋ฆฌ์†Œ์Šค๋ฅผ ์ถ”๊ฐ€ํ•ด์ค๋‹ˆ๋‹ค.

 

main.go 262

  1. ์œ„์—์„œ ์ƒ์„ฑํ•œ Controller ๊ฐ์ฒด๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๋’ค์— ์žˆ๋Š” workers ๋Š” Reconciliation ์˜ 2๋ฒˆ์งธ ๋‹จ๊ณ„์ธ Analyze ์™€ 3๋ฒˆ์งธ ๋‹จ๊ณ„์ธ Act ๋ฅผ ์ˆ˜ํ–‰ํ• ๋•Œ ์ฒ˜๋ฆฌํ•  ๋ณ‘๋ ฌ ๊ฐฏ์ˆ˜์ž…๋‹ˆ๋‹ค.
  2. go routine ์œผ๋กœ๋งŒ ์‹คํ–‰๋˜๋Š” Controller ๋ฅผ ํฌ๊ทธ๋ผ์šด๋“œ๋กœ ์˜๊ตฌ์ ์œผ๋กœ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

 

main.go 145

์•ž์„œ ์‹คํ–‰ํ–ˆ๋˜ Controller.Run() ์˜ ๊ตฌํ˜„ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

  1. informer.Run ์„ ๊ณ ๋ฃจํ‹ด์œผ๋กœ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๋’ค์—์„œ ์‚ดํŽด๋ณด๊ฒ ์ง€๋งŒ, stopCh ์ด close ๋ ๋•Œ๊นŒ์ง€ ListWatch ๋ฅผ ํ†ตํ•ด ๋ฌดํ•œ์œผ๋กœ(Control Loop) ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ์ฃผ์‹œ(Watch) ํ•ฉ๋‹ˆ๋‹ค.
  2. c.runWorker() ๋Š” wait.Until ๊ณ ๋ฃจํ‹ด์œผ๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. c.runWorker() ์€ Analyze ์™€ Act ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ํ•จ์ˆ˜๋กœ ๋’ค์—์„œ ๋‹ค๋ฃน๋‹ˆ๋‹ค.

 

wait.Until ์€ ๊ฝค๋‚˜ ์ค‘์š”ํ•œ ํ•จ์ˆ˜์ด๋ฏ€๋กœ ํ•œ๋ฒˆ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

backoff.go 211

  1. wait.Until() ๋ฅผ ํƒ€๊ณ , ํƒ€๊ณ  ๋“ค์–ด๊ฐ€๋ฉด ๊ฒฐ๊ตญ BackoffUntil ์ด๋ผ๋Š” ํ•จ์ˆ˜๊ฐ€ ๋‚˜์˜ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒผ์„ ๊ฒฝ์šฐ ๋ฐ”๋กœ ์ข…๋ฃŒํ•˜๋Š”๊ฒŒ ์•„๋‹ˆ๊ณ , Backoff ์„ ์ง„ํ–‰ํ•ด์„œ ๊ณ„์† ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ•˜๋Š” ๊ฑฐ์ฃ . 
  2. ๊ทธ๋ฆฌ๊ณ  ๋ฌธ์ œ๊ฐ€ ์—†๋”๋ผ๋„ ์ค‘๊ฐ„์— ๋„˜๊ฒจ๋ฐ›์€ f() ๋ฅผ for{} ์„ ํ†ตํ•ด ๊ณ„์†ํ•ด์„œ ์‹คํ–‰์‹œํ‚ต๋‹ˆ๋‹ค.

์–ด? ์—ฌ๊ธฐ์„œ ํ•œ๊ฐ€์ง€ ์˜๋ฌธ์ด ์ƒ๊ธธ ์ˆ˜ ์žˆ์„ ๊ฒ๋‹ˆ๋‹ค. "for{} ์„ ๋Œ๊ฒŒ๋˜๋ฉด ๋ฌดํ•œ์ •์œผ๋กœ ์‰ดํ‹ˆ์—†์ด f() ๊ฐ€ ์‹คํ–‰๋ ํ…๋ฐ ์ด๊ฑฐ ๋งž์•„?"

 

main.go 52

์•ž์—์„œ WorkQueue ๋ฅผ ์ƒ์„ฑํ–ˆ๋˜๊ฑฐ ๊ธฐ์–ต๋‚˜์‹œ๋‚˜์š”? Informer ๋Š” ListWatch ๋ฅผ ํ†ตํ•ด ๊ฐ€์ ธ์˜ค๋Š” ๋ฆฌ์†Œ์Šค๋ฅผ WorkQueue ์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  go wait.Until(c.runWorker, time.Second, stopCh) ์„ ์ˆ˜ํ–‰ํ•˜๋Š”๋ฐ c.runWorker ํ•จ์ˆ˜ ์•ˆ์„ ๋ณด๊ฒŒ๋˜๋ฉด processNextItem ์ด ์‹คํ–‰๋˜๊ณ  processNextItem ์•ˆ์—๋Š” c.queue.Get() ์„ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

์ฆ‰, WorkQueue ์—์„œ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ๋ฆฌ์†Œ์Šค๋ฅผ ๋นผ์˜ต๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿฐ๋ฐ c.queue.Get() ๋ฅผ ์ž์„ธํžˆ ๋“ค์—ฌ๋‹ค๋ณด๋ฉด, Lock() ์ด ๊ฑธ๋ ค์žˆ๋Š”๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

queue.go 278

์ •๋ฆฌํ•˜์ž๋ฉด wait.Util() ์€ for{} ๋•Œ๋ฌธ์— ์‰ดํ‹ˆ์—†์ด ๋ฌดํ•œ์ •์œผ๋กœ ๋Œ ์ˆ˜ ์žˆ์ง€๋งŒ, Lock() ์„ ํ†ตํ•ด ๊ณ ๋ฃจํ‹ด์„ ๋ธ”๋กํ•ด๋ฒ„๋ฆฌ๋Š” ๊ฑฐ์ฃ ! ๊ทธ๋ฆฌ๊ณ  defer() ๋ฅผ ํ†ตํ•ด Unlock() ์„ ์‹œ์ผœ์ค๋‹ˆ๋‹ค.

 

์ˆ˜์ •!! ์‹ค์งˆ์ ์œผ๋กœ ๊ณ ๋ฃจํ‹ด์„ ๋ธ”๋กํ•˜๋Š” ๊ฑด for q.queue.Len() == 0 && !q.shuttingDown {} ๋‚ด์— ์žˆ๋Š” q.cond.Wait() ์ž…๋‹ˆ๋‹ค.
๋ฌผ๋ก  Lock ์„ ํ•ด์ฃผ์ง€๋งŒ for ๋ฌธ์ด ์—†์œผ๋ฉด ๊ฒฐ๊ตญ Unlock ์ด ๋˜๋ฒ„๋ฆฌ์ฃ .

 

๊ทธ๋Ÿผ ์ด์ œ Informer ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ ์กฐ๊ธˆ ๋” ์ž์„ธํžˆ ์‚ดํŽด๋ณด์ฃ !

controller.go 135

controller.go ๋Š” kubernetes/client-go ์—์„œ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค.

  1. Reflector ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฐ์ฒด๋Š” ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค API ์—์„œ ๋ฆฌ์†Œ์Šค๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  2. r.Run() ์„ ํ†ตํ•ด Reflector ์˜ ListWatch ๋ฅผ ์‹คํ–‰์‹œํ‚ด์œผ๋กœ์จ, ์ง€์†์ ์œผ๋กœ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ๋ฆฌ์†Œ์Šค๋ฅผ ์ฃผ์‹œ(Watch) ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ถ€๋ถ„์€ Reconciliation ์˜ ์ฒซ๋ฒˆ์งธ ์Šคํ…์ธ Observe ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
  3. processLoop ์ด wait.Until ์„ ํ†ตํ•ด ์‹คํ–‰๋˜๋Š”๋ฐ, ๋“ค์–ด๊ฐ€๋ณด๋ฉด c.config.Queue.Pop() ์ด for{} ์„ ํ†ตํ•ด ๋ฌดํ•œ์ •์œผ๋กœ ๋Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ๋งํ•˜๋Š” Queue ๋Š” WorkQueue ๋Š” ์•„๋‹ˆ๊ณ , ListWatch ๋ฅผ ํ†ตํ•ด ๊ฐ€์ ธ์˜ค๋Š” ๋ฆฌ์†Œ์Šค๋ฅผ ๋‹ด๋Š” Queue ์ž…๋‹ˆ๋‹ค.

 

reflector.go

  1. ListAndWatch() ๋ฅผ ์‹คํ–‰ํ•จ์œผ๋กœ์จ Observe ๋ฅผ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ถ”๊ฐ€์ ์œผ๋กœ r.typeDescription ์—๋Š” ์‹ค์ œ๋กœ ์ฃผ์‹œ(Watch) ํ•˜๊ณ  ์žˆ๋Š” ๋ฆฌ์†Œ์Šค์˜ ํƒ€์ž…์„ ๋‹ด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด v1.ConfigMap, v1.Pod ์ฒ˜๋Ÿผ ๋ง์ด์ฃ .

 

๊ทธ๋Ÿผ ์ง€๊ธˆ๊นŒ์ง€ ์‚ดํŽด๋ณธ ๊ฒƒ๋“ค์€ ํ•œ๋ฒˆ ์ •๋ฆฌํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

Informer ๋Š” ListWatch ๋ฅผ ํ†ตํ•ด Control Loop ์„ ์ง„ํ–‰ํ•˜๋ฉด์„œ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ๋ฆฌ์†Œ์Šค๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. Add/Update/Delete ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ WorkQueue ์— ๋ฆฌ์†Œ์Šค key ๋ฅผ ๋„ฃ์€ ํ›„, ์ถ”ํ›„ Reconciliation ์˜ 2๋ฒˆ์งธ ๋‹จ๊ณ„์ธ Analyze ์™€ 3๋ฒˆ์งธ ๋‹จ๊ณ„์ธ Act ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฐ‘๋ฐ”๋‹ฅ์„ ๋‹ค์ง‘๋‹ˆ๋‹ค.

 

main.go 145

c.informer.Run ์€ ์‚ดํŽด๋ดค์œผ๋‹ˆ. ์ด์ œ๋Š” c.runWorker ์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์ฃ .

  1. c.runWorker ๋˜ํ•œ wait.Until ๊ณ ๋ฃจํ‹ด์„ ํ†ตํ•ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

 

main.go 169

  1. runWorker ์•ˆ์—๋Š” processNextItem() ์ด false ์ผ๋•Œ๊นŒ์ง€ for{} ์„ ํ†ตํ•ด ๋ฌดํ•œ์ •์œผ๋กœ ๋Œ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

main.go 52

  1. ์•ž์„œ informer ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ Add/Update/Delete ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ queue.add(key) ๋ฅผ ํ†ตํ•ด key ๋ฅผ ๋„ฃ์–ด์คฌ๋Š”๋ฐ, ์ด๋ฒˆ์—” Get() ์„ ํ†ตํ•ด key ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. (Get() ํ•จ์ˆ˜ ์•ˆ์—๋Š” pop() ์ด ์žˆ์Œ) ๊ทธ๋ฆฌ๊ณ  ์ด queue ๊ฐ€ ๋น„์–ด์žˆ๋Š” ์ƒํƒœ๋ผ๋ฉด false ๋ฅผ ๋ฆฌํ„ดํ•จ์œผ๋กœ์จ c.processNextItem() ์„ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค.
  2. c.syncToStdout(key) ๋Š” Reconciliation ์˜ Analyze ์™€ Act ์— ๊ด€ํ•œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. (syncToStdout ๋ผ๋Š” ์ด๋ฆ„ ๋ง๊ณ  ๋‹ค๋ฅธ ์ด๋ฆ„์œผ๋กœ ์ง€์–ด๋„ ์ „ํ˜€ ์ƒ๊ด€ ์—†์Œ)

 

main.go 73

ConfigMap ์˜ Annotations ๋ฅผ ๊ฐ€์ ธ์˜จ ํ›„์—, "restart-deployment" Annotation ์˜ value ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ํ•ด๋‹น value ๋Š” ์žฌ์‹œ์ž‘ํ•  Deployment ์˜ ์ด๋ฆ„์„ ๊ฐ€์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

๊ทธ๋ฆฌ๊ณ  ์œ„์—์„œ ๊ฐ€์ ธ์˜จ Deployment ์˜ ์ด๋ฆ„์„ ํ†ตํ•ด Deployment ์˜ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. Deployment ์˜ LabelSelector ๋ฅผ ํ†ตํ•ด์„œ ๋งตํ•‘๋œ Pod ๋˜ํ•œ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

 

์ดํ›„ ๊ฐ€์ ธ์˜จ Pod ๋ฅผ ์ „๋ถ€ ์‚ญ์ œํ•ด์„œ ์žฌ์‹œ์ž‘๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•จ์œผ๋กœ์จ ๋ณ€๊ฒฝ๋œ ConfigMap ์˜ ๋ฐ์ดํ„ฐ ๊ฐ’์ด ํŒŒ๋“œ์— ์ ์šฉ๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

 

์ด๋ฅผ ํ†ตํ•ด Analyze ์™€ Act ๋„ ๊ตฌํ˜„ํ•˜์˜€๊ณ , ๊ฐ„๋‹จํ•œ Controller ๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

Operator ๋„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š”๋ฐ, Operator ๊ฐ™์€ ๊ฒฝ์šฐ operator-sdk ๋ฅผ ์ด์šฉํ•ด์„œ ๋งŒ๋“œ๋Š” ๊ฒƒ์„ ์ถ”์ฒœ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿผ ์ด์ œ ์‹ค์ œ๋กœ Kubernetes ์˜ ReplicaSet ์€ ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ Control Loop ๋Œ๋ฉด์„œ Reconciliation ์„ ์ˆ˜ํ–‰ํ•˜๋Š”์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

ReplicaSet ์ฝ”๋“œ ๊นŒ๋ณด๊ธฐ


 

kubernetes/cmd/kube-controller-manager/app/controllermanager.go

newReplicaSetControllerDescripto() ๋ฅผ ํ†ตํ•ด ReplicaSet ์— ๊ด€ํ•œ ControllerDescriptor ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

 

kubernetes/cmd/kube-controller-manager/app/app.go

๊ทธ๋ฆฌ๊ณ  newReplicaSetControllerDescripto() ๋ฅผ ํƒ€๊ณ  ๋“ค์–ด๊ฐ€๋ฉด startReplicaSetController ํ•จ์ˆ˜๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

kubernetes/cmd/kube-controller-manager/app/app.go

NewReplicaSetController ๊ฐ์ฒด์— InformerFactory ๋ฅผ ์ด์šฉํ•ด์„œ ReplicaSet ๊ณผ Pods ๋ฆฌ์†Œ์Šค์˜ Informer ๋ฅผ ์ถ”๊ฐ€ํ•ด์„œ ์ƒ์„ฑ ํ•œ ํ›„ Run() ์„ ์‹คํ–‰ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

kubernetes/pkg/controller/replicaset/replica_set.go

์—ฌ๊ธฐ์„œ๋ถ€ํ„ฐ๋Š” ์˜ˆ์ œ์™€ ํฌ๊ฒŒ ๋‹ค๋ฅผ ๋ฐ”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. go wait.UntilWithContext ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด์„œ rcs.worker ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

 

kubernetes/pkg/controller/replicaset/replica_set.go

rsc.queue ์—์„œ key ๋ฅผ ๊ฐ€์ ธ์˜จ ํ›„์— rsc.syncHandler ๋ฅผ ์‹คํ–‰ํ•˜๊ฒŒ ๋˜๋Š”๋ฐ,

 

kubernetes/pkg/controller/replicaset/replica_set.go

์—ฌ๊ธฐ์— ์šฐ๋ฆฌ๊ฐ€ ์•„๋Š” ๊ทธ ReplicaSet ์ด ํ•˜๋Š” ํ–‰์œ„๊ฐ€ ์ž‘์„ฑ๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค.

 

ํ™•์‹คํžˆ ๋งŒ๋“ค์—ˆ๋˜ ์˜ˆ์ œ๋ณด๋‹ค ํ›จ์”ฌ ๋” ๋งŽ์ด ์ถ”์ƒํ™”๊ฐ€ ๋˜์–ด ์žˆ๊ธฐ ํ•œ๋ฐ, ํฐ ํ‹€์—์„œ๋Š” ๋น„์Šทํ•œ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

 

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค Controller Manager ๋Š” "๋ถˆ๊ฝƒ ๊ฐ™์€ ๋ˆˆ๋น›"์œผ๋กœ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ๋ฆฌ์†Œ์Šค๋“ค์„ ์ฃผ์‹œ(Watch) ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋Š˜ ์ด "๋ถˆ๊ฝƒ ๊ฐ™์€ ๋ˆˆ๋น›"์„ ์ฝ”๋“œ๋กœ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„ํ–ˆ๋Š”์ง€ ๊ถ๊ธˆํ–ˆ๋Š”๋ฐ ์ด์ œ๋Š” ๋‹ต์„ ์•Œ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

๊ณ ๋ฃจํ‹ด์œผ๋กœ Informer ๊ฐ์ฒด์™€ ListWatch ๋ฅผ ์‹คํ–‰ํ•ด์„œ ๋ฆฌ์†Œ์Šค๋ฅผ ๋ฌดํ•œ์ •์œผ๋กœ(Control Loop) ๋ฐ”๋ผ๋ณด๋‹ค๊ฐ€, Add/Update/Delete ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ด๋ฅผ WorkQueue ์— ๋„ฃ๊ฒŒ ๋˜๊ณ ,  ๊ณ ๋ฃจํ‹ด์œผ๋กœ wait.Util(๋กœ์ง) ์„ ์ˆ˜ํ–‰ํ•จ์œผ๋กœ์จ ๋“ค์–ด์˜ค๋Š” ์ด๋ฒคํŠธ์— ๋Œ€ํ•ด Reconcile ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ด์˜€์Šต๋‹ˆ๋‹ค.

 

์ด๋ ‡๊ฒŒ ์ด๋ฒˆ ๊ธ€์—์„œ๋Š” Controller ์˜ Low ํ•œ ๋ถ€๋ถ„๊นŒ์ง€ ์•Œ์•„๋ดค๋Š”๋ฐ, ๋‚˜์ค‘์— Controller Manager ์˜ ์ปจํŠธ๋ฆฌ๋ทฐํ„ฐ๋„ ํ•œ๋ฒˆ ๋„์ „ํ•ด๋ด์•ผ๊ฒ ๋„ค์š”!

 

๊ทธ๋Ÿผ ์˜ค๋Š˜์€ ์—ฌ๊ธฐ๊นŒ์ง€!

 

profile on loading

Loading...