๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ“š Book Review/๐Ÿ“˜ Kubernetes Best Practice

[Kubernetes Best Practice] 4. ์„ค์ •, ์‹œํฌ๋ฆฟ, RBAC

by Seongpyo Hong 2021. 2. 22.

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

์ตœ๊ทผ ์„œ๋น„์Šค ๋ฉ”์‹œ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฑฐ๋‚˜ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๊ณต๋ถ€ํ•˜๋ฉด์„œ ๊ฐ€์žฅ ๋งŽ์ด ๋“ค์—ˆ๋˜ ์ƒ๊ฐ์€ ์ด ๋ฐฉ๋ฒ•์ด ์ตœ์„ ์ธ๊ฐ€? ๋ผ๋Š” ์ƒ๊ฐ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์ด์— ๋Œ€ํ•œ ๊ถ๊ธˆ์ฆ์„ ํ•ด๊ฒฐํ•˜๋Š”๋ฐ ๋„์›€์ด ๋ ๋งŒํ•œ ์ฑ…์„ ๋ฐœ๊ฒฌํ•ด์„œ ์ฝ์–ด๋ณด๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค.


ConfigMap & Secret

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

Secret์€ base64 ๋ฐฉ์‹์œผ๋กœ ์ธ์ฝ”๋”ฉ๋˜์–ด ํ‘œํ˜„๋ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์•”ํ˜ธํ™”๊ฐ€ ์•„๋‹Œ ์ธ์ฝ”๋”ฉ์ด๊ธฐ ๋•Œ๋ฌธ์— Pod์— ์ฃผ์ž…๋œ ์ˆœ๊ฐ„ ์ผ๋ฐ˜ ํ…์ŠคํŠธ ํ˜•ํƒœ๋กœ ๋ณด์—ฌ์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. (ConfigMap๊ณผ ๋™์ผํ•˜๊ฒŒ ์•”ํ˜ธํ™”๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์™œ Secret์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ผ๊นŒ?๋ผ๋Š” ๊ถ๊ธˆ์ฆ์ด ์ƒ๊ฒผ๋Š”๋ฐ ์กฐ๋Œ€ํ˜‘๋‹˜์˜ ๊ธ€์„ ์ฐธ๊ณ ํ•˜๋ฉด SSL ์ธ์ฆ์„œ์™€ ๊ฐ™์€ ๋ฐ”์ด๋„ˆ๋ฆฌ ํŒŒ์ผ์˜ ๊ฒฝ์šฐ์—๋Š” ๋ฌธ์ž์—ด๋กœ ์ €์žฅ์ด ๋ถˆ๊ฐ€๋Šฅ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ธ์ฝ”๋”ฉํ•˜์—ฌ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์›ํ•˜๊ธฐ ์œ„ํ•จ์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.)

Secret์ด ์ง€์›ํ•˜๋Š” ํƒ€์ž…์œผ๋กœ๋Š” ์ผ๋ฐ˜ ํŒŒ์ผ์ด๋‚˜ ๋ฌธ์ž์—ด ์ƒ์ˆ˜๋กœ ์ƒ์„ฑ๋˜๋Š” generic ๊ณผ docker registry ์ธ์ฆ์— ํ•„์š”ํ•œ ์‹ ์›์ธ docker-registry, public/private key๋กœ ์ƒ์„ฑ๋˜๋Š” TLS Secret์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์œผ๋กœ ์ •์˜๋œ Secret์€ ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” Pod๊ฐ€ ๋– ์žˆ๋Š” Node์˜ tmpfs์— ๋งˆ์šดํŠธ๋˜๊ณ  Pod์ด ์ข…๋ฃŒ๋˜๋ฉด ํ•ด๋‹น Secret์€ ์‚ญ์ œ๋ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ etcd์—๋Š” ํ‰๋ฌธ์œผ๋กœ ์ €์žฅ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ณด์•ˆ์„ ์œ„ํ•ด์„œ๋Š” etcd ๋…ธ๋“œ๊ฐ„ mTLS ๋ฐ ๋ฐ์ดํ„ฐ ์ €์žฅ ์‹œ ์•”ํ˜ธํ™”๋ฅผ ํ•˜๋Š” ๋ฐฉ๋ฒ• ๋“ฑ์˜ ๋ณ„๋„์˜ ๋ฐฉ์•ˆ์ด๋‚˜ Hasicorp Valut์™€ ๊ฐ™์€ KMS Solution์„ ๊ณ ๋ คํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. 


