diff --git a/content/ko/docs/tutorials/security/_index.md b/content/ko/docs/tutorials/security/_index.md new file mode 100644 index 0000000000..0934b4b3e7 --- /dev/null +++ b/content/ko/docs/tutorials/security/_index.md @@ -0,0 +1,5 @@ +--- +title: "보안" +weight: 40 +--- + diff --git a/content/ko/docs/tutorials/security/cluster-level-pss.md b/content/ko/docs/tutorials/security/cluster-level-pss.md new file mode 100644 index 0000000000..75213a745b --- /dev/null +++ b/content/ko/docs/tutorials/security/cluster-level-pss.md @@ -0,0 +1,324 @@ +--- +title: 파드 시큐리티 스탠다드를 클러스터 수준에 적용하기 +content_type: tutorial +weight: 10 +--- + +{{% alert title="Note" %}} +이 튜토리얼은 새로운 클러스터에만 적용할 수 있다. +{{% /alert %}} + +파드 시큐리티 어드미션(PSA, Pod Security Admission)은 +[베타로 변경](/blog/2021/12/09/pod-security-admission-beta/)되어 v1.23 이상에서 기본적으로 활성화되어 있다. +파드 시큐리티 어드미션은 파드가 생성될 때 +[파드 시큐리티 스탠다드(Pod Security Standards)](/docs/concepts/security/pod-security-standards/)를 +적용하는 어드미션 컨트롤러이다. +이 튜토리얼은 +`baseline` 파드 시큐리티 스탠다드를 클러스터 수준(level)에 적용하여 +표준 구성을 클러스터의 모든 네임스페이스에 적용하는 방법을 보여 준다. + +파드 시큐리티 스탠다드를 특정 네임스페이스에 적용하려면, [파드 시큐리티 스탠다드를 네임스페이스 수준에 적용하기](/ko/docs/tutorials/security/ns-level-pss/)를 참고한다. + +## {{% heading "prerequisites" %}} + +워크스테이션에 다음을 설치한다. + +- [KinD](https://kind.sigs.k8s.io/docs/user/quick-start/#installation) +- [kubectl](/ko/docs/tasks/tools/) + +## 적용할 알맞은 파드 시큐리티 스탠다드 선택하기 + +[파드 시큐리티 어드미션](/docs/concepts/security/pod-security-admission/)을 이용하여 +`enforce`, `audit`, 또는 `warn` 모드 중 하나로 +내장 [파드 시큐리티 스탠다드](/docs/concepts/security/pod-security-standards/)를 적용할 수 있다. + +현재 구성에 가장 적합한 파드 시큐리티 스탠다드를 고르는 데 +도움이 되는 정보를 수집하려면, 다음을 수행한다. + +1. 파드 시큐리티 스탠다드가 적용되지 않은 클러스터를 생성한다. + + ```shell + kind create cluster --name psa-wo-cluster-pss --image kindest/node:v1.23.0 + ``` + 다음과 비슷하게 출력될 것이다. + ``` + Creating cluster "psa-wo-cluster-pss" ... + ✓ Ensuring node image (kindest/node:v1.23.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! 😊 + + ``` + +1. kubectl context를 새로 생성한 클러스터로 설정한다. + + ```shell + 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'. + ``` + +1. 클러스터의 네임스페이스 목록을 조회한다. + + ```shell + 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 + ``` + +1. `--dry-run=server`를 사용하여 다른 파드 시큐리티 스탠다드가 적용되었을 때 + 어떤 것이 변경되는지 확인한다. + + 1. Privileged + ```shell + 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 + ``` + 2. Baseline + ```shell + 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 + ``` + + 3. Restricted + ```shell + 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`와 같은 더 엄격한 파드 시큐리티 스탠다드가 더 좋을 수도 있다. +1. `kube-system` 네임스페이스를 적용 대상에서 제외하면 + 이 네임스페이스의 파드가 `privileged`로 실행될 수 있다. + 실제 사용 환경에서는, + 최소 권한 원칙을 준수하도록, + 접근을 `kube-system` 네임스페이스로 제한하는 + 엄격한 RBAC 정책을 적용할 것을 강력히 권장한다. +1. 파드 시큐리티 어드미션 컨트롤러가 이러한 파드 시큐리티 스탠다드를 구현하는 데 사용할 수 있는 + 구성 파일을 생성한다. + + ``` + mkdir -p /tmp/pss + cat < /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/v1beta1 + 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 + ``` + +1. API 서버가 클러스터 생성 과정에서 이 파일을 처리할 수 있도록 구성한다. + + ``` + cat < /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/docs/concepts/storage/volumes/#mount-propagation + # default None + propagation: None + EOF + ``` + + {{}} + macOS에서 Docker Desktop과 KinD를 사용하고 있다면, + **Preferences > Resources > File Sharing** 메뉴에서 + `/tmp`를 Shared Directory로 추가할 수 있다. + {{}} + +1. 이러한 파드 시큐리티 스탠다드를 적용하기 위해 + 파드 시큐리티 어드미션을 사용하는 클러스터를 생성한다. + + ```shell + kind create cluster --name psa-with-cluster-pss --image kindest/node:v1.23.0 --config /tmp/pss/cluster-config.yaml + ``` + 다음과 비슷하게 출력될 것이다. + ``` + Creating cluster "psa-with-cluster-pss" ... + ✓ Ensuring node image (kindest/node:v1.23.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 🙂 + ``` + +1. kubectl context를 새로 생성한 클러스터로 설정한다. + ```shell + 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'. + ``` +1. 기본 네임스페이스에 생성할 최소한의 구성에 대한 파드 명세를 다음과 같이 생성한다. + + ``` + cat < /tmp/pss/nginx-pod.yaml + apiVersion: v1 + kind: Pod + metadata: + name: nginx + spec: + containers: + - image: nginx + name: nginx + ports: + - containerPort: 80 + EOF + ``` +1. 클러스터에 해당 파드를 생성한다. + + ```shell + 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` 명령을 실행하여 +생성했던 클러스터를 삭제한다. + +## {{% heading "whatsnext" %}} + +- 다음의 모든 단계를 한 번에 수행하려면 + [셸 스크립트](/examples/security/kind-with-cluster-level-baseline-pod-security.sh)를 + 실행한다. + 1. 파드 시큐리티 스탠다드 기반의 클러스터 수준 구성(configuration)을 생성 + 2. API 서버가 이 구성을 사용할 수 있도록 파일을 생성 + 3. 이 구성을 사용하는 API 서버를 포함하는 클러스터를 생성 + 4. kubectl context를 새로 생성한 클러스터에 설정 + 5. 최소한의 파드 구성을 위한 yaml 파일을 생성 + 6. 해당 파일을 적용하여 새 클러스터에 파드를 생성 +- [파드 시큐리티 어드미션](/docs/concepts/security/pod-security-admission/) +- [파드 시큐리티 스탠다드](/docs/concepts/security/pod-security-standards/) +- [파드 시큐리티 스탠다드를 네임스페이스 수준에 적용하기](/ko/docs/tutorials/security/ns-level-pss/) diff --git a/content/ko/docs/tutorials/security/ns-level-pss.md b/content/ko/docs/tutorials/security/ns-level-pss.md new file mode 100644 index 0000000000..46e518e43c --- /dev/null +++ b/content/ko/docs/tutorials/security/ns-level-pss.md @@ -0,0 +1,159 @@ +--- +title: 파드 시큐리티 스탠다드를 네임스페이스 수준에 적용하기 +content_type: tutorial +weight: 10 +--- + +{{% alert title="Note" %}} +이 튜토리얼은 새로운 클러스터에만 적용할 수 있다. +{{% /alert %}} + +파드 시큐리티 어드미션(PSA, Pod Security Admission)은 +[베타로 변경](/blog/2021/12/09/pod-security-admission-beta/)되어 v1.23 이상에서 기본적으로 활성화되어 있다. +파드 시큐리티 어드미션은 파드가 생성될 때 +[파드 시큐리티 스탠다드(Pod Security Standards)](/docs/concepts/security/pod-security-standards/)를 적용하는 어드미션 컨트롤러이다. +이 튜토리얼에서는, +각 네임스페이스별로 `baseline` 파드 시큐리티 스탠다드를 강제(enforce)할 것이다. + +파드 시큐리티 스탠다드를 클러스터 수준에서 여러 네임스페이스에 한 번에 적용할 수도 있다. +이에 대한 안내는 [파드 시큐리티 스탠다드를 클러스터 수준에 적용하기](/ko/docs/tutorials/security/cluster-level-pss/)를 참고한다. +## {{% heading "prerequisites" %}} + +워크스테이션에 다음을 설치한다. + +- [KinD](https://kind.sigs.k8s.io/docs/user/quick-start/#installation) +- [kubectl](/ko/docs/tasks/tools/) + +## 클러스터 생성하기 + +1. 다음과 같이 `KinD` 클러스터를 생성한다. + + ```shell + kind create cluster --name psa-ns-level --image kindest/node:v1.23.0 + ``` + 다음과 비슷하게 출력될 것이다. + ``` + Creating cluster "psa-ns-level" ... + ✓ Ensuring node image (kindest/node:v1.23.0) 🖼 + ✓ Preparing nodes 📦 + ✓ Writing configuration 📜 + ✓ Starting control-plane 🕹️ + ✓ Installing CNI 🔌 + ✓ Installing StorageClass 💾 + Set kubectl context to "kind-psa-ns-level" + You can now use your cluster with: + + kubectl cluster-info --context kind-psa-ns-level + + Not sure what to do next? 😅 Check out https://kind.sigs.k8s.io/docs/user/quick-start/ + ``` + +1. kubectl context를 새로 생성한 클러스터로 설정한다. + ```shell + kubectl cluster-info --context kind-psa-ns-level + ``` + 다음과 비슷하게 출력될 것이다. + ``` + Kubernetes control plane is running at https://127.0.0.1:50996 + CoreDNS is running at https://127.0.0.1:50996/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy + + To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'. + ``` + +## 네임스페이스 생성하기 + +`example`이라는 네임스페이스를 생성한다. + +```shell +kubectl create ns example +``` +다음과 비슷하게 출력될 것이다. +``` +namespace/example created +``` + +## 파드 시큐리티 스탠다드 적용하기 + +1. 내장 파드 시큐리티 어드미션이 지원하는 레이블을 사용하여 + 이 네임스페이스에 파드 시큐리티 스탠다드를 활성화한다. + 이 단계에서는 `latest` 버전(기본값)에 따라 `baseline(기준)` 파드 시큐리티 스탠다드에 대해 경고를 설정한다. + + ```shell + kubectl label --overwrite ns example \ + pod-security.kubernetes.io/warn=baseline \ + pod-security.kubernetes.io/warn-version=latest + ``` + +2. 어떠한 네임스페이스에도 복수 개의 파드 시큐리티 스탠다드를 활성화할 수 있으며, + 이는 레이블을 이용하여 가능하다. + 다음 명령어는 최신 버전(기본값)에 따라, `baseline(기준)` 파드 시큐리티 스탠다드는 `enforce(강제)`하지만 + `restricted(제한된)` 파드 시큐리티 스탠다드에 대해서는 `warn(경고)` 및 `audit(감사)`하도록 설정한다. + + ``` + kubectl label --overwrite ns example \ + pod-security.kubernetes.io/enforce=baseline \ + pod-security.kubernetes.io/enforce-version=latest \ + pod-security.kubernetes.io/warn=restricted \ + pod-security.kubernetes.io/warn-version=latest \ + pod-security.kubernetes.io/audit=restricted \ + pod-security.kubernetes.io/audit-version=latest + ``` + +## 파드 시큐리티 스탠다드 검증하기 + +1. `example` 네임스페이스에 최소한의 파드를 생성한다. + + ```shell + cat < /tmp/pss/nginx-pod.yaml + apiVersion: v1 + kind: Pod + metadata: + name: nginx + spec: + containers: + - image: nginx + name: nginx + ports: + - containerPort: 80 + EOF + ``` +1. 클러스터의 `example` 네임스페이스에 해당 파드 스펙을 적용한다. + ```shell + kubectl apply -n example -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 + ``` + +1. 클러스터의 `default` 네임스페이스에 해당 파드 스펙을 적용한다. + ```shell + kubectl apply -n default -f /tmp/pss/nginx-pod.yaml + ``` + 다음과 비슷하게 출력될 것이다. + ``` + pod/nginx created + ``` + +파드 시큐리티 스탠다드는 `example` 네임스페이스에만 적용되었다. +동일한 파드를 `default` 네임스페이스에 생성하더라도 +경고가 발생하지 않는다. + +## 정리하기 + +`kind delete cluster -name psa-ns-level` 명령을 실행하여 생성했던 클러스터를 삭제한다. + +## {{% heading "whatsnext" %}} + +- 다음의 모든 단계를 한 번에 수행하려면 + [셸 스크립트](/examples/security/kind-with-namespace-level-baseline-pod-security.sh)를 + 실행한다. + 1. KinD 클러스터를 생성 + 2. 새로운 네임스페이스를 생성 + 3. `baseline` 파드 시큐리티 스탠다드는 `enforce` 모드로 적용하고 + `restricted` 파드 시큐리티 스탠다드는 `warn` 및 `audit` 모드로 적용 + 4. 해당 파드 시큐리티 스탠다드가 적용된 상태에서 새로운 파드를 생성 +- [파드 시큐리티 어드미션](/docs/concepts/security/pod-security-admission/) +- [파드 시큐리티 스탠다드](/docs/concepts/security/pod-security-standards/) +- [파드 시큐리티 스탠다드를 클러스터 수준에 적용하기](/ko/docs/tutorials/security/cluster-level-pss/) \ No newline at end of file