CI ํŒŒ์ดํ”„๋ผ์ธ์˜ ํšŒ์‚ฌ ์ •์ฑ…์— ๋”ฐ๋ผ ์•ฑ ๊ฒ€์ฆ

์กฐ์ง์—์„œ ์ •์ฑ… ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Google Kubernetes Engine(GKE) Enterprise ๋ฒ„์ „ ํด๋Ÿฌ์Šคํ„ฐ ๊ฐ„์˜ ์ •์ฑ…์„ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒฝ์šฐ ์ง€์†์  ํ†ตํ•ฉ(CI) ํŒŒ์ดํ”„๋ผ์ธ์—์„œ ํ•ด๋‹น ๋ฐฐํฌ ๊ตฌ์„ฑ์„ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํŠœํ† ๋ฆฌ์–ผ์—์„œ๋Š” ์ด ๊ฒฐ๊ณผ๋ฅผ ์–ป๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์•ฑ์˜ CI ํŒŒ์ดํ”„๋ผ์ธ์„ ๋นŒ๋“œํ•˜๋Š” ๊ฐœ๋ฐœ์ž์ด๊ฑฐ๋‚˜ ์—ฌ๋Ÿฌ ์•ฑํŒ€์„ ์œ„ํ•œ CI ํŒŒ์ดํ”„๋ผ์ธ ํ…œํ”Œ๋ฆฟ์„ ๋นŒ๋“œํ•˜๋Š” ํ”Œ๋žซํผ ์—”์ง€๋‹ˆ์–ด๋ผ๋ฉด ์•ฑ ๊ฒ€์ฆ์ด ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๋Š” ๊ฐ์‚ฌ ๋˜๋Š” ์‹œํ–‰ ์ž๋™ํ™”๋ฅผ ์ œ๊ณตํ•˜๊ณ  ์œ ์ง€ํ•˜์—ฌ ํด๋ผ์šฐ๋“œ ํ”Œ๋žซํผ ๋‚ด์—์„œ ์‹คํ–‰๋˜๋Š” ๋ชจ๋“  ๋ฆฌ์†Œ์Šค๊ฐ€ ์กฐ์ง์˜ ๊ทœ์ • ์ค€์ˆ˜ ์š”๊ตฌ์‚ฌํ•ญ์„ ์ถฉ์กฑํ•˜๋„๋ก ๋ณด์žฅํ•˜๊ณ  ๊ธฐ๋ณธ ๊ธฐ์ˆ  ์ธํ”„๋ผ์˜ ์ˆ˜๋ช… ์ฃผ๊ธฐ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” IT ๊ด€๋ฆฌ์ž์™€ ์šด์˜์ž๋ฅผ ์œ„ํ•ด ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.Google Cloud ์ฝ˜ํ…์ธ ์—์„œ ์ฐธ์กฐํ•˜๋Š” ์ผ๋ฐ˜์ ์ธ ์—ญํ•  ๋ฐ ์˜ˆ์‹œ ํƒœ์Šคํฌ์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ณด๋ ค๋ฉด ์ผ๋ฐ˜ GKE ์‚ฌ์šฉ์ž ์—ญํ•  ๋ฐ ํƒœ์Šคํฌ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

