**Pod Security Standards (PSS)**는 Kubernetes에서 파드의 보안을 강화하기 위해 마련된 표준 가이드라인입니다. 이 표준은 파드에 적용할 수 있는 보안 정책을 세 가지(Privileged, Baseline, Restricted)로 정의하며, 이 중 **Restricted**는 가장 엄격한 수준의 보안을 요구합니다.


Restricted 표준이 요구하는 주요 사항

Restricted 프로파일은 민감한 정보에 대한 접근을 제한하고, 권한 상승을 방지하는 것을 목표로 합니다. 이 표준을 준수하는 파드는 다음과 같은 엄격한 보안 규칙을 따라야 합니다.

1. 권한 있는(Privileged) 컨테이너 사용 금지

  • **privileged: false**를 명시적으로 설정하거나, 기본값으로 사용해야 합니다.
  • 파드가 호스트 노드에 대한 완전한 접근 권한을 가지는 것을 차단하여 보안 위험을 최소화합니다.

2. 권한 상승(Privilege Escalation) 차단

  • **allowPrivilegeEscalation: false**를 설정해야 합니다.
  • 이는 파드 내의 프로세스가 부모 프로세스보다 더 높은 권한을 얻는 것을 금지하여, 보안 취약점을 통한 공격 경로를 막습니다.

3. 루트(Root) 권한 사용 제한

  • **runAsNonRoot: true**를 명시적으로 설정해야 합니다.
  • 컨테이너 내부의 프로세스가 루트가 아닌 사용자로 실행되도록 강제합니다. 이는 컨테이너에서 권한 상승 공격이 발생하더라도 시스템 전체에 미치는 영향을 제한합니다.
  • runAsUser 필드도 0이 아닌 값으로 설정해야 합니다.

4. 읽기 전용 루트 파일 시스템

  • **readOnlyRootFilesystem: true**를 설정해야 합니다.
  • 컨테이너의 루트 파일 시스템을 읽기 전용으로 만들어, 악의적인 사용자가 시스템 파일을 수정하거나 악성코드를 심는 것을 방지합니다.

5. 드롭된(Dropped) 기능 및 추가 기능

  • capabilities 필드를 사용하여 모든 기본 리눅스 기능(capabilities)을 드롭해야 합니다.
  • NET_BIND_SERVICE와 같이 파드 운영에 꼭 필요한 특정 기능(Capabilities)만 선택적으로 허용할 수 있습니다.

6. Seccomp 프로파일 사용

  • **seccompProfile: {type: RuntimeDefault or Localhost}**를 사용해야 합니다.
  • 컨테이너가 호출할 수 있는 시스템 콜(syscall)을 제한하여, 컨테이너가 의도치 않은 시스템 작업을 수행하는 것을 막습니다

 

테스트

1. 네임스페이스 생성 및 label 적용

controlplane:~$ k create ns pss-ns
namespace/pss-ns created

controlplane:~$ kubectl label --overwrite ns pss-ns \
  pod-security.kubernetes.io/enforce=restricted
namespace/pss-ns labeled

 

2. 테스트를 위한 deployment 기본 yaml 생성

k create deployment -n pss-ns  nginx-test --image=nginx --dry-run=client  -o yaml

 

3. 배포 후 결과 확인

  • Warning 에서 에러가 발생하고, 해당 항목을 수정 하여야 배포가 가능합니다
controlplane:~$ k apply -f deploy.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")
deployment.apps/nginx-test created
controlplane:~$

 

4. 조건에 맞게 항목 수정 후 배포

 

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: nginx-test
  name: nginx-test
  namespace: pss-ns
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-test
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx-test
    spec:
      containers:
      - image: nginx
        name: nginx
        securityContext:                  #####여기서부터 구문 추가######
          allowPrivilegeEscalation: false
          capabilities:
            drop: ["ALL"]
          runAsNonRoot: true
          seccompProfile:
            type: RuntimeDefault

 

 

'k8s > CKS' 카테고리의 다른 글

