• Aiden's Lab แ„‚แ…ฒแ„‰แ…ณแ„…แ…ฆแ„แ…ฅ
  • Posts
  • ๐Ÿ”ญแ„’แ…ขแ†จแ„‰แ…ตแ†ท แ„€แ…ตแ„‚แ…ณแ†ผ 3แ„€แ…กแ„Œแ…ต แ„‰แ…ตแ†ฏแ„‰แ…ณแ†ธแ„‹แ…ณแ„…แ…ฉ แ„‹แ…กแ†ฏแ„‹แ…กแ„‡แ…ฉแ„‚แ…ณแ†ซ Kyverno (feat. minikube)

๐Ÿ”ญแ„’แ…ขแ†จแ„‰แ…ตแ†ท แ„€แ…ตแ„‚แ…ณแ†ผ 3แ„€แ…กแ„Œแ…ต แ„‰แ…ตแ†ฏแ„‰แ…ณแ†ธแ„‹แ…ณแ„…แ…ฉ แ„‹แ…กแ†ฏแ„‹แ…กแ„‡แ…ฉแ„‚แ…ณแ†ซ Kyverno (feat. minikube)

Kyvernoแ„‹แ…ด แ„’แ…ขแ†จแ„‰แ…ตแ†ท แ„€แ…ตแ„‚แ…ณแ†ผ 3แ„€แ…กแ„Œแ…ตแ„…แ…ณแ†ฏ minikube แ„แ…ณแ†ฏแ„…แ…ฅแ„‰แ…ณแ„แ…ฅแ„‹แ…ฆ แ„‡แ…ขแ„‘แ…ฉแ„’แ…กแ„€แ…ฉ แ„‰แ…ตแ†ฏแ„‰แ…ณแ†ธแ„’แ…กแ„†แ…ง แ„‹แ…ตแ†จแ„’แ…งแ„‡แ…ฉแ†ธแ„‚แ…ตแ„ƒแ…ก.

์•ˆ๋…•ํ•˜์„ธ์š”, Aidenโ€™s Lab ๋‰ด์Šค๋ ˆํ„ฐ์ž…๋‹ˆ๋‹ค.

์—ฌ๋Ÿฌ ๊ฐœ๋ฐœ์ž ๋˜๋Š” ํŒ€์—์„œ ๋™์ผ Kubernetes ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ์ผ๊ด€๋œ ๊ทœ์น™, ๋˜๋Š” ์ •์ฑ…์„ ์ ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์•ˆ์ •์ ์ธ ์šด์˜๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋ณด์•ˆ ์ทจ์•ฝ์ ์„ ์ตœ์†Œํ™”ํ•  ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ธ๋ฐ์š”. ์—ฌ๊ธฐ์„œ ๋งํ•˜๋Š” ์ •์ฑ…์ด๋ผ ํ•˜๋ฉด...

  • ๋ชจ๋“  ์›Œํฌ๋กœ๋“œ์— ํŠน์ • ๋ณด์•ˆ ์„ค์ •์„ ๊ฐ•์ œํ•˜๊ฑฐ๋‚˜,

  • ๋ฆฌ์†Œ์Šค ์‚ฌ์šฉ๋Ÿ‰์„ ์ œํ•œํ•˜๊ณ ,

  • ํ•„์ˆ˜ ๋ ˆ์ด๋ธ”์ด ๋ฌด์กฐ๊ฑด ํฌํ•จ๋˜๋„๋ก ํ•˜๋Š” ๋“ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฐ ํด๋Ÿฌ์Šคํ„ฐ์˜ ์ •์ฑ…์„ ๋ฌธ์„œ๋กœ๋งŒ ๊ด€๋ฆฌํ•˜๊ณ  ๊ฐœ๋ฐœ์ž/์šด์˜์ž๊ฐ€ ์ง์ ‘ ์ง€ํ‚ค๋„๋ก ํ•œ๋‹ค๋ฉด ์‹ค์ˆ˜(ํœด๋จผ ์—๋Ÿฌ)๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ ๋ฆฌ์†Œ์Šค๋ฅผ ๋ฐฐํฌํ•  ๋•Œ๋งˆ๋‹ค Kubernetes ๋ฆฌ์†Œ์Šค ๋งค๋‹ˆํŽ˜์Šคํ† ๋ฅผ ์ผ์ผ์ด ๊ฒ€ํ† ํ•ด์•ผ ํ•œ๋‹ค๋ฉด, ํด๋Ÿฌ์Šคํ„ฐ ์šด์˜ ํšจ์œจ์„ฑ ์ธก๋ฉด์—์„œ๋„ ์•ˆ ์ข‹๊ฒ ์ฃ ?

๊ทธ๋ž˜์„œ ํด๋Ÿฌ์Šคํ„ฐ์— ์ ์šฉ๋  ์ •์ฑ…์„ ์ฝ”๋“œ๋กœ ์ •์˜ํ•˜๊ณ , ์‹œ์Šคํ…œ์ด ์ด๋ฅผ ์ž๋™์œผ๋กœ ๊ฐ•์ œํ•˜๋Š” ๋ฐฉ์‹์ด ๋“ฑ์žฅํ–ˆ์Šต๋‹ˆ๋‹ค. Policy as Code(PaC)๋ผ๊ณ  ํ•˜๋Š” ๊ฐœ๋…์ธ๋ฐ์š”. ํด๋Ÿฌ์Šคํ„ฐ์— ๋ฆฌ์†Œ์Šค๊ฐ€ ๋ฐฐํฌ๋˜๊ธฐ ์ „์— ์ •์˜๋œ ์ •์ฑ…์„ ์ค€์ˆ˜ํ•˜๋Š”์ง€ ์ž๋™์œผ๋กœ ๊ฒ€์ฆํ•˜๊ณ , ์œ„๋ฐ˜ ์‹œ์—๋Š” ๋ฆฌ์†Œ์Šค ๋ฐฐํฌ๋ฅผ ์ฐจ๋‹จํ•ด์„œ ํด๋Ÿฌ์Šคํ„ฐ์˜ ๋ณด์•ˆ์„ฑ๊ณผ ์•ˆ์ •์„ฑ์„ ์ด๋Œ์–ด๋‚ด๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  Kubernetes ํด๋Ÿฌ์Šคํ„ฐ์—์„œ PaC๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ๋‚˜์˜จ ์˜คํ”ˆ์†Œ์Šค ์ •์ฑ… ์—”์ง„(Policy Engine)์ด ๋ฐ”๋กœ, Kyverno์ž…๋‹ˆ๋‹ค.

Kubernetes ํด๋Ÿฌ์Šคํ„ฐ์— ์ •์ฑ…์ด ํ•„์š”ํ•  ๋• Kyverno๋ฅผ ์จ๋ณด์ž

Kyverno๋Š” Kubernetes ํ™˜๊ฒฝ์—์„œ ์ •์ฑ…์„ ๊ด€๋ฆฌํ•˜๊ณ  ์‹œํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ์„ค๊ณ„๋œ ์˜คํ”ˆ์†Œ์Šค ์ •์ฑ… ์—”์ง„์ž…๋‹ˆ๋‹ค. ํด๋Ÿฌ์Šคํ„ฐ์— ๋“ค์–ด์˜ค๋Š” ๋ชจ๋“  ๋ฆฌ์†Œ์Šค ์ƒ์„ฑ ๋ฐ ๋ณ€๊ฒฝ ์š”์ฒญ์„ ๊ฐ์ง€ํ•˜๊ณ , ์ •์˜๋œ ์ •์ฑ…์— ๋”ฐ๋ผ ํ—ˆ์šฉ, ์ฐจ๋‹จ ๋˜๋Š” ์ˆ˜์ • ์ž‘์—…์„ ํ•˜๋Š” '๋ฌธ์ง€๊ธฐ'๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์ฃ .