์ •์ฑ…์€ ์กฐ์ง์˜ ๋ณด์•ˆ๊ณผ ๊ทœ์ • ์ค€์ˆ˜์—์„œ ์ค‘์š”ํ•œ ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค. ์ •์ฑ… ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์กฐ์ง์ด ๋ชจ๋“  ํด๋Ÿฌ์Šคํ„ฐ์— ๋Œ€ํ•ด ์ด๋Ÿฌํ•œ ์ •์ฑ…์„ ์ค‘์•™์—์„œ ์„ ์–ธ์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž๋Š” ์ด๋Ÿฌํ•œ ์ •์ฑ…์˜ ์ค‘์•™ ์ง‘์ค‘์‹ ์„ ์–ธ์  ํŠน์„ฑ์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ ์›Œํฌํ”Œ๋กœ์—์„œ ์ด๋Ÿฌํ•œ ํŠน์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ€๋Šฅํ•œ ํ•œ ๋นจ๋ฆฌ ์ด๋Ÿฌํ•œ ์ •์ฑ…์— ๋Œ€ํ•ด ์•ฑ ์œ ํšจ์„ฑ์„ ๊ฒ€์‚ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐฐํฌ ์ค‘ ๋Œ€์‹ ์— CI ํŒŒ์ดํ”„๋ผ์ธ์˜ ์ •์ฑ… ์œ„๋ฐ˜์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๋Š” ๊ฒƒ์€ ๋‘ ๊ฐ€์ง€ ์ฃผ์š” ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๊ฐœ๋ฐœ ์ดˆ๊ธฐ๋ถ€ํ„ฐ ๋ณด์•ˆ ๋ฌธ์ œ๋ฅผ ๋ฐ˜์˜ํ•˜๊ณ , ํ”ผ๋“œ๋ฐฑ ๋ฃจํ”„๋ฅผ ๊ฐ•ํ™”ํ•˜๊ณ , ์ด๋Ÿฌํ•œ ์œ„๋ฐ˜์‚ฌํ•ญ์„ ์ˆ˜์ •ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ์‹œ๊ฐ„๊ณผ ๋น„์šฉ์„ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ํŠœํ† ๋ฆฌ์–ผ์—์„œ๋Š” Cloud Build๋ฅผ CI ๋„๊ตฌ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ๋ฐ๋ชจ์šฉ ์ •์ฑ…์ด ํฌํ•จ๋œ ์ƒ˜ํ”Œ GitHub ์ €์žฅ์†Œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋ฆฌ์†Œ์Šค

์ด ํŠœํ† ๋ฆฌ์–ผ์—์„œ๋Š” ์—ฌ๋Ÿฌ Kubernetes ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ์„น์…˜์—์„œ๋Š” ์ด๋Ÿฌํ•œ ๋„๊ตฌ์—๋Š” ๋ฌด์—‡์ด ์žˆ๋Š”์ง€, ์„œ๋กœ ์–ด๋–ป๊ฒŒ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š”์ง€, ๋‹ค๋ฅธ ๋„๊ตฌ๋กœ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

