Information in this document may be out of date

This document has an older update date than the original, so the information it contains may be out of date. If you're able to read English, see the English version for the most up-to-date information: Apply Pod Security Standards at the Cluster Level

ํŒŒ๋“œ ์‹œํ๋ฆฌํ‹ฐ ์Šคํƒ ๋‹ค๋“œ๋ฅผ ํด๋Ÿฌ์Šคํ„ฐ ์ˆ˜์ค€์— ์ ์šฉํ•˜๊ธฐ

ํŒŒ๋“œ ์‹œํ๋ฆฌํ‹ฐ ์–ด๋“œ๋ฏธ์…˜(PSA, Pod Security Admission)์€ ๋ฒ ํƒ€๋กœ ๋ณ€๊ฒฝ๋˜์–ด v1.23 ์ด์ƒ์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ํ™œ์„ฑํ™”๋˜์–ด ์žˆ๋‹ค. ํŒŒ๋“œ ์‹œํ๋ฆฌํ‹ฐ ์–ด๋“œ๋ฏธ์…˜์€ ํŒŒ๋“œ๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ ํŒŒ๋“œ ์‹œํ๋ฆฌํ‹ฐ ์Šคํƒ ๋‹ค๋“œ(Pod Security Standards)๋ฅผ ์ ์šฉํ•˜๋Š” ์–ด๋“œ๋ฏธ์…˜ ์ปจํŠธ๋กค๋Ÿฌ์ด๋‹ค. ์ด ํŠœํ† ๋ฆฌ์–ผ์€ baseline ํŒŒ๋“œ ์‹œํ๋ฆฌํ‹ฐ ์Šคํƒ ๋‹ค๋“œ๋ฅผ ํด๋Ÿฌ์Šคํ„ฐ ์ˆ˜์ค€(level)์— ์ ์šฉํ•˜์—ฌ ํ‘œ์ค€ ๊ตฌ์„ฑ์„ ํด๋Ÿฌ์Šคํ„ฐ์˜ ๋ชจ๋“  ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ์ ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ ์ค€๋‹ค.

ํŒŒ๋“œ ์‹œํ๋ฆฌํ‹ฐ ์Šคํƒ ๋‹ค๋“œ๋ฅผ ํŠน์ • ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ์ ์šฉํ•˜๋ ค๋ฉด, ํŒŒ๋“œ ์‹œํ๋ฆฌํ‹ฐ ์Šคํƒ ๋‹ค๋“œ๋ฅผ ๋„ค์ž„์ŠคํŽ˜์ด์Šค ์ˆ˜์ค€์— ์ ์šฉํ•˜๊ธฐ๋ฅผ ์ฐธ๊ณ ํ•œ๋‹ค.

๋งŒ์•ฝ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ๋ฒ„์ „์ด v1.34์ด ์•„๋‹ˆ๋ผ๋ฉด, ํ•ด๋‹น ๋ฒ„์ „์˜ ๋ฌธ์„œ๋ฅผ ํ™•์ธํ•˜์ž.

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

์›Œํฌ์Šคํ…Œ์ด์…˜์— ๋‹ค์Œ์„ ์„ค์น˜ํ•œ๋‹ค.

์ ์šฉํ•  ์•Œ๋งž์€ ํŒŒ๋“œ ์‹œํ๋ฆฌํ‹ฐ ์Šคํƒ ๋‹ค๋“œ ์„ ํƒํ•˜๊ธฐ