๊ทธ๋ฆฌ๊ณ  Kyveno๋Š” Kubernetes์˜ Admission Control ์›นํ›… ๊ธฐ๋Šฅ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘ํ•˜๋Š”๋ฐ์š”. ์ข€ ๋” ํ’€์–ด์„œ ์„ค๋ช…ํ•˜์ž๋ฉด, ์‚ฌ์šฉ์ž๊ฐ€ kubectl apply์™€ ๊ฐ™์€ ๋ช…๋ น์–ด๋กœ Kubernetes ๋ฆฌ์†Œ์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ ๋ณ€๊ฒฝํ•˜๋ ค๊ณ  ํ•  ๋•Œ Kubernetes API ์„œ๋ฒ„๊ฐ€ ํ•ด๋‹น ์š”์ฒญ์„ Kyverno์—๊ฒŒ ์ „๋‹ฌํ•ด์„œ ์ •์ฑ… ๊ฒ€์ฆ์„ ์š”์ฒญํ•˜๋Š” ์‹์ž…๋‹ˆ๋‹ค. ์ด๋•Œ Kyverno๋Š” ์š”์ฒญ ๋‚ด์šฉ์„ ๊ฒ€ํ† ํ•˜๊ณ  ์ •์ฑ…์— ๋”ฐ๋ผ์„œ ํ—ˆ์šฉ/๊ฑฐ๋ถ€ ์—ฌ๋ถ€๋ฅผ Kubernetes API ์„œ๋ฒ„์— ๋‹ค์‹œ ์•Œ๋ ค์คŒ์œผ๋กœ์จ ์ •์ฑ…์„ ๊ฐ•์ œํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒ๋‹ˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ์šฐ๋ฆฌ๊ฐ€ Kubernetes ํด๋Ÿฌ์Šคํ„ฐ์˜ ์ •์ฑ… ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•ด Kyverno๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ผ๊นŒ์š”? Kyverno์—๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ํŠน์žฅ์ ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

  1. ClusterPolicy ๋˜๋Š” Policy์™€ ๊ฐ™์€ Kubernetes CRD๋กœ ์ •์ฑ… ์ •์˜

    • ํด๋Ÿฌ์Šคํ„ฐ ์ „์ฒด์— ์ ์šฉ๋  ์ •์ฑ…์€ ClusterPolicy๋กœ, Namespace ๋‹จ์œ„๋กœ ์ ์šฉ๋  ์ •์ฑ…์€ Policy๋กœ ์ •์˜ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

    • ์ผ๋ฐ˜์ ์ธ Kubernetes ๋ฆฌ์†Œ์Šค๋ฅผ ๋‹ค๋ฃจ๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•˜๊ฒŒ kubectl์„ ์‚ฌ์šฉํ•˜์—ฌ ์ •์ฑ…์„ ์ƒ์„ฑ, ์กฐํšŒ, ์ˆ˜์ •, ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    • GitOps ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ ์ ์šฉํ•˜์—ฌ ์ •์ฑ…์˜ ๋ฒ„์ „์„ ๊ด€๋ฆฌํ•˜๊ธฐ์—๋„ ์šฉ์ดํ•ฉ๋‹ˆ๋‹ค.

  2. ์ •์ฑ… ๊ฒฐ๊ณผ๋ฅผ Kubernetes ์ด๋ฒคํŠธ๋‚˜ PolicyReport๋ฅผ ํ†ตํ•ด ํ™•์ธ ๊ฐ€๋Šฅ

    • ์‚ฌ์šฉ์ž๋Š” kubectl get events ๋˜๋Š” kubectl describe์™€ ๊ฐ™์€ ์ต์ˆ™ํ•œ ๋ช…๋ น์–ด๋กœ ์ •์ฑ…์˜ ๊ฒฐ๊ณผ๋ฅผ ์‰ฝ๊ฒŒ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    • ์ •์ฑ… ๋””๋ฒ„๊น…์ด๋‚˜ ํด๋Ÿฌ์Šคํ„ฐ ์ƒํƒœ ๊ฐ์‚ฌ(Audit)๊ฐ€ ๋”์šฑ ํŽธ๋ฆฌํ•ด์ง‘๋‹ˆ๋‹ค.

  3. ๋ฆฌ์†Œ์Šค ์ƒ์„ฑ ์š”์ฒญ ์ฐจ๋‹จ ์™ธ์— ๋ฆฌ์†Œ์Šค ์ˆ˜์ • ๋˜๋Š” ์ƒ์„ฑ ๊ธฐ๋Šฅ๋„ ์ œ๊ณต

    • ์ •์ฑ…์„ ์œ„๋ฐ˜ํ•˜๋Š” ์š”์ฒญ์„ ์ฐจ๋‹จ(Validate)ํ•˜๋Š” ๊ธฐ๋Šฅ ์™ธ์—๋„, ๋ฆฌ์†Œ์Šค์— ํŠน์ • ๋‚ด์šฉ์„ ์ž๋™์œผ๋กœ ์ถ”๊ฐ€ํ•˜๋Š” ์ˆ˜์ •(Mutate) ๊ธฐ๋Šฅ๊ณผ, ํŠน์ • ์กฐ๊ฑด ๋งŒ์กฑ ์‹œ ๋‹ค๋ฅธ ๊ด€๋ จ ๋ฆฌ์†Œ์Šค๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑ(Generate)ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

    • ํด๋Ÿฌ์Šคํ„ฐ ์šด์˜์„ ์ž๋™ํ™”ํ•˜๊ณ  ๊ฐœ๋ฐœ์ž์˜ ํŽธ์˜์„ฑ์„ ๋†’์ด๋Š” ๋ฐ์— ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฐ Kyverno์—๋Š” ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ๋Š”๋ฐ์š”. ๊ทธ ์ค‘์—์„œ๋„ ์•„๋ž˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ 3๊ฐ€์ง€๋ฅผ ์ด๋ฒˆ ์‹ค์Šต ๊ฐ€์ด๋“œ์—์„œ ์ง์ ‘ ์‚ฌ์šฉํ•ด๋ณผ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

  1. ๊ฒ€์ฆ(Validate)

    • Kyverno์˜ ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ๊ทœ์น™์œผ๋กœ, ํด๋Ÿฌ์Šคํ„ฐ์— ์ƒ์„ฑ๋˜๊ฑฐ๋‚˜ ์ˆ˜์ •๋˜๋Š” ๋ฆฌ์†Œ์Šค๊ฐ€ ์ •์˜๋œ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

  2. ์ˆ˜์ •(Mutate)

    • Kubernetes ๋ฆฌ์†Œ์Šค ๋ช…์„ธ ์ค‘ ํŠน์ • ๊ฐ’์ด ๋ˆ„๋ฝ๋˜์—ˆ์„ ๋•Œ ๊ธฐ๋ณธ๊ฐ’์„ ์ž๋™์œผ๋กœ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜, ๋ชจ๋“  ๋ฆฌ์†Œ์Šค์— ๊ณตํ†ต์ ์ธ ๋ ˆ์ด๋ธ” ๋˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜์„ ๋ถ™์ด๋Š” ๋“ฑ ๋ฆฌ์†Œ์Šค๋ฅผ ์ž๋™์œผ๋กœ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.

  3. ์ƒ์„ฑ(Generate)

    • ํŠน์ • ๋ฆฌ์†Œ์Šค๊ฐ€ ์ƒ์„ฑ๋˜๋Š” ์ด๋ฒคํŠธ(ํŠธ๋ฆฌ๊ฑฐ)์— ๋ฐ˜์‘ํ•˜์—ฌ, ๊ทธ์™€ ๊ด€๋ จ๋œ ๋‹ค๋ฅธ ๋ฆฌ์†Œ์Šค๋“ค์„ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    • ์˜ˆ: ์ƒˆ๋กœ์šด Namespace๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ๋งˆ๋‹ค NetworkPolicy ๋˜๋Š” Role์„ ํ•จ๊ป˜ ์ƒ์„ฑ

