Post

[Kubernetes] ๐Ÿ›ก๏ธ OPA Gatekeeper vs Kyverno: ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ์ •์ฑ… ๊ด€๋ฆฌ ์™„์ „ ๊ฐ€์ด๋“œ

[Kubernetes] ๐Ÿ›ก๏ธ OPA Gatekeeper vs Kyverno: ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ์ •์ฑ… ๊ด€๋ฆฌ ์™„์ „ ๊ฐ€์ด๋“œ

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์šด์˜ํ•˜๋‹ค ๋ณด๋ฉด โ€œ๋ชจ๋“  Pod์— ๋ฆฌ์†Œ์Šค ์ œํ•œ์„ ์„ค์ •ํ•ด์•ผ ํ•œ๋‹คโ€, โ€œ์Šน์ธ๋œ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์˜ ์ด๋ฏธ์ง€๋งŒ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹คโ€์ฒ˜๋Ÿผ ์กฐ์ง ์ฐจ์›์˜ ์ •์ฑ…์„ ๊ฐ•์ œํ•ด์•ผ ํ•˜๋Š” ์ƒํ™ฉ์ด ์ƒ๊น๋‹ˆ๋‹ค. ์ด๋ฅผ ์ฝ”๋“œ ๋ฆฌ๋ทฐ์—๋งŒ ์˜์กดํ•˜๋ฉด ๋ˆ„๋ฝ์ด ๋ฐœ์ƒํ•˜๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค. OPA Gatekeeper์™€ Kyverno๋Š” ์ด๋Ÿฐ ์ •์ฑ…์„ ํด๋Ÿฌ์Šคํ„ฐ ๋ ˆ๋ฒจ์—์„œ ์ž๋™์œผ๋กœ ๊ฐ•์ œํ•˜๋Š” ๋Œ€ํ‘œ์ ์ธ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.


๐Ÿ”‘ Kubernetes ์ •์ฑ… ๊ด€๋ฆฌ๋ž€?

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค๋Š” ๋ฆฌ์†Œ์Šค ์ƒ์„ฑยท์ˆ˜์ •ยท์‚ญ์ œ ์š”์ฒญ์ด API ์„œ๋ฒ„์— ๋„๋‹ฌํ–ˆ์„ ๋•Œ ์ด๋ฅผ ๊ฒ€์‚ฌํ•˜๋Š” Admission Controller ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

1
2
3
4
5
6
7
8
kubectl apply
    โ†“
API Server
    โ†“
Authentication โ†’ Authorization โ†’ Admission Control โ†’ etcd ์ €์žฅ
                                       โ†‘
                            Mutating / Validating Webhook
                          (Gatekeeper / Kyverno ๊ฐ€ ์—ฌ๊ธฐ์„œ ๋™์ž‘)

๋‘ ๋„๊ตฌ ๋ชจ๋‘ Webhook ํ˜•ํƒœ๋กœ ๋™์ž‘ํ•˜๋ฉฐ ์š”์ฒญ์„ ๊ฐ€๋กœ์ฑ„ ์ •์ฑ… ์ค€์ˆ˜ ์—ฌ๋ถ€๋ฅผ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค.

Tip: ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค 1.25์—์„œ Pod Security Policy(PSP)๊ฐ€ ์ œ๊ฑฐ๋œ ์ดํ›„ OPA Gatekeeper์™€ Kyverno๊ฐ€ PSP์˜ ์‹ค์งˆ์ ์ธ ๋Œ€์•ˆ์œผ๋กœ ์ž๋ฆฌ์žก์•˜์Šต๋‹ˆ๋‹ค.


๐Ÿ”ต OPA Gatekeeper

๊ฐœ๋… ๋ฐ ์•„ํ‚คํ…์ฒ˜

OPA(Open Policy Agent) ๋Š” CNCF์—์„œ ๊ด€๋ฆฌํ•˜๋Š” ๋ฒ”์šฉ ์ •์ฑ… ์—”์ง„์ž…๋‹ˆ๋‹ค. Gatekeeper๋Š” OPA๋ฅผ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค Admission Webhook๊ณผ ์—ฐ๊ฒฐํ•˜๋Š” ๋ธŒ๋ฆฌ์ง€ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