์ด ํŠœํ† ๋ฆฌ์–ผ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋„๊ตฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ์ •์ฑ… ์ปจํŠธ๋กค๋Ÿฌ: ์˜คํ”ˆ์†Œ์Šค ํ”„๋กœ์ ํŠธ ๊ฐœ๋ฐฉํ˜• ์ •์ฑ… ์—์ด์ „ํŠธ - Gatekeeper๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค. ์ •์ฑ… ์ปจํŠธ๋กค๋Ÿฌ๋Š” Kubernetes ํด๋Ÿฌ์Šคํ„ฐ์—์„œ ์ƒ์„ฑ๋œ ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ •์ฑ…์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค(์˜ˆ: ํŠน์ • ์˜ต์…˜์˜ ์‚ฌ์šฉ ๋ฐฉ์ง€ ๋˜๋Š” ํŠน์ • ๋ผ๋ฒจ ์‚ฌ์šฉ ์ ์šฉ). ์ด๋Ÿฌํ•œ ์ •์ฑ…์„ ์ œ์•ฝ์กฐ๊ฑด์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์ œ์•ฝ์กฐ๊ฑด์€ Kubernetes ์ปค์Šคํ…€ ๋ฆฌ์†Œ์Šค๋กœ ์ •์˜๋ฉ๋‹ˆ๋‹ค. ์ •์ฑ… ์ปจํŠธ๋กค๋Ÿฌ๋Š” Google Kubernetes Engine(GKE) Enterprise ๋ฒ„์ „์˜ ์ผ๋ถ€๋กœ ์ œ๊ณต๋˜์ง€๋งŒ ํ•ด๋‹น ๊ตฌํ˜„์— ์ •์ฑ… ์ปจํŠธ๋กค๋Ÿฌ ๋Œ€์‹  ๊ฐœ๋ฐฉํ˜• ์ •์ฑ… ์—์ด์ „ํŠธ - Gatekeeper๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • GitHub: ์ด ํŠœํ† ๋ฆฌ์–ผ์—์„œ๋Š” GitHub๋ฅผ ์‚ฌ์šฉํ•ด์„œ Git ์ €์žฅ์†Œ๋ฅผ ํ˜ธ์ŠคํŒ…ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ €์žฅ์†Œ๋Š” ์ƒ˜ํ”Œ ์•ฑ์„ ์œ„ํ•œ ์ €์žฅ์†Œ์™€ ์ •์ฑ… ์ปจํŠธ๋กค๋Ÿฌ์˜ ์ œ์•ฝ์กฐ๊ฑด์ด ํฌํ•จ๋œ ์ €์žฅ์†Œ์ž…๋‹ˆ๋‹ค. ํŽธ์˜์ƒ ๋‘ ์ €์žฅ์†Œ๋Š” ๋‹จ์ผ Git ์ €์žฅ์†Œ์˜ ์„œ๋กœ ๋‹ค๋ฅธ ํด๋” ๋‘ ๊ฐœ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ์ €์žฅ์†Œ์ž…๋‹ˆ๋‹ค. ๋ชจ๋“  Git ์†”๋ฃจ์…˜์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Cloud Build: Cloud Build๋Š” Google Cloud์˜ CI ์†”๋ฃจ์…˜์ž…๋‹ˆ๋‹ค. ์ด ํŠœํ† ๋ฆฌ์–ผ์—์„œ๋Š” ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ตฌํ˜„ ์„ธ๋ถ€์ •๋ณด๋Š” CI ์‹œ์Šคํ…œ ๊ฐ„์— ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์ง€๋งŒ ์ด ํŠœํ† ๋ฆฌ์–ผ์— ์„ค๋ช…๋œ ๊ฐœ๋…์€ ๋ชจ๋“  ์ปจํ…Œ์ด๋„ˆ ๊ธฐ๋ฐ˜ CI ์‹œ์Šคํ…œ์—์„œ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Kustomize: Kustomize๋Š” Kubernetes ๊ตฌ์„ฑ์— ์‚ฌ์šฉ๋˜๋Š” ๋งž์ถค์„ค์ • ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. '๊ธฐ๋ณธ' ๊ตฌ์„ฑ์„ ๊ฐ€์ ธ์˜ค๊ณ  ๋งž์ถค์„ค์ •์„ ์ ์šฉํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. Kubernetes ๊ตฌ์„ฑ์— ๋Œ€ํ•ด DRY(๋ฐ˜๋ณต ๊ธˆ์ง€) ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Kustomize๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ธฐ๋ณธ ๊ตฌ์„ฑ์˜ ๋ชจ๋“  ํ™˜๊ฒฝ์— ๊ณตํ†ต์ ์ธ ์š”์†Œ๋ฅผ ์œ ์ง€ํ•˜๊ณ  ํ™˜๊ฒฝ๋ณ„๋กœ ๋งž์ถค์„ค์ •์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํŠœํ† ๋ฆฌ์–ผ์—์„œ๋Š” ์•ฑ ์ €์žฅ์†Œ์˜ Kustomize ๊ตฌ์„ฑ์„ ์œ ์ง€ํ•˜๊ณ  CI ํŒŒ์ดํ”„๋ผ์ธ์˜ ๊ตฌ์„ฑ์„ '๋นŒ๋“œ'(์˜ˆ: ๋งž์ถค์„ค์ • ์ ์šฉ)ํ•ฉ๋‹ˆ๋‹ค. ์ด ํŠœํ† ๋ฆฌ์–ผ์—์„œ ์„ค๋ช…ํ•˜๋Š” ๊ฐœ๋…์€ ํด๋Ÿฌ์Šคํ„ฐ์— ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” Kubernetes ๊ตฌ์„ฑ์„ ์ƒ์„ฑํ•˜๋Š” ๋ชจ๋“  ๋„๊ตฌ(์˜ˆ: helm template ๋ช…๋ น์–ด)์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Kpt: Kpt๋Š” Kubernetes ๊ตฌ์„ฑ์˜ ์›Œํฌํ”Œ๋กœ๋ฅผ ๋นŒ๋“œํ•˜๋Š” ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. kpt๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด Kubernetes ๊ตฌ์„ฑ ๊ฐ€์ ธ์˜ค๊ธฐ, ํ‘œ์‹œ, ๋งž์ถค์„ค์ •, ์—…๋ฐ์ดํŠธ, ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ, ์ ์šฉ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Git ๋ฐ YAML ํŒŒ์ผ๊ณผ ํ˜ธํ™˜๋˜๋ฏ€๋กœ Kubernetes ์ƒํƒœ๊ณ„์˜ ๊ธฐ์กด ๋„๊ตฌ ๋Œ€๋ถ€๋ถ„๊ณผ ํ˜ธํ™˜๋ฉ๋‹ˆ๋‹ค. ์ด ํŠœํ† ๋ฆฌ์–ผ์—์„œ๋Š” CI ํŒŒ์ดํ”„๋ผ์ธ์—์„œ kpt๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ anthos-config-management-samples ์ €์žฅ์†Œ์—์„œ ์ œ์•ฝ์กฐ๊ฑด์„ ๊ฐ€์ ธ์˜ค๊ณ  ์ด๋Ÿฌํ•œ ์ œ์•ฝ์กฐ๊ฑด์— ๋Œ€ํ•ด Kubernetes ๊ตฌ์„ฑ์„ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.