[CKS] 쿠버네티스 API 서버 보안 강화: 익명 접근 차단  (0) 2025.09.09
[CKS] BOM 툴 trivy -1  (0) 2025.09.09
[CKS] cilium  (0) 2025.09.08
[CKS] k8s Cluster & node version upgrade  (0) 2025.09.08
[CKS] Pod Security Standards  (1) 2025.09.07

Cilium은 Linux 커널의 eBPF(extended Berkeley Packet Filter) 기술을 기반으로 하는 오픈 소스 소프트웨어로, 컨테이너화된 워크로드(특히 Kubernetes)의 네트워킹, 보안 및 관측성을 제공하는 솔루션입니다.

전통적인 네트워크 정책은 IP 주소나 포트 번호에 의존하지만, Cilium은 이러한 Layer 3/4 정보뿐만 아니라 컨테이너의 레이블, 애플리케이션 식별자(예: HTTP/gRPC 경로, Kafka 토픽) 등 Layer 7 정보까지 활용하여 훨씬 더 세밀하고 동적인 네트워크 정책을 구현할 수 있습니다.

Cilium의 핵심 기능:

  • 네트워크 정책: 컨테이너 간의 통신을 허용하거나 차단하는 정책을 정의합니다.
  • 로드 밸런싱: 클러스터 내부 및 외부 트래픽에 대한 효율적인 로드 밸런싱을 제공합니다.
  • 관측성: 네트워크 흐름을 실시간으로 추적하고 시각화하여 문제 해결을 돕습니다.
  • 보안: 강력한 암호화(IPsec)와 상호 인증(mTLS)을 지원하여 통신을 보호합니다.

대표적인 Cilium 정책 구문에 대한 상세 설명

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: mutual-auth-echo
  namespace: default
spec:
  endpointSelector:
    matchLabels:
      app: echo
  ingress:
  - authentication:
      mode: required
    fromEndpoints:
    - matchLabels:
        app: pod-worker
  - fromEntities:
    - "host"

1. endpointSelector

  • matchLabels: {app: echo}
  • 설명: 이 정책의 대상을 지정합니다. 이 규칙은 오직 app: echo 레이블을 가진 파드로 들어오는 모든 통신에만 적용됩니다. 이는 정책이 클러스터 내의 특정 워크로드(예: 에코 서버)를 보호하고 제어하는 데 사용됨을 의미합니다.

2. ingress

  • 설명: endpointSelector에 의해 지정된 파드로 들어오는 트래픽에 대한 규칙들의 목록입니다. Cilium은 이 목록에 있는 모든 규칙을 순서에 상관없이 검토하며, 하나의 규칙이라도 일치하면 트래픽을 허용합니다. 즉, 이 규칙들은 논리적인 OR 관계로 묶여 있습니다.

3. 첫 번째 ingress 규칙

이 규칙은 app: pod-workerapp: echo 간의 통신에 대한 보안을 강화합니다.

  • authentication: mode: required:
    • 설명: 이 필드는 Cilium이 제공하는 상호 TLS(mTLS) 인증을 사용하도록 요구합니다. required 모드는 통신을 시작하는 쪽(pod-worker)과 받는 쪽(echo) 모두 자신의 ID를 증명하는 인증서를 제시해야만 통신이 허용된다는 뜻입니다. 이 과정은 Cilium의 내부 CA(Certificate Authority)를 통해 자동으로 관리되며, 두 파드 간의 트래픽을 암호화하여 중간자 공격을 방지하고 신뢰를 보장합니다.
  • fromEndpoints: - matchLabels: {app: pod-worker}:
    • 설명: 이 규칙은 오직 app: pod-worker 레이블을 가진 파드에서 시작된 트래픽에만 적용됩니다. 즉, 이 규칙은 echo 파드로 접속하려는 다른 모든 파드에 대해서는 적용되지 않습니다.

4. 두 번째 ingress 규칙

이 규칙은 노드 자체에서 시작된 트래픽에 대한 접근을 허용합니다.

  • fromEntities: - "host":
    • 설명: fromEntities는 Cilium이 미리 정의해 둔 특별한 "엔티티"로부터의 트래픽을 허용할 때 사용됩니다. 여기서 **host**는 해당 파드가 실행 중인 Kubernetes 노드 자체를 의미합니다. 예를 들어, kubelet과 같은 시스템 데몬이 echo 파드로 상태 점검(liveness/readiness probe)을 보내는 경우 이 규칙에 의해 허용될 수 있습니다.