๋ณธ ์‹ค์Šต ๊ฐ€์ด๋“œ๋Š” Kubernetes ์ •์ฑ… ์„ค์ •์ด๋‚˜ Kyverno์— ๋Œ€ํ•ด ๊ถ๊ธˆํ•˜์‹œ๊ฑฐ๋‚˜ ๋„์ž…์„ ๊ณ ๋ฏผํ•˜์‹œ๋Š” ๋ถ„๋“ค์—๊ฒŒ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ๋„๋ก Kyverno์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ 3๊ฐ€์ง€์— ๋Œ€ํ•œ ๋‚ด์šฉ์„ ํšจ๊ณผ์ ์œผ๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ด๋ฒˆ ์‹ค์Šต์—์„œ ๋‹ค๋ฃจ๋Š” Kyverno์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ๋“ค์€ CNCF์˜ Kyverno Certified Associate(KCA) ์ž๊ฒฉ์ฆ์˜ ์ฃผ์š” ๋‚ด์šฉ์ด๊ธฐ๋„ ํ•˜๋‹ˆ, KCA ์ž๊ฒฉ์ฆ์— ๊ด€์‹ฌ์ด ์žˆ์œผ์‹  ๋ถ„๋“ค๋„ ์ด๋ฒˆ ์‹ค์Šต์„ ์ง„ํ–‰ํ•ด๋ณด์‹œ๋ฉด ์‹œํ—˜์— ํ•„์š”ํ•œ ์ง€์‹์„ ์–ป๋Š” ๋ฐ์— ํฐ ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์‹ค์Šต ์ค€๋น„: minikube ํด๋Ÿฌ์Šคํ„ฐ์— Kyverno ์„ค์น˜ํ•˜๊ธฐ

Kyverno CLI ์„ค์น˜

์•„๊นŒ kubectl๋กœ ์ •์ฑ… ์ƒ์„ฑ๋ถ€ํ„ฐ ์ˆ˜์ •๊นŒ์ง€ ๋ชจ๋‘ ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ–ˆ๋Š”๋ฐ, ์™œ Kyverno CLI๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ• ๊นŒ์š”?

Kyverno ์ •์ฑ…์„ ํด๋Ÿฌ์Šคํ„ฐ์— ์ง์ ‘ ์ ์šฉํ•˜๊ธฐ ์ „์— ํ…Œ์ŠคํŠธํ•˜๊ณ  ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์šฉํ•œ ๋„๊ตฌ์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ •์ฑ… YAML ํŒŒ์ผ๊ณผ ํ…Œ์ŠคํŠธ์šฉ ๋ฆฌ์†Œ์Šค YAML ํŒŒ์ผ์„ ์‚ฌ์šฉํ•ด์„œ ํ•ด๋‹น ์ •์ฑ…์ด ์˜๋„ํ•œ ๋Œ€๋กœ ๋™์ž‘ํ•˜๋Š”์ง€ ๋ฏธ๋ฆฌ ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ฑฐ๋“ ์š”.

Kyverno CLI๋Š” ๋กœ์ปฌ์— ์ง์ ‘ ์„ค์น˜ํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ, Krew๋ฅผ ํ†ตํ•ด kubectl์˜ ํ”Œ๋Ÿฌ๊ทธ์ธ ํ˜•ํƒœ๋กœ ์„ค์น˜๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

Krew๊ฐ€ ๋ญ”์ง€, ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๋Š”์ง€ ๊ถ๊ธˆํ•˜์‹œ๋‹ค๋ฉด Aiden's Lab์˜ krew ํ•ธ์ฆˆ์˜จ ๊ฐ€์ด๋“œ์—์„œ ํ™•์ธํ•ด๋ณด์„ธ์š”.

Krew๊ฐ€ ์ด๋ฏธ ์„ค์น˜๋˜์–ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ์ง„ํ–‰ํ• ๊ฒŒ์š”. kubectl ํ”Œ๋Ÿฌ๊ทธ์ธ ํ˜•ํƒœ๋กœ Kyverno CLI๋ฅผ ์„ค์น˜ํ•˜๋ ค๋ฉด ์•„๋ž˜ Krew ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

kubectl krew install kyverno

๊ทธ๋ฆฌ๊ณ  ์•„๋ž˜ ๋ช…๋ น์–ด๋กœ Kyverno CLI๊ฐ€ ์ž˜ ์„ค์น˜๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

kubectl kyverno version

Kyverno CLI๋ฅผ Krew๋กœ ์„ค์น˜ํ•˜๋‹ˆ ์‚ฌ์šฉํ•˜๊ธฐ๋„ ๊ฐ„๋‹จํ•˜์ฃ ?

์ด์ œ Kyverno ๋™์ž‘์— ํ•„์š”ํ•œ ๋ฆฌ์†Œ์Šค๋“ค์„ Kubernetes ํด๋Ÿฌ์Šคํ„ฐ์— ๋ฐฐํฌํ•  ์ฐจ๋ก€์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด๋ฒˆ์—๋„ ๋น ๋ฅธ ํด๋Ÿฌ์Šคํ„ฐ ๊ตฌ์„ฑ์„ ์œ„ํ•ด minikube๋ฅผ ์‚ฌ์šฉํ•  ๊ฒ๋‹ˆ๋‹ค.

minikube๋ฅผ ์„ค์น˜ํ•˜๊ณ  Kubernetes ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๋ฐ์— ์•„์ง ์ต์ˆ™์น˜ ์•Š์•„๋„ ๊ฑฑ์ •๋งˆ์„ธ์š”. minikube ์†Œ๊ฐœ๋ถ€ํ„ฐ ์„ค์น˜, ํ™œ์šฉ๋ฒ•๊นŒ์ง€ ์ž์„ธํžˆ ๋‹ค๋ฃฌ Aiden's Lab์˜ minikube ํ•ธ์ฆˆ์˜จ ๊ฐ€์ด๋“œ๋ฅผ ๋ณด์‹œ๋ฉด ๊ธˆ๋ฐฉ ๋”ฐ๋ผ์˜ค์‹ค ์ˆ˜ ์žˆ์„ ๊ฒ๋‹ˆ๋‹ค.

๊ทธ๋Ÿผ ๋ฐ”๋กœ ๋‹ค์Œ ๋‹จ๊ณ„๋กœ ๋„˜์–ด๊ฐ€๋ด…์‹œ๋‹ค.