ํŒŒ์ดํ”„๋ผ์ธ

์ด ํŠœํ† ๋ฆฌ์–ผ์—์„œ ์‚ฌ์šฉํ•˜๋Š” CI ํŒŒ์ดํ”„๋ผ์ธ์€ ๋‹ค์Œ ๋‹ค์ด์–ด๊ทธ๋žจ์— ๋‚˜์™€ ์žˆ์Šต๋‹ˆ๋‹ค.

์ •์ฑ… ์ปจํŠธ๋กค๋Ÿฌ์šฉ CI ํŒŒ์ดํ”„๋ผ์ธ

์ด ํŒŒ์ดํ”„๋ผ์ธ์€ Cloud Build์—์„œ ์‹คํ–‰๋˜๋ฉฐ ๋ช…๋ น์–ด๋Š” ์ƒ˜ํ”Œ ์•ฑ ์ €์žฅ์†Œ์˜ ๋ณต์‚ฌ๋ณธ์ด ํฌํ•จ๋œ ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. kustomize๋ฅผ ํ†ตํ•ด ์ตœ์ข… Kubernetes ๊ตฌ์„ฑ์„ ์ƒ์„ฑํ•˜๋ฉด ํŒŒ์ดํ”„๋ผ์ธ์ด ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ํ›„ kpt๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ anthos-config-management-์ƒ˜ํ”Œ ์ €์žฅ์†Œ์—์„œ ๊ฒ€์ฆํ•  ์ œ์•ฝ์กฐ๊ฑด์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ kpt๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋Ÿฌํ•œ ์ œ์•ฝ์กฐ๊ฑด์— ๋Œ€ํ•ด Kubernetes ๊ตฌ์„ฑ์˜ ์œ ํšจ์„ฑ์„ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ด ๋งˆ์ง€๋ง‰ ๋‹จ๊ณ„๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ ค๋ฉด ์ด ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” gatekeeper๋ผ๋Š” ํŠน์ • ๊ตฌ์„ฑ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ํŠœํ† ๋ฆฌ์–ผ์—์„œ๋Š” CI ํŒŒ์ดํ”„๋ผ์ธ์„ ์ˆ˜๋™์œผ๋กœ ํŠธ๋ฆฌ๊ฑฐํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ Git ์ €์žฅ์†Œ์— git push๋ฅผ ์‹คํ–‰ํ•œ ํ›„์— ์‹คํ–‰๋˜๋„๋ก ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.

๋ชฉํ‘œ

  • Cloud Build๋กœ ์ƒ˜ํ”Œ ์•ฑ์˜ CI ํŒŒ์ดํ”„๋ผ์ธ์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • ์ •์ฑ… ์œ„๋ฐ˜์œผ๋กœ ์ธํ•ด ํŒŒ์ดํ”„๋ผ์ธ์ด ์‹คํŒจํ–ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  • ์ •์ฑ…์„ ์ค€์ˆ˜ํ•˜๋„๋ก ์ƒ˜ํ”Œ ์•ฑ ์ €์žฅ์†Œ๋ฅผ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.
  • CI ํŒŒ์ดํ”„๋ผ์ธ์„ ์„ฑ๊ณต์ ์œผ๋กœ ๋‹ค์‹œ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

๋น„์šฉ