ConfigMap & Secret ๋ณ€๊ฒฝ

ConfigMap ๋ฐ Secret์„ ์ฃผ์ž…ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ ๋ณผ๋ฅจ ๋งˆ์šดํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ๋‘ ๋ฐฉ๋ฒ•์€ ์„ค์ •์ด ๋ณ€๊ฒฝ๋˜์—ˆ์„ ๋•Œ ๋™์ž‘ํ•˜๋Š” ๋ฐฉ์‹์— ์žˆ์–ด ์ฐจ์ด์ ์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

Volume Mount
๋จผ์ € ๋ณผ๋ฅจ์œผ๋กœ ๋งˆ์šดํŠธ ํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ConfigMap/Secret์˜ ์†์„ฑ ์ด๋ฆ„์€ ๋งˆ์šดํŠธ ๋œ ๋ณผ๋ฅจ์˜ ํŒŒ์ผ๋ช…์ด ๋˜๊ณ , ๊ฐ’์€ ํŒŒ์ผ ๋‚ด์šฉ์ด ๋ฉ๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์€ ์„ค์ •์ด ๋ณ€๊ฒฝ ๋์„ ๋•Œ ์ƒˆ๋กœ์šด ๋ฒ„์ „์˜ Pod์„ ๋‹ค์‹œ ๋ฐฐํฌํ•˜์ง€ ์•Š์•„๋„ ๋ณ€๊ฒฝ์„ ๊ฐ์ง€ํ•˜๊ณ  ์—…๋ฐ์ดํŠธ๋ฉ๋‹ˆ๋‹ค. ๋ฌธ์„œ๋ฅผ ์‚ดํŽด๋ณด๋ฉด kubelet์„ ํ†ตํ•ด ๋™๊ธฐํ™” ์ž‘์—…์ด ์ˆ˜ํ–‰๋˜๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.(๋ฌผ๋ก  ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ์˜ ์žฌ์‹œ์ž‘์ด ํ•„์š”ํ• ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.)  

์ด ๋ฐฉ๋ฒ•์œผ๋กœ Pod์ด ๋ฐฐํฌ๋˜๊ธฐ ์ „์— ๋™์ผํ•œ ๋„ค์ž„์ŠคํŽ˜์ด์Šค ์•ˆ์— ConfigMap/Secret์ด ์กด์žฌํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ ๊ธฐ๋ณธ๊ฐ’์€ Pod์ด ์‹คํ–‰๋˜์ง€ ์•Š์ง€๋งŒ `Optional` ํ•„๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์กด์žฌํ•˜์ง€ ์•Š๋”๋ผ๋„ Pod์ด ์‹œ์ž‘๋˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
    - name: test-container
      image: gcr.io/google_containers/busybox
      command: [ "/bin/sh", "-c", "env" ]
      env: 
        - name: OPTIONAL_ENV
          valueFrom:
            configMapKeyRef:
              name: test-cm
              key: optional.key 
              optional: true 

Admission Controller๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํŠน์ • ์„ค์ •๋ฐ์ดํ„ฐ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ๋ฐฐํฌ๋ฅผ ๋ง‰์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
(Admission Controller๋ž€ Kubernetes API๋ฅผ ํ˜ธ์ถœํ–ˆ์„ ๋•Œ ํ•ด๋‹น ์š”์ฒญ์˜ ๋‚ด์šฉ์„ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ ๊ฒ€์ฆํ•˜๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์˜ ์ง‘ํ•ฉ์œผ๋กœ Istio์˜ Envoy Proxy Injection, ResourceQuota ๋“ฑ์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. Admission Controller์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๊ณต์‹ ๋ฌธ์„œ๋‚˜ alice_k106๋‹˜์˜ ๋ธ”๋กœ๊ทธ์—์„œ ํ™•์ธํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.).
๋งŒ์•ฝ Admission Controller๋ฅผ ์ •์˜ํ•˜๋Š” ๊ฒƒ์ด ์ œํ•œ๋œ๋‹ค๋ฉด LifeCycle Hook์„ ํ†ตํ•ด ConfigMap/Secret์˜ ๋ฐฐํฌ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