minikube ํด๋Ÿฌ์Šคํ„ฐ์—์„œ Helm์œผ๋กœ Kyverno ๋ฐฐํฌ

์šฐ๋ฆฌ๋Š” Kyverno๋ฅผ ํด๋Ÿฌ์Šคํ„ฐ์— ๋ฐฐํฌํ•  ๋•Œ Helm์„ ์‚ฌ์šฉํ•  ๊ฒ๋‹ˆ๋‹ค. ์•„๋งˆ ์•„์‹œ๋Š” ๋ถ„๋“ค์ด ๊ณ„์‹œ๊ฒ ์ง€๋งŒ, Helm์€ Kubernetes์— ๋ฐฐํฌ๋˜๋Š” ํ”„๋กœ์ ํŠธ์˜ ๊ฐ ๋ฆฌ์†Œ์Šค์˜ YAML ํŒŒ์ผ์„ ๋กœ์ปฌ์— ์ €์žฅํ•˜์ง€ ์•Š๊ณ ๋„ ์›๊ฒฉ์—์„œ ๋ถˆ๋Ÿฌ์™€ CLI ํ™˜๊ฒฝ์—์„œ ์ƒ์„ฑ, ๋ฒ„์ „ ๊ด€๋ฆฌ, ๊ณต์œ ๊นŒ์ง€ ํ•  ์ˆ˜ ์žˆ๋Š” Kubernetes ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ € ํˆด์ž…๋‹ˆ๋‹ค.

Helm์„ ์‚ฌ์šฉํ•˜๋ฉด Kyverno๋ฅผ ํด๋Ÿฌ์Šคํ„ฐ์— ๊ฐ„ํŽธํ•˜๊ฒŒ ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ์š”. Kyverno์˜ ๊ณต์‹ ๋ฌธ์„œ์—์„œ๋„ ์ด์ฒ˜๋Ÿผ ๊ถŒ์žฅํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ, ์ €ํฌ๋„ Helm์œผ๋กœ Kyverno๋ฅผ ๋ฐฐํฌํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋งŒ์•ฝ ์‹ค์Šต ํ™˜๊ฒฝ์— Helm์ด ์„ค์น˜๋˜์–ด ์žˆ์ง€์•Š๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด Helm์„ ๋จผ์ € ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค. (Ubuntu ํ™˜๊ฒฝ ๊ธฐ์ค€)

curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

๊ทธ๋ฆฌ๊ณ  ์•„๋ž˜์™€ ๊ฐ™์ด Helm ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์—ฌ minikube ํด๋Ÿฌ์Šคํ„ฐ์— Kyverno๋ฅผ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค.

helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo update
helm install kyverno kyverno/kyverno -n kyverno --create-namespace

๋ฐฐํฌ๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด Kyverno์˜ ๊ตฌ์„ฑ์š”์†Œ๋“ค์ด ์ •์ƒ์ ์œผ๋กœ ์‹คํ–‰ ์ค‘์ธ์ง€ ํ™•์ธํ•ด์•ผ ํ•˜๋Š”๋ฐ์š”. kubectl -n kyverno get pods ๋ช…๋ น์–ด๋กœ ํ˜„์žฌ ๋ฐฐํฌ๋œ ๋ชจ๋“  Kyverno ๊ด€๋ จ Pod์˜ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ๋ณด๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์•„๋ž˜์™€ ๊ฐ™์ด Kyverno ๊ด€๋ จ Pod๊ฐ€ ๋ชจ๋‘ READY ์ƒํƒœ์ด๋ฉด์„œ STATUS๋„ Running์ด๋ฏ€๋กœ, Kyverno ๊ตฌ์„ฑ์š”์†Œ๋“ค์ด ๋ชจ๋‘ ์ž˜ ๋™์ž‘ ์ค‘์ธ ๊ฑธ ์•Œ ์ˆ˜ ์žˆ๋„ค์š”.

Kyverno CLI ์„ค์น˜์™€ Kyverno ๋ฐฐํฌ๊ฐ€ ๋ชจ๋‘ ์™„๋ฃŒ๋˜์—ˆ์œผ๋‹ˆ, ์ด์ œ Kyverno์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ ์‹ค์Šต์„ ์‹œ์ž‘ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ๊ธฐ๋Šฅ ์‹ค์Šต 1 - ๋ฆฌ์†Œ์Šค ์ƒ์„ฑ ๊ทœ์น™ ๊ฒ€์ฆ(Validate)

validate ๊ทœ์น™์€ ์ •์˜๋œ ์ •์ฑ…์„ ์œ„๋ฐ˜ํ•˜๋Š” ๋ฆฌ์†Œ์Šค ์š”์ฒญ์„ ์ฐจ๋‹จํ•˜์—ฌ Kubernetes ํด๋Ÿฌ์Šคํ„ฐ์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ณ , ์ž ์žฌ์ ์ธ ๋ณด์•ˆ ์œ„ํ—˜๋„ ์ค„์—ฌ์ค๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, '๋ชจ๋“  Pod๋Š” non-root ์œ ์ €๋กœ ์‹คํ–‰ํ•ด์•ผ ํ•œ๋‹ค'๊ฑฐ๋‚˜, '๋ชจ๋“  Ingress๋Š” HTTPS๋งŒ ํ—ˆ์šฉํ•ด์•ผ ํ•œ๋‹ค'์™€ ๊ฐ™์€ ๋ณด์•ˆ ๋ชจ๋ฒ”์‚ฌ๋ก€๋ฅผ ์ •์ฑ…์œผ๋กœ ๋งŒ๋“ค์–ด ๊ฐ•์ œํ•  ์ˆ˜ ์žˆ์ฃ . ๋˜ํ•œ, '๋ชจ๋“  ๋ฆฌ์†Œ์Šค์—๋Š” owner ๋ ˆ์ด๋ธ”์ด ์žˆ์žˆ์–ด์•ผ ํ•œ๋‹ค'์™€ ๊ฐ™์ด ์กฐ์ง ๋‚ด๋ถ€์˜ ๊ด€๋ฆฌ ํ‘œ์ค€์„ ์ ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿผ ์ด์ œ validate ๊ทœ์น™์„ ํฌํ•จํ•˜๋Š” Kyverno์˜ ClusterPolicy๋ฅผ ์ง์ ‘ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์€ ์š”๊ตฌ์‚ฌํ•ญ์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณผ๊ฒŒ์š”.

  • ํด๋Ÿฌ์Šคํ„ฐ์— ์ƒ์„ฑ๋˜๋Š” ๋ชจ๋“  Pod์—๋Š” ๋ฐ˜๋“œ์‹œ test-for-kyverno/name ๋ ˆ์ด๋ธ”์ด ํฌํ•จ๋˜์–ด์•ผ ํ•จ

  • ๋ณธ ์ •์ฑ… ์œ„๋ฐ˜ ์‹œ ๋ฆฌ์†Œ์Šค ์ƒ์„ฑ ์ฐจ๋‹จ

