11 ways not to get hacked

https://kubernetes.io/blog/2018/07/18/11-ways-not-to-get-hacked/ ์š”์•ฝ

psp๊ด€๋ จ ๋‚ด์šฉ์€ ์‚ญ์ œ

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

Part One: The Control Plane

control plane์€ Kubernetes์˜ ๋‘๋‡Œ์ž…๋‹ˆ๋‹ค. ํด๋Ÿฌ์Šคํ„ฐ์—์„œ ์‹คํ–‰ ์ค‘์ธ ๋ชจ๋“  ์ปจํ…Œ์ด๋„ˆ์™€ ํฌ๋“œ์— ๋Œ€ํ•œ ์ „์ฒด ๋ณด๊ธฐ๊ฐ€ ์žˆ๊ณ  ์ƒˆ ํฌ๋“œ(๋ถ€๋ชจ ๋…ธ๋“œ์— ๋Œ€ํ•œ ๋ฃจํŠธ ์•ก์„ธ์Šค ๊ถŒํ•œ์ด ์žˆ๋Š” ์ปจํ…Œ์ด๋„ˆ๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Œ)๋ฅผ ์˜ˆ์•ฝํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ํด๋Ÿฌ์Šคํ„ฐ์— ์ €์žฅ๋œ ๋ชจ๋“  ๋น„๋ฐ€์„ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ท€์ค‘ํ•œ ๊ฒƒ์€ ์ ‘๊ทผํ•  ๋•Œ๋‚˜, ์ €์žฅ๋˜์–ด ์žˆ์„ ๋•Œ๋‚˜, ๋„คํŠธ์›Œํฌ๋ฅผ ํ†ตํ•ด ์šด์†ก๋  ๋•Œ๋„ ์šฐ๋ฐœ์ ์ธ ๋ˆ„์ถœ ๋ฐ ์•…์˜์ ์ธ ์˜๋„๋กœ๋ถ€ํ„ฐ ๋ณดํ˜ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

1. TLS Everywhere

ํŠธ๋ž˜ํ”ฝ ์Šค๋‹ˆํ•‘์„ ๋ฐฉ์ง€ํ•˜๊ณ , ์„œ๋ฒ„์˜ ID๋ฅผ ํ™•์ธํ•˜๊ณ , (์ƒํ˜ธ TLS์˜ ๊ฒฝ์šฐ) ํด๋ผ์ด์–ธํŠธ์˜ ID๋ฅผ ํ™•์ธํ•˜๋ ค๋ฉด TLS๋ฅผ ์ง€์›ํ•˜๋Š” ๋ชจ๋“  ๊ตฌ์„ฑ ์š”์†Œ์— ๋Œ€ํ•ด TLS๋ฅผ ํ™œ์„ฑํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Source

Lucas Kรคldstrรถm์ด ์ž‘์„ฑํ•œ ์ด ๋„คํŠธ์›Œํฌ ๋‹ค์ด์–ด๊ทธ๋žจ์€ TLS๊ฐ€ ์ด์ƒ์ ์œผ๋กœ ์ ์šฉ๋˜์–ด์•ผ ํ•˜๋Š” ์ผ๋ถ€ ์œ„์น˜, ์ฆ‰ ๋งˆ์Šคํ„ฐ์˜ ๋ชจ๋“  ๊ตฌ์„ฑ์š”์†Œ ์‚ฌ์ด, Kubelet๊ณผ API ์„œ๋ฒ„ ์‚ฌ์ด๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

2. RBACํ™œ์„ฑํ™”(Least Privilege ์ตœ์†Œ ๊ถŒํ•œ ๋ฒ•์น™์œผ๋กœ) , ABAC๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ , ๊ทธ๋ฆฌ๊ณ  ๋กœ๊ทธ ๋ชจ๋‹ˆํ„ฐ๋ง ํ•˜๊ธฐ

Role-based access control์€ ๋„ค์ž„์ŠคํŽ˜์ด์Šค ์•ก์„ธ์Šค์™€ ๊ฐ™์€ ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ ์‚ฌ์šฉ์ž ์•ก์„ธ์Šค์— ๋Œ€ํ•œ ์„ธ๋ถ„ํ™”๋œ ์ •์ฑ… ๊ด€๋ฆฌ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