최종 결론

이 정책은 app: echo 파드를 두 가지 유형의 트래픽으로부터 보호합니다.

  1. app: pod-worker 파드로부터 오는 트래픽은 반드시 mTLS를 통한 상호 인증이 이루어져야만 허용됩니다. 이는 서비스 간의 통신에 대한 강력한 신원 확인과 암호화를 보장합니다.
  2. **노드 자체(host)**에서 오는 트래픽은 인증 없이도 허용됩니다. 이는 클러스터 내부 시스템 관리와 관련된 통신을 허용하기 위한 것입니다.

'k8s > CKS' 카테고리의 다른 글

[CKS] BOM 툴 trivy -1  (0) 2025.09.09
[CKS] Pod Security Standards - restricted  (0) 2025.09.08
[CKS] k8s Cluster & node version upgrade  (0) 2025.09.08
[CKS] Pod Security Standards  (1) 2025.09.07
[CKS] falco 사용방법 및 샘플 - 2  (0) 2025.09.07

쿠버네티스 클러스터의 컨트롤 플레인노드는 버전이 일치해야만 최적의 성능과 안정성을 보장할 수 있습니다. 이는 단순히 기능적 호환성을 넘어, 클러스터의 보안을 유지하는 데 필수적인 요소입니다.


주요 원인

1. API 버전 호환성 문제

쿠버네티스 API는 지속적으로 발전하며 새로운 기능이 추가되거나 기존 기능이 변경됩니다. 만약 컨트롤 플레인의 API 서버와 각 노드의 Kubelet 버전이 서로 다르면, API 호출이 예상치 않게 실패할 수 있습니다. 예를 들어, 최신 API를 사용하는 컨트롤 플레인이 구형 API만 아는 Kubelet에 명령을 내리면, 명령이 제대로 수행되지 않아 클러스터의 기능적 오류와 더불어 보안 정책에 허점이 생길 수 있습니다.

2. 보안 기능 불일치

새로운 쿠버네티스 버전에는 항상 최신 보안 패치취약점 수정 사항이 포함됩니다. 만약 컨트롤 플레인만 최신 버전으로 업데이트되고 노드는 그대로 남아 있다면, 패치되지 않은 노드가 클러스터의 가장 약한 고리가 됩니다. 공격자는 이 취약한 노드를 통해 클러스터에 침투할 수 있으며, 이는 전체 시스템의 보안을 위협합니다.

3. 인증 및 권한 문제

버전이 다르면 Kubelet과 컨트롤 플레인 간의 통신에서 인증 및 권한 부여 방식에 차이가 발생할 수 있습니다. 이는 Kubelet이 API 서버로부터 필요한 권한을 얻지 못하거나, 반대로 과도한 권한으로 민감한 리소스에 접근하는 문제를 일으킬 수 있습니다. 이러한 문제는 클러스터의 보안 모델을 무너뜨릴 수 있는 심각한 위험을 내포합니다.

4. 기능적 비정상 작동

버전 불일치는 파드 스케줄링, 볼륨 마운트 등 기본적인 클러스터 운영에도 영향을 미칩니다. 컨트롤 플레인에는 존재하는 새로운 기능이 노드에는 없어 정상적으로 작동하지 않거나, 예측 불가능한 오류가 발생할 수 있습니다. 이러한 기능적 불안정성은 클러스터를 취약하게 만들고, 결국 보안 문제로 이어질 수 있습니다.

결론적으로, 컨트롤 플레인과 노드의 버전을 일관되게 유지하는 것은 클러스터의 안정성을 넘어, 최신 보안 기능을 모두에게 적용하고, 불필요한 보안 취약점을 예방하는 가장 핵심적인 보안 관리 방법입니다.

 

적용 방법

https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/upgrading-linux-nodes/

 

Upgrading Linux nodes