๊ทธ๋ฆฌ๊ณ  ํ•ด๋‹น ์š”๊ตฌ์‚ฌํ•ญ์„ ์ถฉ์กฑํ•˜๊ธฐ ์œ„ํ•œ ClusterPolicy ์˜ˆ์ œ ์ฝ”๋“œ(require-label.yaml)๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-label
spec:
  validationFailureAction: Enforce # ์ •์ฑ… ์œ„๋ฐ˜ ์‹œ ๋ฆฌ์†Œ์Šค ์ƒ์„ฑ์„ ์ฐจ๋‹จ
  rules:
    - name: check-for-name-label
      match:
        resources: # ์ •์ฑ…์ด ์ ์šฉ๋  ๋ฆฌ์†Œ์Šค ์ข…๋ฅ˜ ์ง€์ •
          kinds:
            - Pod
      validate:
        message: "Pod์—๋Š” ๋ฐ˜๋“œ์‹œ test-for-kyverno/name ๋ ˆ์ด๋ธ”์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค."
        pattern:
          metadata:
            labels:
              test-for-kyverno/name: "?*" # ์ด ๋ ˆ์ด๋ธ”์˜ ์กด์žฌ ์—ฌ๋ถ€๋งŒ ๊ฒ€์‚ฌ

๊ทธ๋ฆฌ๊ณ  ์•„๋ž˜ ๋‘ Deployment YAML ์˜ˆ์ œ๋Š” ๊ฐ๊ฐ ์œ„ ์ •์ฑ…์— ์œ„๋ฐ˜ ๋ฐ ํ†ต๊ณผ๋˜๋Š” ํ…Œ์ŠคํŠธ์šฉ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

์ •์ฑ…์— ์œ„๋ฐ˜๋˜๋Š” Deployment(test-validate-fail.yaml):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-deployment-fail
  namespace: kyverno-demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-test-app
  template:
    metadata:
      # 'test-for-kyverno/name' ๋ ˆ์ด๋ธ”์ด ์—†์œผ๋ฏ€๋กœ validate ์ •์ฑ…์— ์˜ํ•ด ์ƒ์„ฑ ๊ฑฐ๋ถ€
      labels:
        app: my-test-app
    spec:
      containers:
      - name: nginx
        image: nginx:latest

์ •์ฑ…์„ ๋”ฐ๋ฅด๋Š” Deployment(test-validate-success.yaml):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-deployment-success
  namespace: kyverno-demo
spec:
  replicas: 1
  selector:
    matchLabels:
      test-for-kyverno/name: my-successful-app
  template:
    metadata:
      # 'test-for-kyverno/name' ๋ ˆ์ด๋ธ”์ด ์žˆ์œผ๋ฏ€๋กœ validate ์ •์ฑ… ํ†ต๊ณผ
      labels:
        test-for-kyverno/name: my-successful-app
    spec:
      containers:
      - name: nginx
        image: nginx:latest

ํ…Œ์ŠคํŠธ์šฉ Deployment YAML ์ฝ”๋“œ์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋“ฏ์ด, ์šฐ๋ฆฌ๊ฐ€ ํ…Œ์ŠคํŠธํ•  ๋ฆฌ์†Œ์Šค๋“ค์€ kyverno-demo Namespace์— ๋ฐฐํฌํ•  ์˜ˆ์ •์ด๋ฏ€๋กœ kubectl create ns kyverno-demo ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•ด์„œ ํ•ด๋‹น Namespace๋ฅผ ๋จผ์ € ์ƒ์„ฑํ•ด์ฃผ์„ธ์š”.

์ €๋Š” ์‹ค์Šต์„ ์œ„ํ•ด ๋ณ„๋„์˜ ํด๋”๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ์ •์ฑ… ์˜ˆ์ œ ์ฝ”๋“œ๋Š” ๋ชจ๋‘ policies ํด๋”์— ์ €์žฅํ–ˆ๊ณ , ํ…Œ์ŠคํŠธ์šฉ ๋ฆฌ์†Œ์Šค ํŒŒ์ผ๋“ค์€ ๋˜ ๋‹ค๋ฅธ resources ํด๋” ์•ˆ์— ์ €์žฅํ–ˆ๋Š”๋ฐ์š”. ์ด์ œ ์‹ค์ œ๋กœ ์ •์ฑ…์„ ๋ฐฐํฌํ•˜๊ธฐ ์ „์—, ์•„๋ž˜ Kyverno CLI ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด ์ •์ฑ…์ด ์–ด๋–ป๊ฒŒ ์ ์šฉ๋˜๋Š”์ง€ ํ…Œ์ŠคํŠธํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

kubectl kyverno apply {Policy ํŒŒ์ผ๋ช…} -r {ํ…Œ์ŠคํŠธ ๋ฆฌ์†Œ์Šค ๊ฒฝ๋กœ}

์œ„ ๋ช…๋ น์–ด ๋งˆ์ง€๋ง‰์— -t ์˜ต์…˜์„ ์ฃผ๋ฉด, ์•„๋ž˜์™€ ๊ฐ™์ด ์ •์ฑ… ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ๊ฐ€ ํ‘œ ํ˜•์‹์œผ๋กœ ๋ณด๊ธฐ ์‰ฝ๊ฒŒ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๊ฐ€ ์˜๋„ํ•œ ๋Œ€๋กœ, test-validate-fail.yaml ๋ฆฌ์†Œ์Šค๋Š” ์ •์ฑ… ์œ„๋ฐ˜, test-validate-success.yaml ๋ฆฌ์†Œ์Šค๋Š” ์ •์ฑ… ํ†ต๊ณผ๋ผ๋Š” ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ค๊ณ  ์žˆ๋„ค์š”. ๊ทธ๋Ÿผ ์ด์ œ ์‹ค์ œ๋กœ ํด๋Ÿฌ์Šคํ„ฐ์— ์ •์ฑ…์„ ๋ฐฐํฌํ•œ ๋‹ค์Œ, ํ…Œ์ŠคํŠธ์šฉ ๋ฆฌ์†Œ์Šค๋“ค๋„ ๋ฐฐํฌํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋จผ์ € ์•„๋ž˜ ๋ช…๋ น์–ด๋กœ require-label.yaml ์ •์ฑ…์„ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค.

โš ๏ธClusterPolicy ์ ์šฉ ์ฃผ์˜!

์•ž์œผ๋กœ ๋ฐฐํฌํ•  Kyverno์˜ ClusterPolicy๋Š” ํด๋Ÿฌ์Šคํ„ฐ์— ๋ฐฐํฌ๋œ ์ „์ฒด Pod์— ํŠน์ • ๋ ˆ์ด๋ธ”์ด ํฌํ•จ๋˜๋„๋ก ๊ฐ•์ œํ•˜๋ฏ€๋กœ ๋ฐ˜๋“œ์‹œ ์‹ค์Šต์šฉ ํด๋Ÿฌ์Šคํ„ฐ์—์„œ ์ง„ํ–‰ํ•ด์ฃผ์„ธ์š”.

ํ•ด๋‹น ํด๋Ÿฌ์Šคํ„ฐ์— ์ด๋ฏธ ๋‹ค๋ฅธ Pod๊ฐ€ ์‹คํ–‰ ์ค‘์ด๋ผ๋ฉด ClusterPolicy์˜ ์˜ํ–ฅ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

kubectl apply -f policies/require-label.yaml