1
2
3
4
5
6
7
8
9
10
API Server
    โ”‚ AdmissionReview ์š”์ฒญ
    โ–ผ
Gatekeeper Webhook
    โ”‚ Rego ์ •์ฑ… ํ‰๊ฐ€
    โ–ผ
OPA (์ •์ฑ… ํ‰๊ฐ€ ์—”์ง„)
    โ”‚ allow / deny ๋ฐ˜ํ™˜
    โ–ผ
API Server (์š”์ฒญ ํ—ˆ์šฉ or ๊ฑฐ๋ถ€)

Gatekeeper v3.0๋ถ€ํ„ฐ๋Š” OPA Constraint Framework๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ CRD(Custom Resource Definition)๋ฅผ ํ†ตํ•ด ์ •์ฑ…์„ ์„ ์–ธ์ ์œผ๋กœ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

ConstraintTemplate โ€” ์ •์ฑ… ํ…œํ”Œ๋ฆฟ ์ •์˜

ConstraintTemplate์€ ์ •์ฑ…์˜ ๋กœ์ง(Rego)๊ณผ ํŒŒ๋ผ๋ฏธํ„ฐ ์Šคํ‚ค๋งˆ๋ฅผ ์ •์˜ํ•˜๋Š” ์ฒญ์‚ฌ์ง„์ž…๋‹ˆ๋‹ค. ํ•œ ๋ฒˆ ์ •์˜ํ•˜๋ฉด ์—ฌ๋Ÿฌ ํด๋Ÿฌ์Šคํ„ฐ, ์—ฌ๋Ÿฌ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  name: k8srequiredlabels
spec:
  crd:
    spec:
      names:
        kind: K8sRequiredLabels
      validation:
        openAPIV3Schema:
          properties:
            labels:
              type: array
              items:
                type: string
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8srequiredlabels

        deny[{"msg": msg, "details": {"missing_labels": missing}}] {
          provided := {label | input.review.object.metadata.labels[label]}
          required := {label | label := input.parameters.labels[_]}
          missing := required - provided
          count(missing) > 0
          msg := sprintf("ํ•„์ˆ˜ ๋ ˆ์ด๋ธ”์ด ๋ˆ„๋ฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค: %v", [missing])
        }

Constraint โ€” ์ •์ฑ… ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ

ConstraintTemplate์œผ๋กœ ๋งŒ๋“ค์–ด์ง„ CRD๋ฅผ ์ธ์Šคํ„ด์Šคํ™”ํ•˜์—ฌ ์‹ค์ œ ์ •์ฑ…์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. match ํ•„๋“œ๋กœ ์ ์šฉ ๋Œ€์ƒ์„ ์„ธ๋ฐ€ํ•˜๊ฒŒ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
  name: ns-must-have-owner
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Namespace"]
  parameters:
    labels: ["owner", "env"]

์œ„ ์ •์ฑ… ์ ์šฉ ํ›„ owner, env ๋ ˆ์ด๋ธ” ์—†์ด ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋ฉด ์•„๋ž˜์ฒ˜๋Ÿผ ๊ฑฐ๋ถ€๋ฉ๋‹ˆ๋‹ค.

1
Error from server ([ns-must-have-owner] ํ•„์ˆ˜ ๋ ˆ์ด๋ธ”์ด ๋ˆ„๋ฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค: {"env", "owner"})

์„ค์น˜

1
2
3
4
5
6
# Helm์œผ๋กœ ์„ค์น˜
helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts
helm install gatekeeper/gatekeeper \
  --name-template=gatekeeper \
  --namespace gatekeeper-system \
  --create-namespace
1
2
# ๋˜๋Š” manifest๋กœ ์„ค์น˜
kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/master/deploy/gatekeeper.yaml

์„ค์น˜ ํ›„ gatekeeper-system ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ์ปจํŠธ๋กค๋Ÿฌ ํŒŒ๋“œ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

1
2
3
4
kubectl get pods -n gatekeeper-system
# NAME                                             READY   STATUS
# gatekeeper-audit-xxxxxxxxx                       1/1     Running
# gatekeeper-controller-manager-xxxxxxxxx          1/1     Running

Audit ๊ธฐ๋Šฅ