Kubernetes์˜ ABAC(์†์„ฑ ๊ธฐ๋ฐ˜ ์•ก์„ธ์Šค ์ œ์–ด)๋Š” ๋ฆด๋ฆฌ์Šค 1.6๋ถ€ํ„ฐ RBAC๋กœ ๋Œ€์ฒด๋˜์—ˆ์œผ๋ฉฐ API ์„œ๋ฒ„์—์„œ ํ™œ์„ฑํ™”ํ•˜๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ๋Œ€์‹  RBAC๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.

์žŠ์ง€ ๋งˆ์„ธ์š”: ์ด๋Ÿฌํ•œ ๋กœ๊ทธ๋ฅผ ํด๋Ÿฌ์Šคํ„ฐ ๋‚ด๋ถ€์— ๋ณด๊ด€ํ•˜๋Š” ๊ฒƒ์€ ์นจํ•ด ์‹œ ๋ณด์•ˆ ์œ„ํ˜‘์ด ๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋‹ค๋ฅธ ๋ชจ๋“  ๋ณด์•ˆ์— ๋ฏผ๊ฐํ•œ ๋กœ๊ทธ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์œ„๋ฐ˜ ์‹œ ๋ณ€์กฐ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ํด๋Ÿฌ์Šคํ„ฐ ์™ธ๋ถ€๋กœ ์ „์†ก๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

3. API ์„œ๋ฒ„์— ํƒ€์‚ฌ ์ธ์ฆ ์‚ฌ์šฉ

์กฐ์ง ์ „์ฒด์—์„œ ์ธ์ฆ ๋ฐ ๊ถŒํ•œ ๋ถ€์—ฌ(Single Sign On์ด๋ผ๊ณ ๋„ ํ•จ)๋ฅผ ์ค‘์•™ ์ง‘์ค‘ํ™”ํ•˜๋ฉด ์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ ์˜จ๋ณด๋”ฉ, ์˜คํ”„๋ณด๋”ฉ ๋ฐ ์ผ๊ด€๋œ ๊ถŒํ•œ์ด ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.

Kubernetes๋ฅผ ํƒ€์‚ฌ ์ธ์ฆ ์ œ๊ณต์ž(์˜ˆ: Google ๋˜๋Š” GitHub)์™€ ํ†ตํ•ฉํ•˜๋ฉด ์›๊ฒฉ ํ”Œ๋žซํผ์˜ ID ๋ณด์ฆ(2FA์™€ ๊ฐ™์€ ๊ฒƒ์œผ๋กœ ๋ฐฑ์—…๋จ)์„ ์‚ฌ์šฉํ•˜๊ณ  ๊ด€๋ฆฌ์ž๊ฐ€ ์‚ฌ์šฉ์ž๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•ด Kubernetes API ์„œ๋ฒ„๋ฅผ ์žฌ๊ตฌ์„ฑํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.

4. etcd ํด๋Ÿฌ์Šคํ„ฐ ๋ถ„๋ฆฌ ๋ฐ ๋ฐฉํ™”๋ฒฝ

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

API ์„œ๋ฒ„์˜ etcd์— ๋Œ€ํ•œ ์“ฐ๊ธฐ ์•ก์„ธ์Šค๋Š” ์ „์ฒด ํด๋Ÿฌ์Šคํ„ฐ์—์„œ ๋ฃจํŠธ๋ฅผ ์–ป๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•˜๋ฉฐ ์ฝ๊ธฐ ์•ก์„ธ์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ถŒํ•œ์„ ์ƒ๋‹นํžˆ ์‰ฝ๊ฒŒ ์—์Šค์ปฌ๋ ˆ์ด์…˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Kubernetes ์Šค์ผ€์ค„๋Ÿฌ๋Š” ๋…ธ๋“œ๊ฐ€ ์—†๋Š” ํฌ๋“œ ์ •์˜์— ๋Œ€ํ•ด etcd๋ฅผ ๊ฒ€์ƒ‰ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ฐพ์€ ํฌ๋“œ๋ฅผ ์˜ˆ์•ฝ์„ ์œ„ํ•ด ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ kubelet์œผ๋กœ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ์ œ์ถœ๋œ ํฌ๋“œ์— ๋Œ€ํ•œ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋Š” API ์„œ๋ฒ„๊ฐ€ etcd์— ์“ฐ๊ธฐ ์ „์— ์ˆ˜ํ–‰ํ•˜๋ฏ€๋กœ etcd์— ์ง์ ‘ ์“ฐ๋Š” ์•…์˜์ ์ธ ์‚ฌ์šฉ์ž๋Š” ๋งŽ์€ ๋ณด์•ˆ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์šฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ)PodSecurity์ •์ฑ….