kubectl๋กœ ๋ฐฐํฌํ•œ Kyverno์˜ ClusterPolicy๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ์กฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ ๋‹ค์Œ, ์•„๊นŒ Kyverno CLI ํ…Œ์ŠคํŠธ ๋•Œ ์ •์ฑ…์— ์œ„๋ฐ˜๋˜์—ˆ๋˜ test-validate-fail.yaml ๋ฆฌ์†Œ์Šค๋ฅผ kubectl apply ๋ช…๋ น์–ด๋กœ ๋ฐฐํฌํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ณด์ด๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ฆฌ์†Œ์Šค ๋ฐฐํฌ๊ฐ€ ๋ง‰ํ˜”์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ํ•ด๋‹น validate์˜ message ํ•„๋“œ์— ์ง€์ •ํ–ˆ๋˜ ์•ˆ๋‚ด ๋ฉ”์‹œ์ง€๋„ ํ•จ๊ป˜ ๋‚˜์˜ค๊ณ  ์žˆ๋„ค์š”! ์ด๋ ‡๊ฒŒ Kyverno์˜ validate ๊ทœ์น™์€ ๋ฆฌ์†Œ์Šค ์ƒ์„ฑ ์ „ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ •์ฑ…์— ์œ„๋ฐ˜๋˜๋Š” ์‚ฌํ•ญ์„ ์•Œ๋ ค์ฃผ๊ณ , ์ •์ฑ…์„ ๋”ฐ๋ฅด๋„๋ก ์œ ๋„ํ•˜๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ๊ธฐ๋Šฅ ์‹ค์Šต 2 - ๋ฆฌ์†Œ์Šค ์ž๋™ ์ˆ˜์ •(Mutate)

๋‹ค์Œ์œผ๋กœ ์•Œ์•„๋ณผ ๊ทœ์น™์€ mutate์ž…๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž๋‚˜ ์šด์˜์ž๊ฐ€ Kubernetes ํด๋Ÿฌ์Šคํ„ฐ์— ๋ฆฌ์†Œ์Šค๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ํ•„์š”ํ•œ ํŠน์ • ํ•„๋“œ๋ฅผ ๋ช…์‹œํ•˜์ง€ ์•Š์•˜์„ ๊ฒฝ์šฐ, mutate ๊ทœ์น™์„ ํ†ตํ•ด ์ž๋™์œผ๋กœ ๊ธฐ๋ณธ๊ฐ’์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ์š”.

์˜ˆ๋ฅผ ๋“ค๋ฉด Pod์˜ imagePullPolicy ํ•„๋“œ ๊ฐ’์ด ๋ช…์‹œ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด IfNotPresent ๊ฐ’์„ ์ž๋™์œผ๋กœ ๋„ฃ์–ด์ฃผ๊ฑฐ๋‚˜, ๋ชจ๋“  Pod์— resouces/requests ๊ฐ’์„ ์ž๋™์œผ๋กœ ์ถ”๊ฐ€ํ•˜๋Š” ๋“ฑ์˜ ์ž‘์—…์ด ๊ฐ€๋Šฅํ•œ ๊ฑฐ์ฃ . ํด๋Ÿฌ์Šคํ„ฐ์˜ ์•ˆ์ •์„ฑ๊ณผ ์ž์› ํšจ์œจ์„ฑ์„ ๋†’์ด๊ธฐ ์œ„ํ•ด ํ™œ์šฉ๋˜๋Š” ๊ทœ์น™์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿผ mutate ๊ทœ์น™์„ ์‹ค์Šตํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์€ ์š”๊ตฌ์‚ฌํ•ญ์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณผ๊ฒŒ์š”.

  • ๋ชจ๋“  ํด๋Ÿฌ์Šคํ„ฐ์— ์ƒˆ๋กœ์šด Pod๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ๋งˆ๋‹ค managed-by๋ผ๋Š” ์–ด๋…ธํ…Œ์ด์…˜์ด ํ•„์ˆ˜๋กœ ์กด์žฌํ•ด์•ผ ํ•จ

  • managed-by ํ•„๋“œ์˜ ๊ธฐ๋ณธ๊ฐ’์€ kyverno

์œ„ ์š”๊ตฌ์‚ฌํ•ญ์„ ์ถฉ์กฑํ•˜๋Š” ClusterPolicy(add-annotation.yaml)๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: add-annotation-simple
spec:
  rules:
    - name: add-managed-by-annotation
      match:
        resources:
          kinds:
            - Pod
      mutate:
        patchStrategicMerge: # ์•„๋ž˜ ๋ฆฌ์†Œ์Šค ๋‚ด์šฉ์„ ์ƒ์„ฑ๋  ๋ฆฌ์†Œ์Šค ๋ช…์„ธ์— ๋ณ‘ํ•ฉ
          metadata:
            annotations:
              # 'managed-by' ์–ด๋…ธํ…Œ์ด์…˜์ด ์—†์œผ๋ฉด(+) ์ง€์ • ๊ฐ’(kyverno)์„ ์ถ”๊ฐ€
              +(managed-by): kyverno

์•„๊นŒ 'ํ•ต์‹ฌ ๊ธฐ๋Šฅ 1'์—์„œ ์‚ฌ์šฉํ–ˆ๋˜ ํ…Œ์ŠคํŠธ์šฉ Deployment๋ฅผ ๋‹ค์‹œ ์‹ค์Šต์— ์‚ฌ์šฉํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋จผ์ € Kyverno CLI์˜ apply ๋ช…๋ น์–ด๋กœ add-annotation.yaml๋กœ ์ •์˜ํ•œ mutate ๊ทœ์น™์ด ์ •์ƒ ์ž‘๋™ํ•˜๋Š”์ง€ ํ…Œ์ŠคํŠธํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. kyverno apply ๋ช…๋ น์–ด ์–‘์‹์€ 'ํ•ต์‹ฌ ๊ธฐ๋Šฅ 1'์—์„œ ์ด๋ฏธ ์‚ดํŽด๋ดค์—ˆ์ฃ ?

๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋ฉด mutate ๊ทœ์น™์œผ๋กœ ์ธํ•ด ๋‘ ๊ฐœ์˜ Deployment ๋ชจ๋‘ managed-by ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ kyverno ๊ฐ’์ด ์ž๋™์œผ๋กœ ๋“ค์–ด๊ฐ€๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฐธ๊ณ ๋กœ, kyverno apply๋Š” ํ„ฐ๋ฏธ๋„์ƒ์—์„œ ๋™์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์šฐ๋ฆฌ๊ฐ€ ์‹คํ–‰ํ•œ ๋ช…๋ น์–ด๋กœ ์‹ค์ œ Deployment YAML ํŒŒ์ผ์ด ์ˆ˜์ •๋œ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค.

์ด์ œ ํ•ด๋‹น ClusterPolicy๋ฅผ ์‹ค์Šต์šฉ ํด๋Ÿฌ์Šคํ„ฐ์— ๋ฐฐํฌ ํ›„, test-validate-success.yaml ํŒŒ์ผ์˜ Deployment๋ฅผ ๋ฐฐํฌํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. (์šฐ๋ฆฌ๊ฐ€ ์ด๋ฏธ require-label ClusterPolicy๋ฅผ ํด๋Ÿฌ์Šคํ„ฐ์— ๋ฐฐํฌํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— test-validate-fail.yaml์˜ Deployment๋Š” test-for-kyverno/name label์„ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š๋Š” ์ด์ƒ ๋ฐฐํฌํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.)