Gatekeeper๋Š” Audit ๊ธฐ๋Šฅ์„ ํ†ตํ•ด ์ด๋ฏธ ๋ฐฐํฌ๋œ ๋ฆฌ์†Œ์Šค๋„ ์ •์ฑ… ์œ„๋ฐ˜ ์—ฌ๋ถ€๋ฅผ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ •์ฑ… ์ ์šฉ ์‹œ์  ์ด์ „์— ์ƒ์„ฑ๋œ ๋ฆฌ์†Œ์Šค๊นŒ์ง€ ์†Œ๊ธ‰ ๊ฒ€์‚ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

1
2
3
# ์ •์ฑ… ์œ„๋ฐ˜ ๋ฆฌ์†Œ์Šค ํ™•์ธ
kubectl get k8srequiredlabels ns-must-have-owner -o yaml
# status.violations ํ•„๋“œ์— ์œ„๋ฐ˜ ๋ฆฌ์†Œ์Šค ๋ชฉ๋ก์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค

๋˜ํ•œ ํด๋Ÿฌ์Šคํ„ฐ ๋‚ด ๋ฆฌ์†Œ์Šค๋ฅผ Gatekeeper์— ๋ณต์ œํ•˜์—ฌ ์ •์ฑ… ๊ฐ„ ๋ฐ์ดํ„ฐ ์ฐธ์กฐ๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
apiVersion: config.gatekeeper.sh/v1alpha1
kind: Config
metadata:
  name: config
  namespace: gatekeeper-system
spec:
  sync:
    syncOnly:
      - group: ""
        version: "v1"
        kind: "Namespace"

๐ŸŸข Kyverno

๊ฐœ๋… ๋ฐ ์•„ํ‚คํ…์ฒ˜

Kyverno๋Š” Kubernetes Native ์ •์ฑ… ์—”์ง„์ž…๋‹ˆ๋‹ค. ์ •์ฑ…์„ Rego ๊ฐ™์€ ๋ณ„๋„ ์–ธ์–ด ์—†์ด ์ˆœ์ˆ˜ YAML(CR)๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์–ด ํ•™์Šต ๊ณก์„ ์ด ๋‚ฎ์Šต๋‹ˆ๋‹ค.

1
2
3
4
5
6
7
8
API Server
    โ”‚ AdmissionReview ์š”์ฒญ
    โ–ผ
Kyverno Webhook
    โ”‚ ClusterPolicy / Policy ํ‰๊ฐ€
    โ”œโ”€โ”€ Mutate  โ†’ ๋ฆฌ์†Œ์Šค ์ž๋™ ์ˆ˜์ • ํ›„ ํ—ˆ์šฉ
    โ”œโ”€โ”€ Validate โ†’ ๊ฒ€์ฆ ์‹คํŒจ ์‹œ ๊ฑฐ๋ถ€
    โ””โ”€โ”€ Generate โ†’ ์ƒˆ ๋ฆฌ์†Œ์Šค ์ž๋™ ์ƒ์„ฑ

Kyverno๋Š” 4๊ฐœ์˜ ์ปจํŠธ๋กค๋Ÿฌ๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค.

์ปจํŠธ๋กค๋Ÿฌ์—ญํ• 
WebhookAdmissionReview ์š”์ฒญ ์ฒ˜๋ฆฌ
Monitorํ•„์ˆ˜ ์„ค์ •(์›นํ›… ๋“ฑ) ์œ ์ง€ ๊ด€๋ฆฌ
PolicyController์ •์ฑ… CR ๋ณ€๊ฒฝ ๊ฐ์‹œ
GenerateControllerGenerate ์ •์ฑ…์œผ๋กœ ์ƒ์„ฑ๋œ ๋ฆฌ์†Œ์Šค ๊ด€๋ฆฌ

์„ค์น˜

1
2
3
4
5
6
# Helm์œผ๋กœ ์„ค์น˜ (๊ถŒ์žฅ)
helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo update
helm install kyverno kyverno/kyverno \
  -n kyverno \
  --create-namespace
1
2
# ๋˜๋Š” manifest๋กœ ์„ค์น˜
kubectl create -f https://raw.githubusercontent.com/kyverno/kyverno/main/config/install.yaml