Environment Variable
๋‹ค์Œ์€ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋กœ ์„ค์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. envFrom์„ ํ†ตํ•ด ConfigMap/Secret ๋‚ด ๋ชจ๋“  ๊ฐ’๋“ค์„ ํ™˜๊ฒฝ๋ณ€์ˆ˜๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๊ณ  configMapKeyRef / secretKeyRef๋ฅผ ํ†ตํ•ด ๊ฐœ๋ณ„์ ์œผ๋กœ ์„ค์ •๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ๋ณ„์ ์œผ๋กœ ์„ค์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ConfigMap/Secret์ด ๋ฐฐํฌ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ Pod์˜ ์‹œ์ž‘์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ envFrom์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ๋ถ€์ ํ•ฉํ•œ ๊ฐ’์— ๋Œ€ํ•ด InvalidVariableName์ด๋ผ๋Š” ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  ํ•ด๋‹น ๊ฐ’์„ ๊ฑด๋„ˆ๋›ด ์ฑ„๋กœ Pod์ด ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค. 

์ด ๋ฐฉ๋ฒ•์˜ ๊ฒฝ์šฐ ๋ณผ๋ฅจ ๋งˆ์šดํŠธ์™€๋Š” ๋‹ค๋ฅด๊ฒŒ ConfigMap/Secret์„ ์—…๋ฐ์ดํŠธ ํ•˜๋Š” ๊ฒฝ์šฐ Pod ์•ˆ์— ๊ฐ’์€ ์—…๋ฐ์ดํŠธ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ Pod์˜ ์‚ญ์ œ ํ›„ ์žฌ์‹œ์ž‘์ด๋‚˜ Deployment์˜ ์—…๋ฐ์ดํŠธ๋ฅผ ํ†ตํ•ด ์žฌ์‹œ์ž‘ํ•˜๋Š” ์ „๋žต์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ฑ…์—์„œ ์ถ”์ฒœํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ConfigMap/Secret์˜ ์ด๋ฆ„๊ณผ deployment์—์„œ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š” ConfigMap์„ ๋ณ€๊ฒฝํ•จ์œผ๋กœ์จ ์ž๋™์œผ๋กœ Deployment๊ฐ€ ์—…๋ฐ์ดํŠธ ๋˜๋„๋ก ์„ค์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.


 

๋ฆฌ์†Œ์Šค ์ ‘๊ทผ ์ œํ•œ ์ „๋žต

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์—์„œ ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ ์ ‘๊ทผ ์ œํ•œ์„ ์œ„ํ•œ ํ”„๋กœ์„ธ์Šค๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

User Account, Service Account๋ฅผ ํ†ตํ•ด ์ธ์ฆ๋œ ์‚ฌ์šฉ์ž๋ฅผ ๊ด€๋ฆฌ - ์ธ์ฆ
RBAC๋ฅผ ํ†ตํ•ด ์ธ์ฆ๋œ ์‚ฌ์šฉ์ž์—๊ฒŒ ์—ฌ๋Ÿฌ API์— ๋Œ€ํ•œ ๊ถŒํ•œ์„ ๋ถ€์—ฌ - ์ธ๊ฐ€


RBAC

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

RBAC๋ฅผ ์ ์šฉํ•˜๋ฉด ์ฃผ์˜ํ•ด์•ผํ•  ์ ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • Kubernetes API์— ์ ‘๊ทผํ•˜๊ณ ์ž ํ•˜๋Š” ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•œ๋‹ค๋ฉด ์ƒˆ๋กœ์šด Service Account๋ฅผ ๋งŒ๋“ค๊ณ  ์ตœ์†Œํ•œ์˜ ๊ถŒํ•œ๋งŒ์„ ๊ฐ€์ง€๋Š” Role์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.
  • CI/CD Tool์„ ์‚ฌ์šฉํ•  ๋–„์—๋Š” ์ด๋ฅผ ์œ„ํ•œ ์„œ๋น„์Šค ๊ณ„์ •์„ ์‚ฌ์šฉํ•ด์„œ ์˜ค๋ธŒ์ ํŠธ์˜ ๋ฐฐํฌ ๋ฐ ์‚ญ์ œ์— ๋Œ€ํ•œ ๊ฐ์‹œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด์™ธ์—๋„ ๋ช‡๊ฐ€์ง€ ๊ถŒ์žฅ ์‚ฌํ•ญ์ด ์กด์žฌํ•˜์ง€๋งŒ ํ˜„์žฌ๋Š” ์ดํ•ดํ•  ์ˆ˜ ์—†๋Š” ๋ถ€๋ถ„์ด์—ฌ์„œ ์ดํ•ด๋˜๋Š” ๋ถ€๋ถ„๋งŒ ์ž‘์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๋Œ“๊ธ€