etcd๋Š” ํ”ผ์–ด ๋ฐ ํด๋ผ์ด์–ธํŠธ TLS ์ธ์ฆ์„œ๋กœ ๊ตฌ์„ฑํ•˜๊ณ  ์ „์šฉ ๋…ธ๋“œ์— ๋ฐฐํฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ์ธ ํ‚ค๊ฐ€ ๋„๋‚œ๋‹นํ•˜๊ณ  ์ž‘์—…์ž ๋…ธ๋“œ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ API ์„œ๋ฒ„๋กœ ๋ฐฉํ™”๋ฒฝ์œผ๋กœ ์„ค์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

5. ์•”ํ˜ธํ™” ํ‚ค ๊ต์ฒด

๋ณด์•ˆ ๋ชจ๋ฒ” ์‚ฌ๋ก€๋Š” ํ‚ค ์†์ƒ์˜ "ํญ๋ฐœ ๋ฐ˜๊ฒฝ"์„ ์ œํ•œํ•˜๊ธฐ ์œ„ํ•ด ์•”ํ˜ธํ™” ํ‚ค์™€ ์ธ์ฆ์„œ๋ฅผ ์ •๊ธฐ์ ์œผ๋กœ ๊ต์ฒดํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Kubernetes๋Š” ๊ธฐ์กด ์ž๊ฒฉ ์ฆ๋ช…์ด ๋งŒ๋ฃŒ๋˜๋ฉด ์ƒˆ CSR์„ ์ƒ์„ฑํ•˜์—ฌ ์ผ๋ถ€ ์ธ์ฆ์„œ(ํŠนํžˆ kubelet ํด๋ผ์ด์–ธํŠธ ๋ฐ ์„œ๋ฒ„ ์ธ์ฆ์„œ)๋ฅผ ์ž๋™์œผ๋กœ ๊ต์ฒดํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ API ์„œ๋ฒ„๊ฐ€ etcd ๊ฐ’์„ ์•”ํ˜ธํ™”ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์นญ ์•”ํ˜ธํ™” ํ‚ค๋Š” ์ž๋™์œผ๋กœ ์ˆœํ™˜๋˜์ง€ ์•Š์œผ๋ฉฐ ์ˆ˜๋™์œผ๋กœ ์ˆœํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด์„œ๋Š” ๋งˆ์Šคํ„ฐ ์•ก์„ธ์Šค๊ฐ€ ํ•„์š”ํ•˜๋ฏ€๋กœ ๊ด€๋ฆฌ ์„œ๋น„์Šค(์˜ˆ: GKE ๋˜๋Š” AKS)๋Š” ์šด์˜์ž๋กœ๋ถ€ํ„ฐ ์ด ๋ฌธ์ œ๋ฅผ ์ถ”์ƒํ™”ํ•ฉ๋‹ˆ๋‹ค.

Part Two: Workloads

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

6. Use Linux Security Features and PodSecurityPolicies

Linux ์ปค๋„์—๋Š” ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์— ์ตœ์†Œ ๊ถŒํ•œ์„ ์ œ๊ณตํ•˜๋„๋ก ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ์—ฌ๋Ÿฌ ์ค‘์ฒฉ ๋ณด์•ˆ ํ™•์žฅ(๊ธฐ๋Šฅ, SELinux, AppArmor, seccomp-bpf)์ด ์žˆ์Šต๋‹ˆ๋‹ค.

bane๊ณผ ๊ฐ™์€ ๋„๊ตฌ๋Š” AppArmor ํ”„๋กœํ•„์„ ์ƒ์„ฑํ•˜๊ณ  seccomp ํ”„๋กœํ•„์„ ์œ„ํ•œ docker-slim์„ ์ƒ์„ฑํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๋Ÿฌํ•œ ์ •์ฑ… ์ ์šฉ์˜ ๋ถ€์ž‘์šฉ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํฌ๊ด„์ ์ธ ํ…Œ์ŠคํŠธ๋ฅผ ์ฃผ์˜ํ•˜์—ฌ ํ•˜์‹ญ์‹œ์˜ค.