๋จผ์ € add-annotation.yaml ํŒŒ์ผ์˜ ์ •์ฑ…์„ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  test-validate-success.yaml ํŒŒ์ผ์˜ Deployment๋ฅผ ๋ฐฐํฌํ•œ ๋‹ค์Œ, kubectl describe ๋ช…๋ น์–ด๋กœ ๋ฐฐํฌ๋œ Deployment์˜ ๋ช…์„ธ๋ฅผ ํ™•์ธํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ ์˜ˆ์ œ YAML ํŒŒ์ผ์—๋Š” managed-by ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ช…์‹œ๋˜์ง€ ์•Š์•˜๋‹ค๋Š” ์  ๊ธฐ์–ตํ•ด์ฃผ์„ธ์š”!

test-validate-success.yaml์˜ Deployment๊ฐ€ ์ •์ƒ ๋ฐฐํฌ๋˜์—ˆ๊ณ , managed-by ์–ด๋…ธํ…Œ์ด์…˜์˜ kyverno ๊ฐ’์ด ์ž๋™์œผ๋กœ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค! ์ด๋ ‡๊ฒŒ mutate ๊ทœ์น™์œผ๋กœ Kubernetes ๋ฆฌ์†Œ์Šค์— ๊ผญ ๋ช…์‹œ๋˜์–ด์•ผ ํ•˜๋Š” ํ•„๋“œ์˜ ๊ธฐ๋ณธ๊ฐ’์„ ์ž๋™์œผ๋กœ ์ถ”๊ฐ€ํ•˜์—ฌ ๋ฆฌ์†Œ์Šค ๋ช…์„ธ์˜ ์ผ๊ด€์„ฑ์„ ๋ณด์žฅํ•  ์ˆ˜ ์žˆ์Œ์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ๊ธฐ๋Šฅ 3 - ํ•„์ˆ˜ ๋ฆฌ์†Œ์Šค ์ž๋™ ์ƒ์„ฑ(Generate)

๋งˆ์ง€๋ง‰์œผ๋กœ Kyverno์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ generate ๊ทœ์น™์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ํŠน์ • ๋ฆฌ์†Œ์Šค๊ฐ€ ์ƒ์„ฑ๋  ๊ฒฝ์šฐ, ํ•„์š”ํ•˜์ง€๋งŒ ์ง์ ‘ ์ƒ์„ฑํ•˜๊ธฐ์—” ๋ฐ˜๋ณต ์ž‘์—…์ด ๋  ์ˆ˜ ์žˆ๋Š” ๋‹ค๋ฅธ ๋ฆฌ์†Œ์Šค๋“ค์„ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” ๊ธฐ๋Šฅ์ธ๋ฐ์š”.

์˜ˆ๋ฅผ ๋“ค๋ฉด ์ƒˆ๋กœ์šด ์‚ฌ์šฉ์ž๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ๋งˆ๋‹ค ํ•ด๋‹น ์‚ฌ์šฉ์ž๋ฅผ ์œ„ํ•œ ๊ธฐ๋ณธ Role๊ณผ RoleBinding์„ ์ž๋™์œผ๋กœ ๋งŒ๋“ค์–ด ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ณต์žกํ•œ ์„ค์ • ๊ณผ์ •์„ ์ž๋™ํ™”ํ•˜๋ฉด์„œ ์ผ๊ด€์„ฑ๋„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์–ด ์œ ์šฉํ•œ ๊ทœ์น™์ž…๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ์•„๋ž˜ ์š”๊ตฌ์‚ฌํ•ญ์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณผ๊ฒŒ์š”.

  • ์ƒˆ๋กœ์šด Namespace๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ๋งˆ๋‹ค ํ•ด๋‹น Namespace๋ฅผ ์œ„ํ•œ NetworkPolicy ์ž๋™ ์ƒ์„ฑ

  • ์ด NetworkPolicy๋Š” ํ•ด๋‹น Namespace์— ์†ํ•  ๋ชจ๋“  Pod์˜ ์™ธ๋ถ€๋กœ ํ–ฅํ•˜๋Š” ํ†ต์‹ ์„ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ฐจ๋‹จ

์ด ์š”๊ตฌ์‚ฌํ•ญ์„ ์ถฉ์กฑํ•˜๋Š” ClusterPolicy(generate-network-policy.yaml)๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: generate-network-policy
spec:
  rules:
  - name: generate-default-deny-policy
    # Namespace ์ƒ์„ฑ์œผ๋กœ ํ•ด๋‹น ๊ทœ์น™์ด ํŠธ๋ฆฌ๊ฑฐ๋จ์„ ์ •์˜ 
    match:
      resources:
        kinds:
          - Namespace
    # ์œ„ match ์กฐ๊ฑด์ด ์ถฉ์กฑ๋˜๋ฉด ์•„๋ž˜ ๋ฆฌ์†Œ์Šค๋ฅผ ์ƒ์„ฑ
    generate:
      apiVersion: networking.k8s.io/v1
      kind: NetworkPolicy
      name: default-deny-all # ์ƒ์„ฑ๋  NetworkPolicy์˜ ์ด๋ฆ„
      namespace: "{{request.object.metadata.name}}" # ํŠธ๋ฆฌ๊ฑฐ๋œ Namespace์˜ ์ด๋ฆ„์„ ์‚ฌ์šฉ
      synchronize: true # Namespace๊ฐ€ ์‚ญ์ œ๋˜๋ฉด ์ด NetworkPolicy๋„ ํ•จ๊ป˜ ์‚ญ์ œ
      data:
        spec:
          # ํ•ด๋‹น Namespace์˜ ๋ชจ๋“  Pod์— ์ด ์ •์ฑ…์„ ์ ์šฉ
          podSelector: {}
          # ์™ธ๋ถ€๋กœ ๋‚˜๊ฐ€๋Š”(Egress) ๋ชจ๋“  ํŠธ๋ž˜ํ”ฝ์„ ์ฐจ๋‹จ
          policyTypes:
          - Egress

๊ทธ๋Ÿผ ํ•ด๋‹น ClusterPolicy๋ฅผ ๋ฐ”๋กœ ํด๋Ÿฌ์Šคํ„ฐ์— ๋ฐฐํฌํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  test-for-generate-rule์ด๋ผ๋Š” ์ด๋ฆ„์˜ Namespace๋ฅผ ๋ฐ”๋กœ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

ํ•ด๋‹น Namespace์˜ NetworkPolicy๋ฅผ ์กฐํšŒํ•ด๋ณด๋ฉด...

generate-network-policy.yaml ClusterPolicy์—์„œ ์ •์˜ํ–ˆ๋˜ default-deny-all NetworkPolicy๊ฐ€ ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค! ๊ทธ๋ฆฌ๊ณ  generate.kyverno.io/policy-name ๋ฐ generate.kyverno.io/rule-name Label์˜ ๊ฐ’์„ ๋ณด๋ฉด ์–ด๋–ค Kyverno ์ •์ฑ…๊ณผ ๊ทœ์น™์œผ๋กœ ์ธํ•ด ์ƒ์„ฑ๋˜์—ˆ๋Š”์ง€๋„ ์•Œ ์ˆ˜ ์žˆ๋„ค์š”.

