쿠버네티스에서 컨테이너 보안을 강화하려면, 불필요한 시스템 호출(syscalls)을 제한하고, 애플리케이션이 최소한의 권한으로 실행되도록 구성해야 합니다.
이번 글에서는 seccomp, AppArmor 및 최소 권한 원칙(Least Privilege)을 적용하여 컨테이너 보안을 강화하는 방법을 다룹니다.
📌 글에서 다루는 상황들
1️⃣ seccomp 및 AppArmor를 활용한 컨테이너 보안 강화
2️⃣ 최소 권한 원칙(Least Privilege) 적용 및 RBAC 연계
각 문제를 실무에서 바로 활용할 수 있도록 Manifest 템플릿과 예상 결과 값을 제공합니다.
1️⃣ seccomp 및 AppArmor를 활용한 컨테이너 보안 강화
❓ 문제 상황
운영팀에서 컨테이너가 불필요한 시스템 호출을 수행하지 않도록 제한해야 하는 요구사항이 생겼습니다.
특히, 악성 코드가 컨테이너 내에서 실행될 경우 호스트 OS에 영향을 미치지 않도록, seccomp와 AppArmor를 활용하여 보안 정책을 적용해야 합니다.
• 컨테이너에서 불필요한 시스템 호출(syscalls)을 제한해야 합니다.
• 특정 Pod에 seccomp 및 AppArmor 프로파일을 적용해야 합니다.
• restricted-seccomp라는 보안 프로파일을 적용해야 합니다.
✅ 어떻게 해결할 수 있을까요?
🛠️ 해결 방법
1. seccomp를 활용하여 컨테이너에서 불필요한 시스템 호출을 제한합니다.
• seccompProfile.type: RuntimeDefault → 쿠버네티스 기본 seccomp 프로파일 적용
• seccompProfile.type: Localhost → 특정 seccomp 프로파일 적용 가능
2. AppArmor를 설정하여 컨테이너가 파일 시스템 및 네트워크 접근을 제한하도록 구성합니다.
✅ 정답 Manifest (seccomp 및 AppArmor 적용)
apiVersion: v1
kind: Pod
metadata:
name: secure-pod
annotations:
container.apparmor.security.beta.kubernetes.io/nginx: localhost/restricted-profile # AppArmor 프로파일 적용
spec:
securityContext:
seccompProfile:
type: RuntimeDefault # 기본 seccomp 프로파일 적용
containers:
- name: nginx
image: nginx
securityContext:
allowPrivilegeEscalation: false # 권한 상승 방지
capabilities:
drop:
- ALL # 모든 추가 권한 제거
📌 적용 후 예상 결과 값
1. Pod이 정상적으로 실행되는지 확인
kubectl get pods
💡 예상 출력 값
NAME READY STATUS RESTARTS AGE
secure-pod 1/1 Running 0 5s
2. seccomp 및 AppArmor 적용 여부 확인
kubectl get pod secure-pod -o jsonpath='{.spec.securityContext.seccompProfile}'
💡 예상 출력 값
{"type":"RuntimeDefault"}
2️⃣ 최소 권한 원칙(Least Privilege) 적용 및 RBAC 연계
❓ 문제 상황
운영팀에서 컨테이너가 최소한의 권한으로 실행되도록 보안 정책을 적용해야 하는 요구사항이 생겼습니다.
기본적으로 Pod은 root 사용자가 아닌 비특권(non-root) 사용자로 실행되어야 하며, 필요 이상의 권한을 가지지 않도록 해야 합니다.
• 컨테이너는 반드시 root 사용자가 아닌 비특권 사용자로 실행해야 합니다.
• Pod이 특정 네임스페이스에서만 실행되도록 RBAC를 적용해야 합니다.
✅ 어떻게 해결할 수 있을까요?
🛠️ 해결 방법
1. Pod의 runAsUser를 설정하여 root 사용자가 아닌 비특권 사용자로 실행하도록 제한합니다.
2. RBAC를 설정하여 특정 네임스페이스에서만 보안 정책이 적용된 Pod을 실행할 수 있도록 제한합니다.
✅ 정답 Manifest (비특권 사용자 실행 및 RBAC 설정)
apiVersion: v1
kind: Pod
metadata:
name: non-root-pod
namespace: team-a
spec:
securityContext:
runAsUser: 1000 # 비특권 사용자 ID로 실행
runAsGroup: 1000
fsGroup: 1000
containers:
- name: app
image: busybox
command: ["sleep", "3600"]
securityContext:
allowPrivilegeEscalation: false # 권한 상승 방지
readOnlyRootFilesystem: true # 루트 파일 시스템을 읽기 전용으로 설정
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: team-a
name: non-root-pod-executor
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["create", "delete", "get", "list", "watch", "update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: non-root-pod-executor-binding
namespace: team-a
subjects:
- kind: User
name: "developer-a" # team-a의 개발자 계정
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: non-root-pod-executor
apiGroup: rbac.authorization.k8s.io
📌 적용 후 예상 결과 값
1. Pod이 정상적으로 실행되는지 확인
kubectl get pods -n team-a
💡 예상 출력 값
NAME READY STATUS RESTARTS AGE
non-root-pod 1/1 Running 0 5s
2. Pod 내부에서 사용자 확인 (root가 아님)
kubectl exec -n team-a non-root-pod -- id
💡 예상 출력 값
uid=1000 gid=1000 groups=1000
3. RBAC 적용 여부 확인
kubectl auth can-i create pods --as=developer-a -n team-b
💡 예상 출력 값
no
4. developer-a가 자신의 네임스페이스에서 Pod을 생성할 수 있는지 확인
kubectl auth can-i create pods --as=developer-a -n team-a
💡 예상 출력 값
yes