์ด ํŠœํ† ๋ฆฌ์–ผ์—์„œ๋Š” ๋น„์šฉ์ด ์ฒญ๊ตฌ๋  ์ˆ˜ ์žˆ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ Google Cloud๊ตฌ์„ฑ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  • Cloud Build
  • Google Kubernetes Engine(GKE) Enterprise ๋ฒ„์ „

ํ”„๋กœ์ ํŠธ ์‚ฌ์šฉ๋Ÿ‰์„ ๊ธฐ์ค€์œผ๋กœ ์˜ˆ์ƒ ๋น„์šฉ์„ ์‚ฐ์ถœํ•˜๋ ค๋ฉด ๊ฐ€๊ฒฉ ๊ณ„์‚ฐ๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.

์ด ํŠœํ† ๋ฆฌ์–ผ์„ ๋งˆ์นœ ํ›„์— ๊ณ„์† ๋น„์šฉ์ด ์ฒญ๊ตฌ๋˜์ง€ ์•Š๋„๋ก ํ•˜๋ ค๋ฉด ๋งŒ๋“  ๋ฆฌ์†Œ์Šค๋ฅผ ์‚ญ์ œํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์‚ญ์ œ ์„น์…˜์„ ์ฐธ์กฐํ•˜์„ธ์š”.

์‹œ์ž‘ํ•˜๊ธฐ ์ „์—

  1. Google Cloud ํ”„๋กœ์ ํŠธ๋ฅผ ์„ ํƒํ•˜๊ฑฐ๋‚˜ ๋งŒ๋“ญ๋‹ˆ๋‹ค. Google Cloud ์ฝ˜์†”์—์„œ ๋ฆฌ์†Œ์Šค ๊ด€๋ฆฌ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

    ๋ฆฌ์†Œ์Šค ๊ด€๋ฆฌ๋กœ ์ด๋™

  2. ํ”„๋กœ์ ํŠธ์— ๊ฒฐ์ œ๋ฅผ ์‚ฌ์šฉ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

  3. ์ด ํŠœํ† ๋ฆฌ์–ผ์— ๋‚˜์—ด๋œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด Cloud Shell์„ ์—ฝ๋‹ˆ๋‹ค.

    Cloud Shell๋กœ ์ด๋™

  4. Cloud Shell์—์„œ gcloud config get-value project๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

    ๋ช…๋ น์–ด๊ฐ€ ๋ฐฉ๊ธˆ ์„ ํƒํ•œ ํ”„๋กœ์ ํŠธ์˜ ID๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š์œผ๋ฉด Cloud Shell์ด ํ”„๋กœ์ ํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    gcloud config set project PROJECT_ID
    

    PROJECT_ID๋ฅผ ํ”„๋กœ์ ํŠธ ID๋กœ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

  5. Cloud Shell์—์„œ ํ•„์š”ํ•œ Cloud Build API๋ฅผ ์‚ฌ์šฉ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

    gcloud services enable cloudbuild.googleapis.com
    

์ƒ˜ํ”Œ ์•ฑ ๊ตฌ์„ฑ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ

์ด ์„น์…˜์—์„œ๋Š” Google์—์„œ ์ œ๊ณตํ•˜๋Š” ์ƒ˜ํ”Œ ์•ฑ ์ €์žฅ์†Œ์— ๋Œ€ํ•ด Cloud Build๋กœ CI ํŒŒ์ดํ”„๋ผ์ธ์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ด ํŒŒ์ดํ”„๋ผ์ธ์€ anthos-config-management-samples ์ €์žฅ์†Œ์— ์ œ๊ณต๋œ ์ œ์•ฝ์กฐ๊ฑด์— ๋Œ€ํ•ด ์ƒ˜ํ”Œ ์•ฑ ์ €์žฅ์†Œ์— ์ œ๊ณต๋œ Kubernetes ๊ตฌ์„ฑ์„ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.