ํŒŒ๋“œ ์‹œํ๋ฆฌํ‹ฐ ์–ด๋“œ๋ฏธ์…˜์„ ์ด์šฉํ•˜์—ฌ enforce, audit, ๋˜๋Š” warn ๋ชจ๋“œ ์ค‘ ํ•˜๋‚˜๋กœ ๋‚ด์žฅ ํŒŒ๋“œ ์‹œํ๋ฆฌํ‹ฐ ์Šคํƒ ๋‹ค๋“œ๋ฅผ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ˜„์žฌ ๊ตฌ์„ฑ์— ๊ฐ€์žฅ ์ ํ•ฉํ•œ ํŒŒ๋“œ ์‹œํ๋ฆฌํ‹ฐ ์Šคํƒ ๋‹ค๋“œ๋ฅผ ๊ณ ๋ฅด๋Š” ๋ฐ ๋„์›€์ด ๋˜๋Š” ์ •๋ณด๋ฅผ ์ˆ˜์ง‘ํ•˜๋ ค๋ฉด, ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

  1. ํŒŒ๋“œ ์‹œํ๋ฆฌํ‹ฐ ์Šคํƒ ๋‹ค๋“œ๊ฐ€ ์ ์šฉ๋˜์ง€ ์•Š์€ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

    kind create cluster --name psa-wo-cluster-pss --image kindest/node:v1.24.0
    

    ๋‹ค์Œ๊ณผ ๋น„์Šทํ•˜๊ฒŒ ์ถœ๋ ฅ๋  ๊ฒƒ์ด๋‹ค.

    Creating cluster "psa-wo-cluster-pss" ...
    โœ“ Ensuring node image (kindest/node:v1.24.0) ๐Ÿ–ผ
    โœ“ Preparing nodes ๐Ÿ“ฆ  
    โœ“ Writing configuration ๐Ÿ“œ
    โœ“ Starting control-plane ๐Ÿ•น๏ธ
    โœ“ Installing CNI ๐Ÿ”Œ
    โœ“ Installing StorageClass ๐Ÿ’พ
    Set kubectl context to "kind-psa-wo-cluster-pss"
    You can now use your cluster with:
    
    kubectl cluster-info --context kind-psa-wo-cluster-pss
    
    Thanks for using kind! ๐Ÿ˜Š
    
  2. kubectl context๋ฅผ ์ƒˆ๋กœ ์ƒ์„ฑํ•œ ํด๋Ÿฌ์Šคํ„ฐ๋กœ ์„ค์ •ํ•œ๋‹ค.

    kubectl cluster-info --context kind-psa-wo-cluster-pss
    

    ๋‹ค์Œ๊ณผ ๋น„์Šทํ•˜๊ฒŒ ์ถœ๋ ฅ๋  ๊ฒƒ์ด๋‹ค.

     Kubernetes control plane is running at https://127.0.0.1:61350
    
    CoreDNS is running at https://127.0.0.1:61350/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
    
    To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
    
  3. ํด๋Ÿฌ์Šคํ„ฐ์˜ ๋„ค์ž„์ŠคํŽ˜์ด์Šค ๋ชฉ๋ก์„ ์กฐํšŒํ•œ๋‹ค.

    kubectl get ns
    

    ๋‹ค์Œ๊ณผ ๋น„์Šทํ•˜๊ฒŒ ์ถœ๋ ฅ๋  ๊ฒƒ์ด๋‹ค.

    NAME                 STATUS   AGE
    default              Active   9m30s
    kube-node-lease      Active   9m32s
    kube-public          Active   9m32s
    kube-system          Active   9m32s
    local-path-storage   Active   9m26s
    
  4. --dry-run=server๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค๋ฅธ ํŒŒ๋“œ ์‹œํ๋ฆฌํ‹ฐ ์Šคํƒ ๋‹ค๋“œ๊ฐ€ ์ ์šฉ๋˜์—ˆ์„ ๋•Œ ์–ด๋–ค ๊ฒƒ์ด ๋ณ€๊ฒฝ๋˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.

    1. Privileged
      kubectl label --dry-run=server --overwrite ns --all \
      pod-security.kubernetes.io/enforce=privileged
      

    ๋‹ค์Œ๊ณผ ๋น„์Šทํ•˜๊ฒŒ ์ถœ๋ ฅ๋  ๊ฒƒ์ด๋‹ค.

    namespace/default labeled
    namespace/kube-node-lease labeled
    namespace/kube-public labeled
    namespace/kube-system labeled
    namespace/local-path-storage labeled
    
    1. Baseline
      kubectl label --dry-run=server --overwrite ns --all \
      pod-security.kubernetes.io/enforce=baseline
      

    ๋‹ค์Œ๊ณผ ๋น„์Šทํ•˜๊ฒŒ ์ถœ๋ ฅ๋  ๊ฒƒ์ด๋‹ค.

    namespace/default labeled
    namespace/kube-node-lease labeled
    namespace/kube-public labeled
    Warning: existing pods in namespace "kube-system" violate the new PodSecurity enforce level "baseline:latest"
    Warning: etcd-psa-wo-cluster-pss-control-plane (and 3 other pods): host namespaces, hostPath volumes
    Warning: kindnet-vzj42: non-default capabilities, host namespaces, hostPath volumes
    Warning: kube-proxy-m6hwf: host namespaces, hostPath volumes, privileged
    namespace/kube-system labeled
    namespace/local-path-storage labeled
    
    1. Restricted
     kubectl label --dry-run=server --overwrite ns --all \
     pod-security.kubernetes.io/enforce=restricted
    

    ๋‹ค์Œ๊ณผ ๋น„์Šทํ•˜๊ฒŒ ์ถœ๋ ฅ๋  ๊ฒƒ์ด๋‹ค.

    namespace/default labeled
    namespace/kube-node-lease labeled
    namespace/kube-public labeled
    Warning: existing pods in namespace "kube-system" violate the new PodSecurity enforce level "restricted:latest"
    Warning: coredns-7bb9c7b568-hsptc (and 1 other pod): unrestricted capabilities, runAsNonRoot != true, seccompProfile
    Warning: etcd-psa-wo-cluster-pss-control-plane (and 3 other pods): host namespaces, hostPath volumes, allowPrivilegeEscalation != false, unrestricted capabilities, restricted volume types, runAsNonRoot != true
    Warning: kindnet-vzj42: non-default capabilities, host namespaces, hostPath volumes, allowPrivilegeEscalation != false, unrestricted capabilities, restricted volume types, runAsNonRoot != true, seccompProfile
    Warning: kube-proxy-m6hwf: host namespaces, hostPath volumes, privileged, allowPrivilegeEscalation != false, unrestricted capabilities, restricted volume types, runAsNonRoot != true, seccompProfile
    namespace/kube-system labeled
    Warning: existing pods in namespace "local-path-storage" violate the new PodSecurity enforce level "restricted:latest"
    Warning: local-path-provisioner-d6d9f7ffc-lw9lh: allowPrivilegeEscalation != false, unrestricted capabilities, runAsNonRoot != true, seccompProfile
    namespace/local-path-storage labeled
    