โš ๏ธ Kyverno๋Š” Kubernetes 1.14 ์ด์ƒ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๊ณ ๊ฐ€์šฉ์„ฑ ํ™˜๊ฒฝ์—์„œ๋Š” replicaCount=3์œผ๋กœ ์„ค์ •์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.

์ •์ฑ… ์œ ํ˜•

Kyverno ์ •์ฑ…์€ ClusterPolicy(ํด๋Ÿฌ์Šคํ„ฐ ์ „์ฒด) ๋˜๋Š” Policy(๋„ค์ž„์ŠคํŽ˜์ด์Šค ๋ฒ”์œ„) ๋‘ ๊ฐ€์ง€ ์Šค์ฝ”ํ”„๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

์œ ํ˜•์„ค๋ช…์‹คํ–‰ ์‹œ์ 
Validate๋ฆฌ์†Œ์Šค๊ฐ€ ์ •์ฑ…์„ ์ค€์ˆ˜ํ•˜๋Š”์ง€ ๊ฒ€์ฆ์ƒ์„ฑยท์ˆ˜์ • ์‹œ
Mutate๋ฆฌ์†Œ์Šค๋ฅผ ์ž๋™์œผ๋กœ ์ˆ˜์ •์ƒ์„ฑยท์ˆ˜์ • ์‹œ (Validate ์ „)
Generate์ƒˆ๋กœ์šด ๋ฆฌ์†Œ์Šค๋ฅผ ์ž๋™ ์ƒ์„ฑํŠธ๋ฆฌ๊ฑฐ ๋ฆฌ์†Œ์Šค ์ƒ์„ฑ ์‹œ
Cleanup๋ถˆํ•„์š”ํ•œ ๋ฆฌ์†Œ์Šค๋ฅผ ์ž๋™ ์‚ญ์ œ์ฃผ๊ธฐ์  ์‹คํ–‰

Validate ์˜ˆ์ œ: ํ•„์ˆ˜ ๋ ˆ์ด๋ธ” ๊ฐ•์ œ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-app-label
spec:
  validationFailureAction: Enforce   # Audit์œผ๋กœ ๋ณ€๊ฒฝํ•˜๋ฉด ๊ฐ์‚ฌ ๋ชจ๋“œ
  rules:
    - name: check-app-label
      match:
        any:
          - resources:
              kinds:
                - Pod
      validate:
        message: "๋ ˆ์ด๋ธ” 'app.kubernetes.io/name' ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค."
        pattern:
          metadata:
            labels:
              app.kubernetes.io/name: "?*"

์ •์ฑ… ์œ„๋ฐ˜ ์‹œ ์•„๋ž˜ ๋ฉ”์‹œ์ง€์™€ ํ•จ๊ป˜ ๊ฑฐ๋ถ€๋ฉ๋‹ˆ๋‹ค.

1
2
Error from server: admission webhook "validate.kyverno.svc-fail" denied the request:
resource Pod was blocked due to the following policies: require-app-label

Mutate ์˜ˆ์ œ: ๋ฆฌ์†Œ์Šค ์ œํ•œ ์ž๋™ ์ฃผ์ž…

๋ ˆ์ด๋ธ”์ด๋‚˜ ๋ฆฌ์†Œ์Šค ์ œํ•œ์ด ์—†๋Š” Pod์— ๊ธฐ๋ณธ๊ฐ’์„ ์ž๋™์œผ๋กœ ์‚ฝ์ž…ํ•ฉ๋‹ˆ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: add-default-resources
spec:
  rules:
    - name: add-resource-limits
      match:
        any:
          - resources:
              kinds:
                - Pod
      mutate:
        patchStrategicMerge:
          spec:
            containers:
              - (name): "*"
                resources:
                  limits:
                    +(memory): "256Mi"
                    +(cpu): "500m"

Tip: +() ํ‘œ๊ธฐ๋Š” ํ•ด๋‹น ํ•„๋“œ๊ฐ€ ์—†์„ ๋•Œ๋งŒ ๊ฐ’์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์กด ์„ค์ •์„ ๋ฎ์–ด์“ฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Generate ์˜ˆ์ œ: ๋„ค์ž„์ŠคํŽ˜์ด์Šค ์ƒ์„ฑ ์‹œ NetworkPolicy ์ž๋™ ์ƒ์„ฑ