This page explains how to upgrade a Linux Worker Nodes created with kubeadm. Before you begin You need to have shell access to all the nodes, and the kubectl command-line tool must be configured to communicate with your cluster. It is recommended to run th

kubernetes.io

 

예시 사진

controlplain 1.33.3

node01 1.33.2

 

1. 노드에서 kubeadm 설치

# replace x in 1.3x.x-* with the latest patch version
sudo apt-mark unhold kubeadm && \
sudo apt-get update && sudo apt-get install -y kubeadm='1.33.3-*' && \
sudo apt-mark hold kubeadm

 

2. 노드에서 kubeadm 을 통한 업그레이드

sudo kubeadm upgrade node

 

3. 컨트롤플레인에서 node drain 적용

kubectl drain node01 --ignore-daemonsets

 

 

4. 노드에서 kubelet 과 kubectl 적용

# replace x in 1.34.x-* with the latest patch version
sudo apt-mark unhold kubelet kubectl && \
sudo apt-get update && sudo apt-get install -y kubelet='1.33.3-*' kubectl='1.33.3-*' && \
sudo apt-mark hold kubelet kubectl

 

5. 노드에서 설정 적용을 위해 재기동

sudo systemctl daemon-reload
sudo systemctl restart kubelet

 

6. 컨트롤플레인에서 버전 확인 후 uncordon 수행

# execute this command on a control plane node
# replace <node-to-uncordon> with the name of your node
kubectl uncordon node01

 

'k8s > CKS' 카테고리의 다른 글

[CKS] Pod Security Standards - restricted  (0) 2025.09.08
[CKS] cilium  (0) 2025.09.08
[CKS] Pod Security Standards  (1) 2025.09.07
[CKS] falco 사용방법 및 샘플 - 2  (0) 2025.09.07
[CKS] falco 사용방법 및 샘플 - 1  (0) 2025.09.07

Pod Security Standards (PSS)는 쿠버네티스에서 파드(Pod)의 보안 수준을 정의하는 일련의 표준입니다. 이는 쿠버네티스 클러스터에서 파드를 실행할 때 따라야 할 권장 보안 정책을 세 가지 프로파일로 구분하여 제공합니다.

이는 과거에 사용되었던 PodSecurityPolicy(PSP)를 대체하며, 쿠버네티스 버전 1.25부터 PodSecurityPolicy가 완전히 제거되면서 PSS가 표준 보안 정책 강제(enforcement) 수단으로 자리 잡았습니다.

PSS는 세 가지 보안 프로파일을 정의합니다.

1. privileged (특권)

  • 정책: 이 프로파일은 제한이 없습니다. 모든 유형의 파드를 허용합니다.
  • 용도: privileged 파드는 호스트의 모든 권한에 접근할 수 있으며, 시스템 유틸리티 파드나 클러스터 관리 에이전트(kube-proxy, calico-node)와 같이 시스템 수준의 작업을 수행해야 하는 워크로드에 사용됩니다.
  • 보안 위험: privileged 파드는 호스트의 루트 권한을 가질 수 있어, 컨테이너 탈출(Container Breakout)과 같은 심각한 보안 취약점을 야기할 수 있습니다. 일반적인 애플리케이션에는 절대 사용해서는 안 됩니다.

2. baseline (기본)

  • 정책: 이 프로파일은 알려진 권한 상승(privilege escalation)을 방지하기 위한 최소한의 제한을 적용합니다.
  • 용도: 일반적인 애플리케이션 개발자에게 충분한 유연성을 제공하면서도, 주요 보안 위협을 방지하는 기본 보안 수준을 제공합니다.
  • 주요 제한 사항:
    • hostPath 볼륨 사용 금지
    • privileged 컨테이너 실행 금지
    • HostPID, HostIPC, HostNetwork 사용 금지
    • allowPrivilegeEscalation 필드 false 강제