์œ„์˜ ์ถœ๋ ฅ์—์„œ, privileged ํŒŒ๋“œ ์‹œํ๋ฆฌํ‹ฐ ์Šคํƒ ๋‹ค๋“œ๋ฅผ ์ ์šฉํ•˜๋ฉด ๋ชจ๋“  ๋„ค์ž„์ŠคํŽ˜์ด์Šค์—์„œ ๊ฒฝ๊ณ ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ baseline ๋ฐ restricted ํŒŒ๋“œ ์‹œํ๋ฆฌํ‹ฐ ์Šคํƒ ๋‹ค๋“œ์— ๋Œ€ํ•ด์„œ๋Š” kube-system ๋„ค์ž„์ŠคํŽ˜์ด์Šค์—์„œ ๊ฒฝ๊ณ ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

๋ชจ๋“œ, ๋ฒ„์ „, ๋ฐ ํŒŒ๋“œ ์‹œํ๋ฆฌํ‹ฐ ์Šคํƒ ๋‹ค๋“œ ์„ค์ •

์ด ์„น์…˜์—์„œ๋Š”, ๋‹ค์Œ์˜ ํŒŒ๋“œ ์‹œํ๋ฆฌํ‹ฐ ์Šคํƒ ๋‹ค๋“œ๋ฅผ latest ๋ฒ„์ „์— ์ ์šฉํ•œ๋‹ค.

  • baseline ํŒŒ๋“œ ์‹œํ๋ฆฌํ‹ฐ ์Šคํƒ ๋‹ค๋“œ๋Š” enforce ๋ชจ๋“œ๋กœ ์ ์šฉ
  • restricted ํŒŒ๋“œ ์‹œํ๋ฆฌํ‹ฐ ์Šคํƒ ๋‹ค๋“œ๋Š” warn ๋ฐ audit ๋ชจ๋“œ๋กœ ์ ์šฉ

baseline ํŒŒ๋“œ ์‹œํ๋ฆฌํ‹ฐ ์Šคํƒ ๋‹ค๋“œ๋Š” ์˜ˆ์™ธ ๋ชฉ๋ก์„ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์œ ์ง€ํ•˜๊ณ  ์•Œ๋ ค์ง„ ๊ถŒํ•œ ์ƒ์Šน(privilege escalations)์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋Š” ํŽธ๋ฆฌํ•œ ์ ˆ์ถฉ์•ˆ์„ ์ œ๊ณตํ•œ๋‹ค.

