이 페이지에서는 PodSecurity
허용 컨트롤러를 사용하여 Google Kubernetes Engine(GKE) 클러스터에 사전 정의된 포드 수준 보안 제어를 적용하는 방법을 보여줍니다.
PodSecurity
작동 방식에 대한 자세한 내용은 포드 보안 허용을 참조하세요.
개요
PodSecurity
는 포드 보안 표준을 GKE 클러스터에서 실행되는 포드에 적용할 수 있게 해주는 Kubernetes 허용 컨트롤러입니다. 포드 보안 표준은 Kubernetes에서 포드 보안의 고급 요구사항을 다루는 사전 정의된 보안 정책입니다. 이러한 정책은 매우 허용적인 정책부터 매우 제한적인 정책까지 다양합니다.
다음 포드 보안 표준을 GKE 클러스터에 적용할 수 있습니다.
- 권한: 가장 광범위한 수준의 권한을 제공하는 제한되지 않은 정책입니다. 알려진 권한 에스컬레이션을 허용합니다.
- 기본: 최소한으로 지정된 기본 포드 구성을 허용하는 최소 제한 정책입니다. 알려진 권한 에스컬레이션을 허용하지 않습니다.
- 제한됨: 포드 강화 권장사항을 따르는 매우 제한적인 정책입니다.
PodSecurity
허용 컨트롤러를 사용하여 다음 모드로 포드 보안 표준을 적용할 수 있습니다.
- 적용: 정책 위반은 포드 생성을 거부합니다. 감사 이벤트가 감사 로그에 추가됩니다.
- 감사: 정책 위반은 감사 로그에 감사 이벤트를 추가하는 것을 트리거합니다. 포드 만들기가 허용됩니다.
- 경고: 정책 위반은 사용자에게 표시되는 경고를 트리거합니다. 포드 만들기가 허용됩니다.
PodSecurity
허용 컨트롤러는 이러한 정책을 Kubernetes API에 삽입합니다.
포드 수준에서 커스텀 보안 정책을 만들고 적용하려면 Gatekeeper 허용 컨트롤러를 대신 사용하는 것이 좋습니다.
시작하기 전에
시작하기 전에 다음 태스크를 수행했는지 확인합니다.
- Google Kubernetes Engine API를 사용 설정합니다. Google Kubernetes Engine API 사용 설정
- 이 태스크에 Google Cloud CLI를 사용하려면 gcloud CLI를 설치한 후 초기화합니다. 이전에 gcloud CLI를 설치한 경우
gcloud components update
를 실행하여 최신 버전을 가져옵니다.
- 버전 1.23 이상을 실행하는 GKE Autopilot 또는 표준 클러스터가 있는지 유의하세요.
- Autopilot 클러스터의 경우 기본 버전이 1.23 이상인 출시 채널에 등록하세요.
- 표준 클러스터의 경우 출시 채널에 등록하거나 클러스터를 특정 버전으로 업그레이드하도록 합니다.
요구사항
PodSecurity
허용 컨트롤러를 사용할 수 있고 기본적으로 다음 GKE 버전을 실행하는 클러스터에서 사용 설정됩니다.
- 버전 1.25 이상: 정식
- 버전 1.23 및 버전 1.24: 베타
GKE 버전을 사용할 수 있고 출시 채널의 기본 버전인지 확인하려면 출시 일정을 참조하세요.
PodSecurity
를 사용하여 포드 보안 표준 적용
PodSecurity
허용 컨트롤러를 사용하려면 특정 모드의 특정 포드 보안 표준을 특정 네임스페이스에 적용해야 합니다. 네임스페이스 라벨을 사용하여 이를 수행할 수 있습니다.
이 연습에서는 다음을 수행합니다.
- 새 네임스페이스 2개 만들기
- 각 네임스페이스에 보안 정책 적용
- 구성된 정책 테스트
다음 GKE 버전에서 GKE는 kube-system
네임스페이스에 적용되는 정책을 무시합니다.
- 1.23.6-gke.1900 이상
- 1.24.0-gke.1200 이상
이전 GKE 버전에서는 kube-system
에 정책을 적용하지 않습니다.
새 네임스페이스 만들기
클러스터에 네임스페이스를 만듭니다.
kubectl create ns baseline-ns
kubectl create ns restricted-ns
이 명령어는 다음 네임스페이스를 만듭니다.
baseline-ns
: 허용적인 워크로드용restricted-ns
: 매우 제한적인 워크로드용
라벨을 사용하여 보안 정책 적용
다음 포드 보안 표준을 적용합니다.
baseline
:warn
모드의baseline-ns
에 적용restricted
:enforce
모드의restricted-ns
에 적용
kubectl label --overwrite ns baseline-ns pod-security.kubernetes.io/warn=baseline
kubectl label --overwrite ns restricted-ns pod-security.kubernetes.io/enforce=restricted
이러한 명령어는 다음과 같은 결과를 생성합니다.
baseline
정책을 위반하는baseline-ns
네임스페이스의 워크로드가 허용되며 클라이언트에 경고 메시지가 표시됩니다.restricted
정책을 위반하는restricted-ns
네임스페이스의 워크로드가 거부되고 GKE는 감사 로그에 항목을 추가합니다.
라벨이 추가되었는지 확인합니다.
kubectl get ns --show-labels
출력은 다음과 비슷합니다.
baseline-ns Active 74s kubernetes.io/metadata.name=baseline-ns,pod-security.kubernetes.io/warn=baseline
restricted-ns Active 18s kubernetes.io/metadata.name=restricted-ns,pod-security.kubernetes.io/enforce=restricted
default Active 57m kubernetes.io/metadata.name=default
kube-public Active 57m kubernetes.io/metadata.name=kube-public
kube-system Active 57m kubernetes.io/metadata.name=kube-system
구성된 정책 테스트
PodSecurity
허용 컨트롤러가 의도한 대로 작동하는지 확인하려면 baseline
및 restricted
정책을 위반하는 워크로드를 두 네임스페이스 모두에 배포합니다. 다음 매니페스트 예시에서는 권한 에스컬레이션을 허용하는 nginx
컨테이너를 배포합니다.
다음 매니페스트를
psa-workload.yaml
로 저장합니다.apiVersion: v1 kind: Pod metadata: name: nginx labels: app: nginx spec: containers: - name: nginx image: nginx securityContext: privileged: true
baseline-ns
네임스페이스에 매니페스트를 적용합니다.kubectl apply -f psa-workload.yaml --namespace=baseline-ns
출력은 다음과 비슷합니다.
Warning: would violate PodSecurity "baseline:latest": privileged (container "nginx" must not set securityContext.privileged=true)
baseline
정책은 포드가 네임스페이스에 배포되도록 허용합니다.포드가 성공적으로 배포되었는지 확인합니다.
kubectl get pods --namespace=baseline-ns -l=app=nginx
restricted-ns
네임스페이스에 매니페스트를 적용합니다.kubectl apply -f psa-workload.yaml --namespace=restricted-ns
출력은 다음과 비슷합니다.
Error from server (Forbidden): error when creating "workload.yaml": pods "nginx" is forbidden: violates 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")
포드가 네임스페이스에 배포되지 않습니다. 감사 항목이 로그에 추가됩니다.
감사 로그에서 정책 위반 보기
audit
및 enforce
모드에서의 정책 위반은 클러스터의 감사 로그에 기록됩니다. Google Cloud 콘솔의 로그 탐색기를 사용하여 이러한 로그를 볼 수 있습니다.
Google Cloud 콘솔의 로그 탐색기 페이지로 이동합니다.
쿼리 필드에 다음을 지정하여
audit
및enforce
모드 감사 로그를 검색합니다.resource.type="k8s_cluster" protoPayload.resourceName:"/pods/nginx" protoPayload.methodName="io.k8s.core.v1.pods.create" (labels."pod-security.kubernetes.io/audit-violations":"PodSecurity" OR protoPayload.response.reason="Forbidden")
쿼리 실행을 클릭합니다.
쿼리 결과 섹션에서
Forbidden
로그 항목을 펼쳐enforce
모드 거부 로그를 살펴봅니다. 세부정보는 다음과 비슷합니다.{ ... protoPayload: { @type: "type.googleapis.com/google.cloud.audit.AuditLog" authenticationInfo: {1} authorizationInfo: [1] methodName: "io.k8s.core.v1.pods.create" request: {6} requestMetadata: {2} resourceName: "core/v1/namespaces/restricted-ns/pods/nginx" response: { @type: "core.k8s.io/v1.Status" apiVersion: "v1" code: 403 details: {2} kind: "Status" message: "pods "nginx" is forbidden: violates PodSecurity "restricted:latest": privileged (container "nginx" must not set securityContext.privileged=true), 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")" metadata: {0} reason: "Forbidden" status: "Failure" } serviceName: "k8s.io" status: {2} } receiveTimestamp: "2022-02-01T19:19:25.353235326Z" resource: {2} timestamp: "2022-02-01T19:19:21.469360Z" }
audit
모드 로그를 살펴보려면audit-violations
로그 항목을 펼칩니다. 세부정보는 다음과 비슷합니다.{ ... labels: { ... pod-security.kubernetes.io/audit-violations: "would violate PodSecurity "baseline:latest": privileged (container "nginx" must not set securityContext.privileged=true)" pod-security.kubernetes.io/enforce-policy: "privileged:latest" } operation: {4} protoPayload: {10} receiveTimestamp: "2023-12-26T05:18:04.533631468Z" resource: {2} timestamp: "2023-12-26T05:17:36.102387Z" }
삭제
Google Cloud 계정에 비용이 청구되지 않도록 하려면 네임스페이스를 삭제하세요.
kubectl delete ns baseline-ns
kubectl delete ns restricted-ns
PodSecurity
의 대안
포드 보안 표준을 적용하기 위해 기본 제공되는 Kubernetes PodSecurity
허용 컨트롤러를 사용하는 것 외에도 Open Policy Agent(OPA)를 기반으로 하는 허용 컨트롤러인 Gatekeeper를 사용하여 커스텀 포드 수준 보안 제어를 만들고 적용할 수 있습니다.