์ƒˆ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ ๊ธฐ๋ณธ NetworkPolicy๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: default-network-policy
spec:
  rules:
    - name: default-deny-ingress
      match:
        any:
          - resources:
              kinds:
                - Namespace
      generate:
        apiVersion: networking.k8s.io/v1
        kind: NetworkPolicy
        name: default-deny-ingress
        namespace: ""
        synchronize: true
        data:
          spec:
            podSelector: {}
            policyTypes:
              - Ingress

โš–๏ธ OPA Gatekeeper vs Kyverno ๋น„๊ต

ํ•ญ๋ชฉOPA GatekeeperKyverno
์ •์ฑ… ์–ธ์–ดRego (์ „์šฉ DSL)YAML (Kubernetes ๋„ค์ดํ‹ฐ๋ธŒ)
ํ•™์Šต ๊ณก์„ ๋†’์Œ (Rego ํ•™์Šต ํ•„์š”)๋‚ฎ์Œ
์ ์šฉ ๋ฒ”์œ„๋ฉ€ํ‹ฐ ํ”Œ๋žซํผ (์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ์™ธ ์ง€์›)์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ์ „์šฉ
์ •์ฑ… ์œ ํ˜•Validate, AuditValidate, Mutate, Generate, Cleanup
Mutate ์ง€์›์ œํ•œ์ ๊ฐ•๋ ฅํ•œ ๊ธฐ๋ณธ ์ง€์›
Generate ์ง€์›โœ—โœ…
Auditโœ… (๋‚ด์žฅ)โœ… (๋‚ด์žฅ)
CLI ๋„๊ตฌOPA CLIKyverno CLI
CNCF ๋“ฑ๊ธ‰GraduatedIncubating
์ปค๋ฎค๋‹ˆํ‹ฐ ์„ฑ์ˆ™๋„๋†’์Œ๋น ๋ฅด๊ฒŒ ์„ฑ์žฅ ์ค‘

๐ŸŽฏ ์–ด๋–ค ๊ฒƒ์„ ์„ ํƒํ• ๊นŒ?

OPA Gatekeeper๋ฅผ ์„ ํƒํ•ด์•ผ ํ•  ๋•Œ:

  • ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ์™ธ ๋‹ค๋ฅธ ์‹œ์Šคํ…œ(Terraform, API ์„œ๋ฒ„ ๋“ฑ)์—๋„ ๋™์ผํ•œ ์ •์ฑ… ์—”์ง„์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ
  • ์ •์ฑ… ๋กœ์ง์ด ๋ณต์žกํ•˜์—ฌ Rego์˜ ํ‘œํ˜„๋ ฅ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ
  • ์ด๋ฏธ OPA ์ƒํƒœ๊ณ„๋ฅผ ์‚ฌ์šฉ ์ค‘์ธ ๊ฒฝ์šฐ

Kyverno๋ฅผ ์„ ํƒํ•ด์•ผ ํ•  ๋•Œ:

  • ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ์ „์šฉ ์ •์ฑ… ๊ด€๋ฆฌ๊ฐ€ ๋ชฉ์ ์ธ ๊ฒฝ์šฐ
  • Rego ํ•™์Šต ์—†์ด ๋น ๋ฅด๊ฒŒ ๋„์ž…ํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ
  • Mutate, Generate ๋“ฑ ๋‹ค์–‘ํ•œ ์ •์ฑ… ์œ ํ˜•์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ
  • GitOps ํ™˜๊ฒฝ์—์„œ YAML ๊ธฐ๋ฐ˜์œผ๋กœ ์ •์ฑ…์„ ๊ด€๋ฆฌํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ

Tip: ๋‘ ๋„๊ตฌ๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋ณต์žกํ•œ ๊ฒ€์ฆ ์ •์ฑ…์€ OPA Gatekeeper๋กœ, ๋ฆฌ์†Œ์Šค ์ž๋™ ๋ณ€ํ˜•ยท์ƒ์„ฑ์€ Kyverno๋กœ ์—ญํ• ์„ ๋ถ„๋‹ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

This post is licensed under CC BY 4.0 by the author.