์ถ”๊ฐ€์ ์œผ๋กœ, kube-system ๋‚ด์˜ ํŒŒ๋“œ๊ฐ€ ์‹คํŒจํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด, ํ•ด๋‹น ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋Š” ํŒŒ๋“œ ์‹œํ๋ฆฌํ‹ฐ ์Šคํƒ ๋‹ค๋“œ๊ฐ€ ์ ์šฉ๋˜์ง€ ์•Š๋„๋ก ์ œ์™ธํ•  ๊ฒƒ์ด๋‹ค.

์‚ฌ์šฉ ์ค‘์ธ ํ™˜๊ฒฝ์— ํŒŒ๋“œ ์‹œํ๋ฆฌํ‹ฐ ์–ด๋“œ๋ฏธ์…˜์„ ์ ์šฉํ•  ๋•Œ์—๋Š” ๋‹ค์Œ์˜ ์‚ฌํ•ญ์„ ๊ณ ๋ คํ•œ๋‹ค.

  1. ํด๋Ÿฌ์Šคํ„ฐ์— ์ ์šฉ๋œ ์œ„ํ—˜ ์ƒํƒœ์— ๋”ฐ๋ผ, restricted์™€ ๊ฐ™์€ ๋” ์—„๊ฒฉํ•œ ํŒŒ๋“œ ์‹œํ๋ฆฌํ‹ฐ ์Šคํƒ ๋‹ค๋“œ๊ฐ€ ๋” ์ข‹์„ ์ˆ˜๋„ ์žˆ๋‹ค.

  2. kube-system ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ์ ์šฉ ๋Œ€์ƒ์—์„œ ์ œ์™ธํ•˜๋ฉด ์ด ๋„ค์ž„์ŠคํŽ˜์ด์Šค์˜ ํŒŒ๋“œ๊ฐ€ privileged๋กœ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋‹ค. ์‹ค์ œ ์‚ฌ์šฉ ํ™˜๊ฒฝ์—์„œ๋Š”, ์ตœ์†Œ ๊ถŒํ•œ ์›์น™์„ ์ค€์ˆ˜ํ•˜๋„๋ก, ์ ‘๊ทผ์„ kube-system ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋กœ ์ œํ•œํ•˜๋Š” ์—„๊ฒฉํ•œ RBAC ์ •์ฑ…์„ ์ ์šฉํ•  ๊ฒƒ์„ ๊ฐ•๋ ฅํžˆ ๊ถŒ์žฅํ•œ๋‹ค.

  3. ํŒŒ๋“œ ์‹œํ๋ฆฌํ‹ฐ ์–ด๋“œ๋ฏธ์…˜ ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ์ด๋Ÿฌํ•œ ํŒŒ๋“œ ์‹œํ๋ฆฌํ‹ฐ ์Šคํƒ ๋‹ค๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ตฌ์„ฑ ํŒŒ์ผ์„ ์ƒ์„ฑํ•œ๋‹ค.

    mkdir -p /tmp/pss
    cat <<EOF > /tmp/pss/cluster-level-pss.yaml 
    apiVersion: apiserver.config.k8s.io/v1
    kind: AdmissionConfiguration
    plugins:
    - name: PodSecurity
      configuration:
        apiVersion: pod-security.admission.config.k8s.io/v1
        kind: PodSecurityConfiguration
        defaults:
          enforce: "baseline"
          enforce-version: "latest"
          audit: "restricted"
          audit-version: "latest"
          warn: "restricted"
          warn-version: "latest"
        exemptions:
          usernames: []
          runtimeClasses: []
          namespaces: [kube-system]
    EOF
    
  4. API ์„œ๋ฒ„๊ฐ€ ํด๋Ÿฌ์Šคํ„ฐ ์ƒ์„ฑ ๊ณผ์ •์—์„œ ์ด ํŒŒ์ผ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌ์„ฑํ•œ๋‹ค.

    cat <<EOF > /tmp/pss/cluster-config.yaml 
    kind: Cluster
    apiVersion: kind.x-k8s.io/v1alpha4
    nodes:
    - role: control-plane
      kubeadmConfigPatches:
      - |
        kind: ClusterConfiguration
        apiServer:
            extraArgs:
              admission-control-config-file: /etc/config/cluster-level-pss.yaml
            extraVolumes:
              - name: accf
                hostPath: /etc/config
                mountPath: /etc/config
                readOnly: false
                pathType: "DirectoryOrCreate"
      extraMounts:
      - hostPath: /tmp/pss
        containerPath: /etc/config
        # optional: if set, the mount is read-only.
        # default false
        readOnly: false
        # optional: if set, the mount needs SELinux relabeling.
        # default false
        selinuxRelabel: false
        # optional: set propagation mode (None, HostToContainer or Bidirectional)
        # see https://kubernetes.io/ko/docs/concepts/storage/volumes/#๋งˆ์šดํŠธ-์ „ํŒŒ-propagation
        # default None
        propagation: None
    EOF
    
  5. ์ด๋Ÿฌํ•œ ํŒŒ๋“œ ์‹œํ๋ฆฌํ‹ฐ ์Šคํƒ ๋‹ค๋“œ๋ฅผ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด ํŒŒ๋“œ ์‹œํ๋ฆฌํ‹ฐ ์–ด๋“œ๋ฏธ์…˜์„ ์‚ฌ์šฉํ•˜๋Š” ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

     kind create cluster --name psa-with-cluster-pss --image kindest/node:v1.24.0 --config /tmp/pss/cluster-config.yaml
    

    ๋‹ค์Œ๊ณผ ๋น„์Šทํ•˜๊ฒŒ ์ถœ๋ ฅ๋  ๊ฒƒ์ด๋‹ค.

     Creating cluster "psa-with-cluster-pss" ...
      โœ“ Ensuring node image (kindest/node:v1.24.0) ๐Ÿ–ผ 
      โœ“ Preparing nodes ๐Ÿ“ฆ  
      โœ“ Writing configuration ๐Ÿ“œ 
      โœ“ Starting control-plane ๐Ÿ•น๏ธ 
      โœ“ Installing CNI ๐Ÿ”Œ 
      โœ“ Installing StorageClass ๐Ÿ’พ 
     Set kubectl context to "kind-psa-with-cluster-pss"
     You can now use your cluster with:
    
     kubectl cluster-info --context kind-psa-with-cluster-pss
    
     Have a question, bug, or feature request? Let us know! https://kind.sigs.k8s.io/#community ๐Ÿ™‚
    
  6. kubectl context๋ฅผ ์ƒˆ๋กœ ์ƒ์„ฑํ•œ ํด๋Ÿฌ์Šคํ„ฐ๋กœ ์„ค์ •ํ•œ๋‹ค.

     kubectl cluster-info --context kind-psa-with-cluster-pss
    

    ๋‹ค์Œ๊ณผ ๋น„์Šทํ•˜๊ฒŒ ์ถœ๋ ฅ๋  ๊ฒƒ์ด๋‹ค.

     Kubernetes control plane is running at https://127.0.0.1:63855
     CoreDNS is running at https://127.0.0.1:63855/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
    
     To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
    
  7. ๊ธฐ๋ณธ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ์ƒ์„ฑํ•  ์ตœ์†Œํ•œ์˜ ๊ตฌ์„ฑ์— ๋Œ€ํ•œ ํŒŒ๋“œ ๋ช…์„ธ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ƒ์„ฑํ•œ๋‹ค.

    cat <<EOF > /tmp/pss/nginx-pod.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
    spec:
      containers:
        - image: nginx
          name: nginx
          ports:
            - containerPort: 80
    EOF
    
  8. ํด๋Ÿฌ์Šคํ„ฐ์— ํ•ด๋‹น ํŒŒ๋“œ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

     kubectl apply -f /tmp/pss/nginx-pod.yaml
    

    ๋‹ค์Œ๊ณผ ๋น„์Šทํ•˜๊ฒŒ ์ถœ๋ ฅ๋  ๊ฒƒ์ด๋‹ค.

     Warning: would violate PodSecurity "restricted:latest": allowPrivilegeEscalation != false (container "nginx" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "nginx" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "nginx" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "nginx" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")
     pod/nginx created
    

์ •๋ฆฌํ•˜๊ธฐ

kind delete cluster --name psa-with-cluster-pss ๋ฐ kind delete cluster --name psa-wo-cluster-pss ๋ช…๋ น์„ ์‹คํ–‰ํ•˜์—ฌ ์ƒ์„ฑํ–ˆ๋˜ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์‚ญ์ œํ•œ๋‹ค.

๋‹ค์Œ ๋‚ด์šฉ

์ตœ์ข… ์ˆ˜์ • June 07, 2023 at 5:58 PM PST: [ko] Update links in dev-1.26-ko.1 (00461e0912)