์˜ˆ์ œ ์‚ฌ๋ก€์—์„œ ๋ดค๋˜ ๊ฒƒ ์ด์™ธ์—๋„, ConfigMap์ด๋‚˜ Secret ๋“ฑ ์ถ”๊ฐ€๋กœ ์ƒ์„ฑ์ด ํ•„์š”ํ•˜์ง€๋งŒ ์ž์นซํ•˜๋ฉด ๋ฐ˜๋ณต ์ž‘์—…์ด ๋  ์ˆ˜ ์žˆ๋Š” ๋ฆฌ์†Œ์Šค๋“ค ์—ญ์‹œ Kyverno์˜ generate ๊ทœ์น™์œผ๋กœ ํ•œ ๋ฒˆ์— ์ƒ์„ฑ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

๋งˆ๋ฌด๋ฆฌ

Kyverno์˜ ClusterPolicy๋Š” ํด๋Ÿฌ์Šคํ„ฐ ์ „์ฒด์— ์˜ํ–ฅ์„ ์ฃผ๋Š” ๋ฆฌ์†Œ์Šค์ด๋ฏ€๋กœ, ์‹ค์Šต์šฉ ํด๋Ÿฌ์Šคํ„ฐ์— ๋ฐฐํฌํ–ˆ๋˜ ์ •์ฑ…์€ ๋ชจ๋‘ ์ œ๊ฑฐํ•  ๊ฒƒ์„ ๊ถŒํ•ด๋“œ๋ฆฝ๋‹ˆ๋‹ค. Kubernetes ๊ฒฝํ—˜์ด ์žˆ์œผ์‹œ๋‹ค๋ฉด ์ต์ˆ™ํ•œ kubectl delete ๋ช…๋ น์–ด๋กœ ํ•œ ๋ฒˆ์— ์ œ๊ฑฐ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

kubectl delete clusterpolicy require-label add-annotation-simple generate-network-policy

์ง€๊ธˆ๊นŒ์ง€ Kyverno์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ์ด์ž ๊ทœ์น™ 3๊ฐ€์ง€๋ฅผ ์ž์„ธํžˆ ์‚ดํŽด๋ณด๊ณ  ์‹ค์Šต๊นŒ์ง€ ์ง„ํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค. validate, mutate, generate ๊ทœ์น™์€ ๋…๋ฆฝ์ ์œผ๋กœ๋„ ๊ฐ•๋ ฅํ•˜์ง€๋งŒ, ์„œ๋กœ ์กฐํ•ฉํ•˜์—ฌ ์‚ฌ์šฉ๋  ๋•Œ ๋”์šฑ ์ •๊ตํ•˜๊ณ  ํšจ๊ณผ์ ์ธ ์ •์ฑ…์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ์š”.

ํŠน์ • ๋ฆฌ์†Œ์Šค๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ mutate๋กœ ๊ธฐ๋ณธ๊ฐ’์„ ์ถ”๊ฐ€ํ•˜๊ณ , validate๋กœ ๋‹ค๋ฅธ ํ•„์ˆ˜ ์กฐ๊ฑด์„ ๊ฒ€์ฆํ•œ ๋’ค, generate๋กœ ๊ด€๋ จ๋œ ๋ณด์กฐ ๋ฆฌ์†Œ์Šค๋ฅผ ํ•จ๊ป˜ ์ƒ์„ฑํ•˜๋Š” ๋ณตํ•ฉ ์‹œ๋‚˜๋ฆฌ์˜ค ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•œ ๊ฒƒ์ด์ฃ . ์ด๋ฒˆ ๊ธ€์€ Kyverno๋ฅผ ๋ง‰ ์‹œ์ž‘ํ•œ ๋ถ„๋“ค์„ ์œ„ํ•ด ์ž‘์„ฑํ•œ ๊ฒƒ์ด์–ด์„œ ์ด๋Ÿฐ ์‹ฌํ™” ์‹œ๋‚˜๋ฆฌ์˜ค๊นŒ์ง€ ์ง„ํ–‰ํ•˜์ง„ ๋ชปํ–ˆ์ง€๋งŒ, ์ถ”ํ›„์— ๋‹ค๋ค„๋ณผ ๊ธฐํšŒ๊ฐ€ ์žˆ์œผ๋ฉด ์ข‹๊ฒ ์Šต๋‹ˆ๋‹ค.

์ด๋ฒˆ ์‹ค์Šต ๊ฐ€์ด๋“œ๋ฅผ ๋”ฐ๋ผํ•˜์‹œ๋ฉด์„œ ์–ด๋А์ƒˆ Kyverno์™€ Policy as Code์— ๋Œ€ํ•œ ๊ธฐ๋ณธ ์ง€์‹์„ ์ตํžˆ์…จ์„ ๊ฑฐ๋ž€ ์ƒ๊ฐ์ด ๋“ญ๋‹ˆ๋‹ค. ํ˜น์‹œ ์ด๋ฒˆ ์ฃผ์ œ์™€ ๊ด€๋ จํ•ด์„œ ์ข€ ๋” ๋‹ค๋ค˜์œผ๋ฉด ํ•˜๋Š” ๋‚ด์šฉ์ด๋‚˜ ๊ถ๊ธˆํ•œ ์ ์ด ์žˆ๋‹ค๋ฉด ์–ธ์ œ๋“  ์•„๋ž˜ ํ”ผ๋“œ๋ฐฑ ์–‘์‹์— ๋‚จ๊ฒจ์ฃผ์„ธ์š”.

๊ทธ๋Ÿผ ๋‹ค์Œ์— ๋” ํฅ๋ฏธ๋กœ์šด ์ฃผ์ œ๋กœ ์ฐพ์•„์˜ค๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

โœจ์ด๋ฒˆ ๋‰ด์Šค๋ ˆํ„ฐ๋Š” ์–ด๋– ์…จ๋‚˜์š”?

์ด๋ฒˆ ๊ธ€์—์„œ ๋‹ค๋ฃฌ ์ฃผ์ œ์— ๋Œ€ํ•ด ์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•˜๋Š”์ง€ ์•Œ๋ ค์ฃผ์„ธ์š”! ๋‰ด์Šค๋ ˆํ„ฐ๋ฅผ ๋” ๋‚˜์€ ๋ฐฉํ–ฅ์œผ๋กœ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด ์•„๋ž˜ ํผ์—์„œ ์งง์€ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ›๊ณ  ์žˆ์–ด์š”.

๐Ÿ‘‰ ํ”ผ๋“œ๋ฐฑ ๋ณด๋‚ด๊ธฐ (1~2๋ถ„ ์†Œ์š”)

์—ฌ๋Ÿฌ๋ถ„๋“ค์˜ ์†Œ์ค‘ํ•œ ์˜๊ฒฌ์€ Aidenโ€™s Lab ๋‰ด์Šค๋ ˆํ„ฐ์—๊ฒŒ ํฐ ํž˜์ด ๋ฉ๋‹ˆ๋‹ค!

๐Ÿ”ญAidenโ€™s Lab์—์„œ ๋” ๋งŽ์€ ์•„ํ‹ฐํด์„ ๋งŒ๋‚˜๋ณด์„ธ์š”

๋ฐœํ–‰๋œ ๋‰ด์Šค๋ ˆํ„ฐ๋ฅผ ์•„์นด์ด๋น™ํ•˜๊ณ  ๋‹ค์–‘ํ•œ ์ •๋ณด๋ฅผ ๊ณต์œ ํ•˜๋Š” ๊ธฐ์ˆ  ๋ธ”๋กœ๊ทธ๋ฅผ ์šด์˜ ์ค‘์ž…๋‹ˆ๋‹ค.