Pod 또는 컨테이너의 보안 컨텍스트 구성하기
Pod 또는 컨테이너의 보안 컨텍스트 구성하기 (Configure a Security Context for a Pod or Container)
보안 컨텍스트(security context)는 Pod 또는 컨테이너에 대한 권한과 접근 제어 설정을 정의해요. 보안 컨텍스트 설정은 다음을 포함하되 이에 국한되지는 않아요.
- 임의 접근 제어(Discretionary Access Control): 파일 같은 객체에 대한 접근 권한이 사용자 ID(UID)와 그룹 ID(GID)에 기반해요.
- Security Enhanced Linux (SELinux): 객체에 보안 라벨을 할당해요.
- privileged 또는 unprivileged로 실행.
- Linux Capabilities: 프로세스에 root 사용자의 모든 권한이 아니라 일부 권한을 부여해요.
- AppArmor: 프로그램 프로파일로 개별 프로그램의 기능을 제한해요.
- Seccomp: 프로세스의 시스템 호출을 필터링해요.
allowPrivilegeEscalation: 프로세스가 부모 프로세스보다 더 많은 권한을 얻을 수 있는지(예: setuid 바이너리 실행)를 제어해요. 이 불리언 값은 컨테이너 프로세스에no_new_privs플래그가 설정될지 직접 제어하지만, 값이 반전된다는 점에 유의하세요.allowPrivilegeEscalation이 true라면no_new_privs는 false로 설정돼요. 컨테이너 사양의securityContext필드에allowPrivilegeEscalation이 정의되지 않았다면 기본값은 true예요.allowPrivilegeEscalation: false는 privileged로 실행되거나CAP_SYS_ADMIN기능이 있는 컨테이너와는 결합해 설정할 수 없는 모순이에요.readOnlyRootFilesystem: 컨테이너의 루트 파일시스템을 읽기 전용으로 마운트해요.
위 항목은 보안 컨텍스트 설정의 완전한 집합이 아니에요. 포괄적인 목록은 SecurityContext를 참고하세요.
출처: 문서
본문
시작하기 전에 (Before you begin)
쿠버네티스 클러스터가 필요하고, kubectl 명령줄 도구가 클러스터와 통신하도록 구성돼 있어야 해요. 이 튜토리얼은 컨트롤 플레인 호스트가 아닌 노드가 두 개 이상 있는 클러스터에서 실행하는 것을 권장해요. 아직 클러스터가 없다면 minikube로 만들거나 다음 쿠버네티스 플레이그라운드 중 하나를 사용할 수 있어요.
- iximiuz Labs
- Killercoda
- KodeKloud
버전을 확인하려면 kubectl version을 입력하세요.
Pod의 보안 컨텍스트 설정하기 (Set the security context for a Pod)
Pod에 대한 보안 설정을 지정하려면 Pod 사양에 securityContext 필드를 포함하세요. securityContext 필드는 PodSecurityContext 객체예요. Pod에 지정한 보안 설정은 Pod의 모든 컨테이너에 적용돼요. securityContext와 emptyDir 볼륨이 있는 Pod의 구성 파일은 다음과 같아요.
apiVersion: v1
kind: Pod
metadata:
name: security-context-demo
spec:
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
supplementalGroups: [4000]
volumes:
- name: sec-ctx-vol
emptyDir: {}
containers:
- name: sec-ctx-demo
image: busybox:1.28
command: [ "sh", "-c", "sleep 1h" ]
volumeMounts:
- name: sec-ctx-vol
mountPath: /data/demo
securityContext:
allowPrivilegeEscalation: false
구성 파일에서 runAsUser 필드는 Pod의 모든 컨테이너에 대해 모든 프로세스가 사용자 ID 1000으로 실행되도록 지정해요. runAsGroup 필드는 Pod의 어떤 컨테이너든 모든 프로세스에 대해 기본 그룹 ID 3000을 지정해요. 이 필드를 생략하면 컨테이너의 기본 그룹 ID는 root(0)이 돼요. runAsGroup을 지정하면 생성되는 모든 파일도 사용자 1000과 그룹 3000이 소유해요. fsGroup 필드를 지정했기 때문에 컨테이너의 모든 프로세스는 보충 그룹 ID 2000의 일부이기도 해요. 볼륨 /data/demo와 그 볼륨에 생성되는 모든 파일의 소유자는 그룹 ID 2000이에요. 또한 supplementalGroups 필드를 지정하면 컨테이너의 모든 프로세스는 지정된 그룹의 일부이기도 해요. 이 필드를 생략하면 비어 있음을 의미해요.
Pod를 생성해요.
kubectl apply -f https://k8s.io/examples/pods/security/security-context.yaml
Pod의 컨테이너가 실행 중인지 확인해요.
kubectl get pod security-context-demo
실행 중인 컨테이너에 쉘을 얻어요.
kubectl exec -it security-context-demo -- sh
쉘에서 실행 중인 프로세스를 나열해요.
ps
출력은 프로세스가 runAsUser의 값인 사용자 1000으로 실행 중임을 보여줘요.
PID USER TIME COMMAND
1 1000 0:00 sleep 1h
6 1000 0:00 sh
...
쉘에서 /data로 이동해 디렉토리를 나열해요.
cd /data
ls -l
출력은 /data/demo 디렉토리가 fsGroup의 값인 그룹 ID 2000을 가짐을 보여줘요.
drwxrwsrwx 2 root 2000 4096 Jun 6 20:08 demo
쉘에서 /data/demo로 이동해 파일을 만들어요.
cd demo
echo hello > testfile
/data/demo 디렉토리의 파일을 나열해요.
ls -l
출력은 testfile이 fsGroup의 값인 그룹 ID 2000을 가짐을 보여줘요.
-rw-r--r-- 1 1000 2000 6 Jun 6 20:08 testfile
다음 명령을 실행해요.
id
출력은 다음과 비슷해요.
uid=1000 gid=3000 groups=2000,3000,4000
출력에서 gid가 runAsGroup 필드와 같은 3000인 것을 볼 수 있어요. runAsGroup을 생략했다면 gid는 0(root)으로 유지되고 프로세스는 root(0) 그룹이 소유한 파일과 root(0) 그룹에 필요한 그룹 권한을 가진 그룹과 상호작용할 수 있어요. 또한 groups에 gid 외에 fsGroup과 supplementalGroups가 지정한 그룹 ID가 포함돼 있는 것을 볼 수 있어요.
쉘을 종료해요.
exit
컨테이너 이미지의 /etc/group에 정의된 암시적 그룹 멤버십 (Implicit group memberships defined in /etc/group in the container image)
기본적으로 쿠버네티스는 Pod의 그룹 정보를 컨테이너 이미지의 /etc/group에 정의된 정보와 병합해요.
apiVersion: v1
kind: Pod
metadata:
name: security-context-demo
spec:
securityContext:
runAsUser: 1000
runAsGroup: 3000
supplementalGroups: [4000]
containers:
- name: sec-ctx-demo
image: registry.k8s.io/e2e-test-images/agnhost:2.45
command: [ "sh", "-c", "sleep 1h" ]
securityContext:
allowPrivilegeEscalation: false
이 Pod 보안 컨텍스트는 runAsUser, runAsGroup, supplementalGroups를 포함해요. 하지만 실제로 컨테이너 프로세스에 붙는 보충 그룹에는 컨테이너 이미지의 /etc/group에서 온 그룹 ID도 포함된다는 것을 볼 수 있어요.
Pod를 생성해요.
kubectl apply -f https://k8s.io/examples/pods/security/security-context-5.yaml
Pod의 컨테이너가 실행 중인지 확인해요.
kubectl get pod security-context-demo
실행 중인 컨테이너에 쉘을 얻어요.
kubectl exec -it security-context-demo -- sh
(계속) 보안 컨텍스트 예시 계속:
- 컨테이너 이미지의
/etc/group에 있는 그룹과의 상호작용 fsGroup과 권한 있는 볼륨- 컨테이너의 보안 컨텍스트 설정
- 권한 상승(privilege escalation) 설정
나머지 섹션에 대해서는 원문을 참고하세요.