3. restricted (제한됨)

  • 정책: 이 프로파일은 baseline보다 더 엄격한 제한을 적용하여 최고 수준의 파드 강화(hardening)를 목표로 합니다.
  • 용도: 보안에 매우 민감한 애플리케이션이나, 권한이 최소화된(least-privilege) 환경에 사용됩니다.
  • 주요 제한 사항:
    • baseline의 모든 제한 사항 포함
    • 컨테이너가 루트(root) 사용자로 실행되는 것을 금지 (runAsNonRoot: true 강제)
    • CAPABILITIES를 기본값으로 제한 (불필요한 기능 제거)
    • hostPath와 유사한 volume 타입 제한 (defaultMode, projected 등)

Pod Security Admission과의 관계

Pod Security Standards(PSS)는 Pod Security Admission(PSA) 컨트롤러를 통해 쿠버네티스 클러스터에 적용됩니다.

  • PSA 컨트롤러는 네임스페이스에 적용된 PSS 레이블(pod-security.kubernetes.io/enforce=baseline)을 읽어, 해당 네임스페이스에 배포되는 파드가 레이블에 정의된 보안 표준을 준수하는지 검사합니다.
  • 정책 위반 시, PSA는 enforce, audit, warn 세 가지 모드에 따라 파드 생성을 거부하거나 경고만 발생시킵니다.

 

적용 테스트

Pod Security Standards 적용을 위해 kube-apiserver.yaml 수정

spec:
  containers:
  - command:
    - kube-apiserver
    - --enable-admission-plugins=NodeRestriction,PodSecurity ####PodSecurity#### 적용

 

Pod Security Standards 적용한 namespace 와 label 추가

kubectl create namespace my-secure-ns

# `enforce=baseline` 레이블 적용
kubectl label namespace my-secure-ns pod-security.kubernetes.io/enforce=baseline

 

테스트 파드 수행

# pod-with-hostpath.yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-test-pod
  namespace: my-secure-ns
spec:
  containers:
  - name: my-container
    image: busybox
    command: ["/bin/sh", "-c", "sleep 3600"]
  volumes:
  - name: hostpath-vol
    hostPath:
      path: /

수행 결과

  • baseline 정책에 위반하면 위반된 사유를 기재해주고 아래와 같은 오류 발생

Falco에서 경고(Alert)를 파일로 저장하도록 설정하는 방법은 falco.yaml 파일을 수정하는 것입니다.

1단계: falco.yaml 파일 찾기

Falco 설정 파일은 일반적으로 다음 위치 중 하나에 있습니다.

  • /etc/falco/falco.yaml
  • /usr/local/etc/falco/falco.yaml

 

2단계: file_output 설정 활성화하기

텍스트 편집기를 사용하여 falco.yaml 파일을 열고, file_output 섹션을 찾으세요. 기본적으로 아래와 같이 enabled 값이 false로 되어 있습니다.

# [Stable] `file_output`
#
# When appending Falco alerts to a file, each new alert will be added to a new
# line. It's important to note that Falco does not perform log rotation for this
# file. If the `keep_alive` option is set to `true`, the file will be opened once
# and continuously written to, else the file will be reopened for each output
# message. Furthermore, the file will be closed and reopened if Falco receives
# the SIGUSR1 signal.
file_output:
  enabled: false
  keep_alive: false
  filename: ./events.txt

이 설정을 다음과 같이 수정하여 활성화합니다.

file_output:
  enabled: true
  keep_alive: false
  filename: /var/log/falco/events.json

수정된 부분의 의미:

  • enabled: true: 파일 출력을 활성화합니다.
  • keep_alive: true: Falco가 파일을 한 번 열고 계속 쓰도록 설정합니다. 이는 성능을 향상시키며, 많은 경고가 발생하는 환경에서 오버헤드를 줄여줍니다.(본문에서는 false 로 테스트 하였습니다)
  • filename: /var/log/falco/events.json: 경고를 저장할 파일의 경로와 이름을 지정합니다. .json 확장자를 사용하면 경고 메시지가 JSON 형식으로 저장되어 로그 분석 도구와 연동하기 쉽습니다.

3단계: Falco 재시작 또는 설정 적용하기

변경사항을 적용하려면 Falco 서비스를 재시작해야 합니다.

  • Systemd를 사용하는 경우 (대부분의 리눅스 배포판)
    sudo systemctl restart falco

 
 

+ Recent posts