Pod Security Standards란?
Kubernetes 1.25에서 PodSecurityPolicy(PSP)가 완전히 제거되면서, 그 대안으로 Pod Security Standards(PSS)와 이를 강제하는 Pod Security Admission(PSA)이 정식 GA가 되었다. PSS는 Pod의 보안 수준을 3단계로 정의하고, PSA는 네임스페이스 레벨에서 이를 강제한다.
PSP 대비 훨씬 단순하고 표준화된 접근이며, 별도 Webhook 없이 빌트인으로 동작한다는 것이 핵심이다.
3가지 보안 레벨
PSS는 세 가지 프로파일을 정의한다. 상위 레벨은 하위 레벨의 규칙을 모두 포함한다.
| 레벨 | 설명 | 사용 시나리오 |
|---|---|---|
| Privileged | 제한 없음. 모든 권한 허용 | kube-system, 시스템 컴포넌트 |
| Baseline | 알려진 권한 상승 차단. 최소한의 제한 | 일반 워크로드 기본값 |
| Restricted | 강력한 보안 제한. Pod 하드닝 모범 사례 강제 | 민감 워크로드, 금융/의료 |
Baseline이 차단하는 것
Baseline 프로파일은 다음을 금지한다:
privileged: true컨테이너hostNetwork,hostPID,hostIPC사용hostPath볼륨 마운트- 위험한 Linux Capabilities (
SYS_ADMIN,NET_RAW등) /proc마스킹 해제 (procMount: Unmasked)- 특정
seccomp프로파일 외 사용
Restricted가 추가로 강제하는 것
Restricted는 Baseline의 모든 규칙에 더해 다음을 요구한다:
runAsNonRoot: true필수allowPrivilegeEscalation: false필수- 모든 Capabilities drop 후 필요한 것만 add:
drop: ["ALL"]필수 - Seccomp 프로파일 명시 필수 (
RuntimeDefault또는Localhost) readOnlyRootFilesystem권장 (필수는 아님)
PSA 적용: 네임스페이스 Label
Pod Security Admission은 네임스페이스 Label로 설정한다. 3가지 모드를 조합할 수 있다:
| 모드 | 동작 | 용도 |
|---|---|---|
enforce |
위반 Pod 생성 거부 | 실제 차단 |
audit |
감사 로그에 기록, 허용 | 모니터링/전환기 |
warn |
경고 메시지 표시, 허용 | 개발자 알림 |
# Baseline enforce + Restricted warn 조합
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
# Baseline 위반 시 Pod 생성 거부
pod-security.kubernetes.io/enforce: baseline
pod-security.kubernetes.io/enforce-version: latest
# Restricted 위반 시 경고만 표시
pod-security.kubernetes.io/warn: restricted
pod-security.kubernetes.io/warn-version: latest
# Restricted 위반 감사 로그 기록
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/audit-version: latest
이 패턴이 가장 권장되는 전환 전략이다. Baseline을 강제하면서, Restricted로 전환 준비를 동시에 한다.
Restricted 준수 Pod 작성법
Restricted 레벨을 만족하는 Pod 스펙을 작성해 보자:
apiVersion: v1
kind: Pod
metadata:
name: secure-app
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: myapp:1.0
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
# 쓰기 필요한 경로만 emptyDir로 마운트
volumeMounts:
- name: tmp
mountPath: /tmp
- name: cache
mountPath: /app/cache
volumes:
- name: tmp
emptyDir: {}
- name: cache
emptyDir:
sizeLimit: 100Mi
핵심 포인트: readOnlyRootFilesystem: true로 설정하면 컨테이너가 파일시스템에 쓸 수 없다. /tmp이나 캐시 디렉토리는 emptyDir로 별도 마운트한다.
기존 클러스터 전환 전략
이미 운영 중인 클러스터에 PSA를 도입하는 단계별 전략이다:
1단계: 현황 파악 (Dry-run)
# 모든 네임스페이스에서 Baseline 위반 Pod 확인
kubectl label --dry-run=server --overwrite ns
--all pod-security.kubernetes.io/enforce=baseline
# 특정 네임스페이스에서 Restricted 위반 확인
kubectl label --dry-run=server --overwrite ns production
pod-security.kubernetes.io/enforce=restricted
--dry-run=server는 실제 Label을 적용하지 않고, 위반하는 Pod 목록만 보여준다.
2단계: Audit + Warn 모드 적용
# 경고만 표시, 차단하지 않음
kubectl label ns production
pod-security.kubernetes.io/warn=baseline
pod-security.kubernetes.io/audit=baseline
3단계: 위반 Pod 수정
경고/감사 로그를 확인하며 위반 Pod의 securityContext를 수정한다.
4단계: Enforce 적용
# 모든 위반이 해결된 후 강제 적용
kubectl label ns production
pod-security.kubernetes.io/enforce=baseline
pod-security.kubernetes.io/warn=restricted
pod-security.kubernetes.io/audit=restricted
클러스터 전역 기본값 설정
모든 네임스페이스에 기본 정책을 적용하려면 Admission Configuration을 사용한다:
# /etc/kubernetes/admission-config.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
warn: restricted
warn-version: latest
audit: restricted
audit-version: latest
exemptions:
# 시스템 네임스페이스 면제
namespaces:
- kube-system
- kube-node-lease
- cert-manager
# 특정 사용자/SA 면제
usernames:
- system:serviceaccount:monitoring:prometheus
# 특정 런타임 클래스 면제
runtimeClasses:
- kata
exemptions로 시스템 네임스페이스나 특정 서비스 어카운트를 면제할 수 있다. cert-manager, 모니터링 에이전트 등 특권이 필요한 컴포넌트에 사용한다.
OPA Gatekeeper와의 비교
PSA와 OPA Gatekeeper는 상호 보완적이다:
| 항목 | PSA | OPA Gatekeeper |
|---|---|---|
| 설치 | 빌트인 (추가 설치 불필요) | 별도 설치 필요 |
| 정책 유연성 | 3단계 고정 프로파일 | Rego로 커스텀 정책 무제한 |
| 적용 범위 | Pod 보안 컨텍스트만 | 모든 K8s 리소스 |
| 복잡도 | 낮음 | 높음 (Rego 학습 필요) |
| 권장 사용 | 기본 보안 베이스라인 | 조직별 세밀한 정책 |
권장: PSA로 기본 보안 수준을 확보하고, 조직 고유의 세밀한 정책은 OPA Gatekeeper로 추가 적용하라.
흔한 위반 사례와 해결법
1. Nginx Ingress Controller
# 위반: NET_BIND_SERVICE capability 필요 (80/443 포트 바인딩)
# 해결: Baseline에서는 허용됨. Restricted에서는 네임스페이스 면제 설정
exemptions:
namespaces:
- ingress-nginx
2. 로그 수집 에이전트 (Fluent Bit)
# 위반: hostPath 볼륨 (/var/log) 마운트 필요
# 해결: 시스템 네임스페이스에 배포하거나 면제 설정
# 또는 sidecar 패턴으로 전환
3. 컨테이너 이미지가 root로 실행
# 위반: runAsNonRoot: true 위반
# 해결: Dockerfile에서 USER 지시어 추가
FROM node:20-slim
RUN groupadd -r app && useradd -r -g app app
USER app
COPY --chown=app:app . /app
운영 베스트 프랙티스
- 모든 네임스페이스에 최소 Baseline enforce: 클러스터 전역 기본값으로 설정하라
- 점진적 Restricted 전환: warn/audit로 시작하여 위반을 파악한 후 enforce로 전환하라
- CI/CD에서 사전 검증:
kubectl --dry-run=server또는 Trivy 같은 도구로 배포 전 PSS 준수 여부를 검증하라 - 면제는 최소화: exemptions는 반드시 필요한 시스템 컴포넌트에만 적용하라
- 버전 고정 vs latest: 운영 환경에서는
enforce-version: v1.30처럼 고정하여 업그레이드 시 예기치 않은 차단을 방지하라
정리
Pod Security Standards는 PSP의 복잡함을 걷어내고, 3단계 보안 프로파일로 단순화한 Kubernetes 빌트인 보안 메커니즘이다. Baseline으로 기본 보안을 확보하고, Restricted로 점진적으로 강화하는 전략이 가장 효과적이다. OPA Gatekeeper와 조합하면 표준 보안 + 커스텀 정책이라는 완전한 보안 체계를 구축할 수 있다.