7. Statically Analyse YAML

Sensitive information should not be stored in pod-type YAML resource (deployments, pods, sets, etc.), and sensitive configmaps and secrets should be encrypted with tools such as vault (with CoreOS's operator), git-crypt, sealed secrets, or cloud provider KMS.

Static analysis of YAML configuration can be used to establish a baseline for runtime security. kubesec generates risk scores for resources:

{
  "score": -30,
  "scoring": {
    "critical": [
      {
        "selector": "containers[] .securityContext .privileged == true",
        "reason": "Privileged containers can allow almost completely unrestricted host access"
      }
    ],
    "advise": [
      {
        "selector": "containers[] .securityContext .runAsNonRoot == true",
        "reason": "Force the running image to run as a non-root user to ensure least privilege"
      },
      {
        "selector": "containers[] .securityContext .capabilities .drop",
        "reason": "Reducing kernel capabilities available to a container limits its attack surface",
        "href": "/docs/tasks/configure-pod-container/security-context/"
      }
    ]
  }
}

And kubetest is a unit test framework for Kubernetes configurations:

#// vim: set ft=python:
def test_for_team_label():
    if spec["kind"] == "Deployment":
        labels = spec["spec"]["template"]["metadata"]["labels"]
        assert_contains(labels, "team", "should indicate which team owns the deployment")

test_for_team_label()

8. ๋ฃจํŠธ๊ฐ€ ์•„๋‹Œ ์‚ฌ์šฉ์ž๋กœ ์ปจํ…Œ์ด๋„ˆ ์‹คํ–‰

๋ฃจํŠธ๋กœ ์‹คํ–‰๋˜๋Š” ์ปจํ…Œ์ด๋„ˆ๋Š” ์ž‘์—… ๋ถ€ํ•˜๊ฐ€ ์š”๊ตฌํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ํ›จ์”ฌ ๋” ๋งŽ์€ ๊ถŒํ•œ์„ ๊ฐ–๊ณ  ์žˆ์œผ๋ฉฐ, ์ด๋Š” ์†์ƒ๋  ๊ฒฝ์šฐ ๊ณต๊ฒฉ์ž๊ฐ€ ๊ณต๊ฒฉ์„ ๊ณ„์†ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Kubernetes์—์„œ ์‚ฌ์šฉ์ž ๋„ค์ž„์ŠคํŽ˜์ด์Šค๊ฐ€ ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฆ‰, ์ปจํ…Œ์ด๋„ˆ์˜ ์‚ฌ์šฉ์ž ID ํ…Œ์ด๋ธ”์ด ํ˜ธ์ŠคํŠธ์˜ ์‚ฌ์šฉ์ž ํ…Œ์ด๋ธ”์— ๋งคํ•‘๋˜๊ณ  ์ปจํ…Œ์ด๋„ˆ ๋‚ด์—์„œ ๋ฃจํŠธ ์‚ฌ์šฉ์ž๋กœ ํ”„๋กœ์„ธ์Šค๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ํ˜ธ์ŠคํŠธ์—์„œ ๋ฃจํŠธ๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ปจํ…Œ์ด๋„ˆ ๋ธŒ๋ ˆ์ดํฌ์•„์›ƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๊ณ„์ธตํ™”๋œ ๋ณด์•ˆ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ์žˆ์ง€๋งŒ ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€์—์„œ ๋ฃจํŠธ๋กœ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์€ ์—ฌ์ „ํžˆ ๊ถŒ์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋งŽ์€ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€๋Š” ๋ฃจํŠธ ์‚ฌ์šฉ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ PID 1์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ํ•ด๋‹น ํ”„๋กœ์„ธ์Šค๊ฐ€ ์†์ƒ๋˜๋ฉด ๊ณต๊ฒฉ์ž๊ฐ€ ์ปจํ…Œ์ด๋„ˆ์— ๋ฃจํŠธ๋ฅผ ๊ฐ–๊ฒŒ ๋˜๋ฉฐ ์ž˜๋ชป๋œ ๊ตฌ์„ฑ์„ ์•…์šฉํ•˜๊ธฐ๊ฐ€ ํ›จ์”ฌ ์‰ฌ์›Œ์ง‘๋‹ˆ๋‹ค.

# Required to prevent escalations to root.
allowPrivilegeEscalation: false
runAsUser:
  # Require the container to run without root privileges.
  rule: 'MustRunAsNonRoot'

๋ฃจํŠธ๊ฐ€ ์•„๋‹Œ ์ปจํ…Œ์ด๋„ˆ๋Š” 1024 ๋ฏธ๋งŒ์˜ ๊ถŒํ•œ ์žˆ๋Š” ํฌํŠธ์— ๋ฐ”์ธ๋”ฉํ•  ์ˆ˜ ์—†์ง€๋งŒ(์ด๊ฒƒ์€ CAP_NET_BIND_SERVICE ์ปค๋„ ๊ธฐ๋Šฅ์— ์˜ํ•ด ์ œ์–ด๋จ) ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด ์‚ฌ์‹ค์„ ์œ„์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์˜ˆ์—์„œ ๊ฐ€์ƒ์˜ MyApp ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์ปจํ…Œ์ด๋„ˆ์˜ ํฌํŠธ 8443์— ๋ฐ”์ธ๋”ฉ๋˜์ง€๋งŒ ์„œ๋น„์Šค๋Š” targetPort์— ๋Œ€ํ•œ ์š”์ฒญ์„ ํ”„๋ก์‹œํ•˜์—ฌ 443์—์„œ ์ด๋ฅผ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
    - protocol: TCP
      port: 443
      targetPort: 8443

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

9. Use Network Policies

๊ธฐ๋ณธ์ ์œผ๋กœ Kubernetes ๋„คํŠธ์›Œํ‚น์€ ๋ชจ๋“  ํฌ๋“œ ๊ฐ„ ํŠธ๋ž˜ํ”ฝ์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ `Network Policy`์„ ์‚ฌ์šฉํ•˜์—ฌ ์ œํ•œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Kubernetes๋Š” ๋ชจ๋“  ์‹œ์Šคํ…œ ์ƒํƒœ๋ฅผ etcd์— ์ €์žฅํ•˜๋ฏ€๋กœ CNI ๋„คํŠธ์›Œํ‚น ํ”Œ๋Ÿฌ๊ทธ์ธ์—์„œ ์ง€์›ํ•˜๋Š” ๊ฒฝ์šฐ ๋™์  ๋ฐฉํ™”๋ฒฝ์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Calico, Cilium, kube-router, Romana ๋ฐ Weave Net์€ ๋ชจ๋‘ Network Policy์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
spec:
  podSelector:
Here's an example NetworkPolicy that denies all egress except UDP 53 (DNS), which also prevents inbound connections to your application. NetworkPolicies are stateful, so the replies to outbound requests still reach the application.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: myapp-deny-external-egress
spec:
  podSelector:
    matchLabels:
      app: myapp
  policyTypes:
  - Egress
  egress:
  - ports:
    - port: 53
      protocol: UDP
  - to:
    - namespaceSelector: {}

Kubernetes ๋„คํŠธ์›Œํฌ ์ •์ฑ…์€ DNS ์ด๋ฆ„์— ์ ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ณ ์ • IP ๋˜๋Š” podSelector(๋™์  Kubernetes IP์˜ ๊ฒฝ์šฐ)์—๋งŒ ๋„คํŠธ์›Œํฌ ์ •์ฑ…์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

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

k8s: # used for Kubernetes pods
  deployment: # only deployments currently supported
    test-frontend: # pod name, defaults to `default` namespace
      test-microservice: 80 # `test-microservice` is the DNS name of the target service
      test-database: -80 # `test-frontend` should not be able to access test-databaseโ€™s port 80
      169.254.169.254: -80, -443 # AWS metadata API
      metadata.google.internal: -80, -443 # GCP metadata API

    new-namespace:test-microservice: # `new-namespace` is the namespace name
      test-database.new-namespace: 80 # longer DNS names can be used for other namespaces
      test-frontend.default: 80
      169.254.169.254: -80, -443 # AWS metadata API
      metadata.google.internal: -80, -443 # GCP metadata API

10. Scan Images and Run IDS(์นจ์ž… ํƒ์ง€ ์‹œ์Šคํ…œ)

์›น ์„œ๋ฒ„๋Š” ์™ธ๋ถ€์—์„œ http/https๋ฅผ ํ†ตํ•ด์„œ pod๋‚ด๋ถ€์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ• ์ˆ˜ ์žˆ์Œ

์ด๋ฏธ์ง€ ์Šค์บ”ํ•˜๋ฉด ๊ณต๊ฒฉ์ž๊ฐ€ ์ปจํ…Œ์ด๋„ˆ์— ์›๊ฒฉ ์•ก์„ธ์Šคํ•˜๊ธฐ ์œ„ํ•ด ์•…์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์•Œ๋ ค์ง„ ์ทจ์•ฝ์ ์ด ์—†๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

IDS(์นจ์ž… ํƒ์ง€ ์‹œ์Šคํ…œ)์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์›นํ›…์€ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€ ์Šค์บ” ๋„๊ตฌ์—์„œ ์ด๋ฏธ์ง€๋ฅผ ํด๋Ÿฌ์Šคํ„ฐ์— ๋ฐฐํฌํ•˜๊ธฐ ์ „์— ์œ ํšจ์„ฑ์„ ๊ฒ€์‚ฌํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒ€์‚ฌ์— ์‹คํŒจํ•œ ์ด๋ฏธ์ง€๋Š” ์ž…์žฅ์ด ๊ฑฐ๋ถ€๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•Œ๋ ค์ง„ ์ทจ์•ฝ์ ์— ๋Œ€ํ•ด ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€๋ฅผ ์Šค์บ”ํ•˜๋ฉด ๊ณต๊ฒฉ์ž๊ฐ€ ๊ณต๊ฐœ๋œ CVE๋ฅผ ์•…์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์‹œ๊ฐ„์„ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. CoreOS์˜ Clair ๋ฐ Aqua์˜ Micro Scanner์™€ ๊ฐ™์€ ๋ฌด๋ฃŒ ๋„๊ตฌ๋Š” ๋ฐฐํฌ ํŒŒ์ดํ”„๋ผ์ธ์—์„œ ์‚ฌ์šฉ๋˜์–ด ์ค‘์š”ํ•˜๊ณ  ์•…์šฉ ๊ฐ€๋Šฅํ•œ ์ทจ์•ฝ์ ์ด ์žˆ๋Š” ์ด๋ฏธ์ง€์˜ ๋ฐฐํฌ๋ฅผ ๋ฐฉ์ง€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Grafeas์™€ ๊ฐ™์€ ๋„๊ตฌ๋Š” ์ปจํ…Œ์ด๋„ˆ์˜ ๊ณ ์œ  ์„œ๋ช…(์ฝ˜ํ…์ธ  ์ฃผ์†Œ ์ง€์ • ๊ฐ€๋Šฅ ํ•ด์‹œ)์— ๋Œ€ํ•œ ์ง€์†์ ์ธ ๊ทœ์ • ์ค€์ˆ˜ ๋ฐ ์ทจ์•ฝ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์œ„ํ•ด ์ด๋ฏธ์ง€ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, ํ•ด๋‹น ํ•ด์‹œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€๋ฅผ ์Šค์บ”ํ•˜๋Š” ๊ฒƒ์€ ํ”„๋กœ๋•์…˜์— ๋ฐฐํฌ๋œ ์ด๋ฏธ์ง€๋ฅผ ์Šค์บ”ํ•˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•˜๋ฉฐ ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์— ์•ก์„ธ์Šคํ•  ํ•„์š” ์—†์ด ๊ณ„์† ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•Œ๋ ค์ง€์ง€ ์•Š์€ Zero Day ์ทจ์•ฝ์ ์€ ํ•ญ์ƒ ์กด์žฌํ•˜๋ฏ€๋กœ Twistlock, Aqua ๋ฐ Sysdig Secure์™€ ๊ฐ™์€ ์นจ์ž… ํƒ์ง€ ๋„๊ตฌ๋ฅผ Kubernetes์— ๋ฐฐํฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

IDS๋Š” ์ปจํ…Œ์ด๋„ˆ์—์„œ ๋น„์ •์ƒ์ ์ธ ๋™์ž‘์„ ๊ฐ์ง€ํ•˜๊ณ  ์ด๋ฅผ ์ผ์‹œ ์ค‘์ง€ํ•˜๊ฑฐ๋‚˜ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค. Sysdig์˜ Falco๋Š” ์˜คํ”ˆ ์†Œ์Šค ๊ทœ์น™ ์—”์ง„์ด๋ฉฐ ์ด ์ƒํƒœ๊ณ„์˜ ์ถœ๋ฐœ์ ์ž…๋‹ˆ๋‹ค.

Part Three: The Future

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

11. Run a Service Mesh

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

๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ๋ณด์•ˆ ๋ฐ ๋„คํŠธ์›Œํ‚น ์ฝ”๋“œ๋ฅผ ๊ณต์œ ํ•˜๊ณ  ์ „ํˆฌ ํ…Œ์ŠคํŠธ๋ฅผ ๊ฑฐ์นœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ธํŠธ๋กœ ์˜คํ”„๋กœ๋“œํ•˜๋Š” ๊ฒƒ์€ Linkerd๋ฅผ ํ†ตํ•ด ์ด๋ฏธ ๊ฐ€๋Šฅํ–ˆ์œผ๋ฉฐ Google, IBM ๋ฐ Lyft์˜ Istio ๋„์ž…์œผ๋กœ ์ด ๋ถ„์•ผ์— ๋Œ€์•ˆ์ด ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํฌ๋“œ๋‹น ์•”ํ˜ธํ™” ID๋ฅผ ์œ„ํ•œ SPIFFE ๋ฐ ๊ธฐํƒ€ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•จ์œผ๋กœ์จ Istio๋Š” ์ฐจ์„ธ๋Œ€ ๋„คํŠธ์›Œํฌ ๋ณด์•ˆ์˜ ๋ฐฐํฌ๋ฅผ ๋‹จ์ˆœํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

"์ œ๋กœ ํŠธ๋Ÿฌ์ŠคํŠธ" ๋„คํŠธ์›Œํฌ์—์„œ๋Š” ๋ชจ๋“  ์ƒํ˜ธ ์ž‘์šฉ์ด mTLS(์ƒํ˜ธ TLS)๋ฅผ ํ†ตํ•ด ๋ฐœ์ƒํ•˜๋ฏ€๋กœ ๊ธฐ์กด ๋ฐฉํ™”๋ฒฝ์ด๋‚˜ Kubernetes ๋„คํŠธ์›Œํฌ ์ •์ฑ…์ด ํ•„์š”ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ „ํ†ต์ ์ธ ๋„คํŠธ์›Œํ‚น์—์„œ ํด๋ผ์šฐ๋“œ ๋„ค์ดํ‹ฐ๋ธŒ ๋ณด์•ˆ ์›์น™์œผ๋กœ์˜ ์ด๋Ÿฌํ•œ ์ „ํ™˜์€ ์ „ํ†ต์ ์ธ ๋ณด์•ˆ ์‚ฌ๊ณ ๋ฐฉ์‹์„ ๊ฐ€์ง„ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ์‰ฝ์ง€ ์•Š์„ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋˜๋ฉฐ SPIFFE์˜ Evan Gilman์ด ์“ด Zero Trust Networking ์ฑ…์€ ์ด ๋ฉ‹์ง„ ์‹ ์„ธ๊ณ„๋ฅผ ์†Œ๊ฐœํ•˜๋Š” ๋ฐ ์ ๊ทน ๊ถŒ์žฅ๋ฉ๋‹ˆ๋‹ค.

Istio LTS๊ฐ€ ์ถœ์‹œ๋˜์—ˆ์œผ๋ฉฐ ํ”„๋กœ์ ํŠธ๋Š” 1.0 ๋ฆด๋ฆฌ์Šค์— ๋น ๋ฅด๊ฒŒ ์ ‘๊ทผํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์•ˆ์ •์„ฑ ๋ฒ„์ „ ๊ด€๋ฆฌ๋Š” Kubernetes ๋ชจ๋ธ๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ๋ณ„ API๊ฐ€ ์ž์ฒด ์•ŒํŒŒ/๋ฒ ํƒ€ ์•ˆ์ •์„ฑ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์—์„œ ์ž์‹ ์„ ์‹๋ณ„ํ•˜๋Š” ์•ˆ์ •์ ์ธ ์ฝ”์–ด์ž…๋‹ˆ๋‹ค. ์•ž์œผ๋กœ ๋ช‡ ๋‹ฌ ๋™์•ˆ Istio ์ฑ„ํƒ์ด ์ฆ๊ฐ€ํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋ฉ๋‹ˆ๋‹ค.

Last updated

Was this helpful?