์•ฑ ๊ตฌ์„ฑ์˜ ์œ ํšจ์„ฑ์„ ๊ฒ€์‚ฌํ•˜๋ ค๋ฉด ๋‹ค์Œ ์•ˆ๋‚ด๋ฅผ ๋”ฐ๋ฅด์„ธ์š”.

  1. Cloud Shell์—์„œ ์ƒ˜ํ”Œ ์•ฑ ์ €์žฅ์†Œ๋ฅผ ํด๋ก ํ•ฉ๋‹ˆ๋‹ค.

    git clone https://github.com/GoogleCloudPlatform/anthos-config-management-samples.git
    
  2. Cloud Build๋กœ CI ํŒŒ์ดํ”„๋ผ์ธ์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๋นŒ๋“œ ๋กœ๊ทธ๊ฐ€ Cloud Shell์— ์ง์ ‘ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

    cd anthos-config-management-samples/ci-app/app-repo
    gcloud builds submit .
    

    ์‹คํ–‰ํ•˜๋Š” ํŒŒ์ดํ”„๋ผ์ธ์€ ๋‹ค์Œ ํŒŒ์ผ์— ์ •์˜๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

    steps:
    - id: 'Prepare config'
      # This step builds the final manifests for the app
      # using kustomize and the configuration files
      # available in the repository.
      name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
      entrypoint: '/bin/sh'
      args: ['-c', 'mkdir hydrated-manifests && kubectl kustomize config/prod > hydrated-manifests/prod.yaml']
    - id: 'Download policies'
      # This step fetches the policies from the Anthos Config Management repository
      # and consolidates every resource in a single file.
      name: 'gcr.io/kpt-dev/kpt'
      entrypoint: '/bin/sh'
      args: ['-c', 'kpt pkg get https://github.com/GoogleCloudPlatform/anthos-config-management-samples.git/ci-app/acm-repo/cluster@main constraints
                      && kpt fn source constraints/ hydrated-manifests/ > hydrated-manifests/kpt-manifests.yaml']
    - id: 'Validate against policies'
      # This step validates that all resources comply with all policies.
      name: 'gcr.io/kpt-fn/gatekeeper:v0.2'
      args: ['--input', 'hydrated-manifests/kpt-manifests.yaml']

    ์ •์ฑ… ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ์ œ์•ฝ์กฐ๊ฑด์€ ์ œ์•ฝ์กฐ๊ฑด ํ…œํ”Œ๋ฆฟ์˜ ์ธ์Šคํ„ด์Šคํ™”์— ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค. ์ œ์•ฝ์กฐ๊ฑด ํ…œํ”Œ๋ฆฟ์€ ์ œ์•ฝ์กฐ๊ฑด์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ์‹ค์ œ Rego ์ฝ”๋“œ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. gcr.io/kpt-fn/gatekeeper ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์ œ์•ฝ์กฐ๊ฑด ํ…œํ”Œ๋ฆฟ๊ณผ ์ œ์•ฝ์กฐ๊ฑด ์ •์˜๊ฐ€ ๋ชจ๋‘ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ƒ˜ํ”Œ ์ •์ฑ… ์ €์žฅ์†Œ์—๋Š” ๋ชจ๋‘ ํฌํ•จ๋˜์–ด ์žˆ์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ๋‹ค๋ฅธ ์œ„์น˜์— ์ €์žฅ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•„์š”์— ๋”ฐ๋ผ kpt pkg get ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ œ์•ฝ์กฐ๊ฑด ํ…œํ”Œ๋ฆฟ๊ณผ ์ œ์•ฝ์กฐ๊ฑด์„ ๋ชจ๋‘ ๋‹ค์šด๋กœ๋“œํ•˜์„ธ์š”.

    ์ด ํŠœํ† ๋ฆฌ์–ผ์—์„œ๋Š” Cloud Build์™€ ํ•จ๊ป˜ gcr.io/kpt-fn/gatekeeper๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฆฌ์†Œ์Šค๋ฅผ ๊ฒ€์ฆํ•˜์ง€๋งŒ ๋‹ค๋ฅธ ๋‘ ๊ฐ€์ง€ ๋Œ€์•ˆ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    kpt fn eval hydrated-manifests/kpt-manifests.yaml --image gcr.io/kpt-fn/gatekeeper:v0.2
    
    gator test -f hydrated-manifests/kpt-manifests.yaml
    
  3. ๋ช‡ ๋ถ„ ํ›„์— ํŒŒ์ดํ”„๋ผ์ธ์ด ์‹คํŒจํ•˜์—ฌ ๋‹ค์Œ ์˜ค๋ฅ˜๊ฐ€ ํ‘œ์‹œ๋˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

    [...]
    Step #2 - "Validate against policies": [error] apps/v1/Deployment/nginx-deployment : Deployment objects should have an 'owner' label indicating who created them.
    Step #2 - "Validate against policies": violatedConstraint: deployment-must-have-owner
    Finished Step #2 - "Validate against policies"
    2022/05/11 18:55:18 Step Step #2 - "Validate against policies" finished
    2022/05/11 18:55:19 status changed to "ERROR"
    ERROR
    ERROR: build step 2 "gcr.io/kpt-fn/gatekeeper:v0.2" failed: exit status 1
    2022/05/11 18:55:20 Build finished with ERROR status
    

    ๊ตฌ์„ฑ์—์„œ ์œ„๋ฐ˜ํ•œ ์ œ์•ฝ์กฐ๊ฑด์€ ๋‹ค์Œ ํŒŒ์ผ์— ์ •์˜๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” K8sRequiredLabels๋ผ๋Š” Kubernetes ์ปค์Šคํ…€ ๋ฆฌ์†Œ์Šค์ž…๋‹ˆ๋‹ค.

    apiVersion: constraints.gatekeeper.sh/v1beta1
    kind: K8sRequiredLabels
    metadata:
      name: deployment-must-have-owner
    spec:
      match:
        kinds:
          - apiGroups: ["apps"]
            kinds: ["Deployment"]
      parameters:
        labels:
          - key: "owner"
        message: "Deployment objects should have an 'owner' label indicating who created them."

    ์ด ์ œ์•ฝ์กฐ๊ฑด์— ํ•ด๋‹นํ•˜๋Š” ์ œ์•ฝ์กฐ๊ฑด ํ…œํ”Œ๋ฆฟ์€ GitHub์˜ requiredlabels.yaml์„ ์ฐธ์กฐํ•˜์„ธ์š”.

  4. ์ „์ฒด Kubernetes ๊ตฌ์„ฑ์„ ์ง์ ‘ ๋นŒ๋“œํ•˜๊ณ  ์‹ค์ œ๋กœ owner ๋ผ๋ฒจ์ด ์—†๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๊ตฌ์„ฑ์„ ๋นŒ๋“œํ•˜๋ ค๋ฉด ๋‹ค์Œ์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

    kubectl kustomize config/prod
    

ํšŒ์‚ฌ ์ •์ฑ…์„ ์ค€์ˆ˜ํ•˜๋„๋ก ์•ฑ ์ˆ˜์ •

์ด ์„น์…˜์—์„œ๋Š” Kustomize๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ •์ฑ… ์œ„๋ฐ˜์„ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.

  1. Cloud Shell์—์„œ commonLabels ์„น์…˜์„ ๊ธฐ๋ณธ Kustomization ํŒŒ์ผ์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

    cat <<EOF >> config/base/kustomization.yaml
    commonLabels:
      owner: myself
    EOF
    
  2. ์ „์ฒด Kubernetes ๊ตฌ์„ฑ์„ ๋นŒ๋“œํ•˜๊ณ  ํ˜„์žฌ owner ๋ผ๋ฒจ์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

    kubectl kustomize config/prod
    
  3. Cloud Build๋กœ CI ํŒŒ์ดํ”„๋ผ์ธ์„ ๋‹ค์‹œ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

    gcloud builds submit .
    

    ์ด์ œ ํŒŒ์ดํ”„๋ผ์ธ์ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.

    [...]
    Step #2 - "Validate against policies": [RUNNING] "gcr.io/kpt-fn/gatekeeper:v0"
    Step #2 - "Validate against policies": [PASS] "gcr.io/kpt-fn/gatekeeper:v0"
    [...]
    

์‚ญ์ œ

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

๋‹ค์Œ ๋‹จ๊ณ„

  • ๊ทธ ๋ฐ–์˜ ์ฐธ์กฐ ์•„ํ‚คํ…์ฒ˜, ๋‹ค์ด์–ด๊ทธ๋žจ, ํŠœํ† ๋ฆฌ์–ผ, ๊ถŒ์žฅ์‚ฌํ•ญ์„ ์•Œ์•„๋ณด๋ ค๋ฉด Cloud ์•„ํ‚คํ…์ฒ˜ ์„ผํ„ฐ๋ฅผ ํ™•์ธํ•˜์„ธ์š”.