수년간의 개발 끝에, Kubernetes의 사용자 네임스페이스 지원이 v1.36 릴리스를 통해 정식 버전(GA, General Availability)에 도달했습니다. 이 기능은 리눅스 전용 기능입니다.
저수준 컨테이너 런타임과 루트리스(rootless) 기술을 연구해 온 이들에게 이번 발표는 오랫동안 기다려온 이정표입니다. 마침내 Kubernetes 워크로드에서 "루트리스" 보안 격리를 사용할 수 있는 단계에 도달한 것입니다.
이 기능은 또한 매우 중요한 패턴을 가능하게 합니다. 바로 워크로드를 권한이 있는 상태로 실행하면서도 사용자 네임스페이스 내에 가두는 것입니다. hostUsers: false로 설정하면 CAP_NET_ADMIN과 같은 기능(Capability)이 네임스페이스화됩니다. 즉, 호스트에 영향을 주지 않으면서 컨테이너 로컬 리소스에 대해서만 관리 권한을 부여하게 됩니다. 이를 통해 이전에는 완전한 권한 부여(privileged) 컨테이너를 실행하지 않고는 불가능했던 새로운 유스케이스들을 효과적으로 지원할 수 있게 되었습니다.
UID 0의 문제점
컨테이너 내부에서 루트(root)로 실행되는 프로세스는 커널 관점에서도 호스트의 루트로 간주됩니다. 만약 공격자가 커널 취약점이나 잘못 설정된 마운트를 통해 컨테이너 격리를 뚫고 나간다면, 그들은 호스트의 루트 권한을 갖게 됩니다.
컨테이너 실행을 위한 여러 보안 조치가 마련되어 있지만, 이러한 조치들은 프로세스의 근본적인 정체성을 바꾸지는 못합니다. 프로세스는 여전히 루트의 "일부"를 가지고 있는 셈입니다.
핵심 엔진: ID 매핑 마운트(ID-mapped mounts)
정식 출시(GA)로 가는 길은 단순히 Kubernetes API에 국한된 것이 아니었습니다. 커널이 우리를 위해 작동하도록 만드는 과정이 필요했습니다. 초기 단계에서 가장 큰 걸림돌 중 하나는 볼륨 소유권 문제였습니다. 컨테이너를 높은 UID 범위로 매핑하면, Kubelet은 컨테이너가 파일을 읽고 쓸 수 있도록 연결된 볼륨의 모든 파일에 대해 재귀적으로 chown을 수행해야 했습니다. 대규모 볼륨의 경우, 이 작업은 시작 성능을 심각하게 저하시키는 매우 비용이 많이 드는 작업이었습니다.
핵심 해결사는 ID 매핑 마운트(리눅스 5.12에서 도입되고 이후 버전에서 개선됨)였습니다. 디스크상의 파일 소유권을 다시 쓰는 대신, 커널이 마운트 시점에 이를 재매핑하는 방식입니다.
사용자 네임스페이스가 활성화된 Pod에 볼륨이 마운트되면, 커널은 UID(사용자 ID)와 GID(그룹 ID)를 투명하게 변환합니다. 컨테이너 입장에서는 파일이 UID 0으로 소유된 것처럼 보이지만, 디스크상의 파일 소유권은 변경되지 않으므로 chown이 필요하지 않습니다. 이는 O(1) 연산으로, 즉각적이고 효율적입니다.
Kubernetes v1.36에서 사용하기
사용자 네임스페이스를 사용하는 방법은 매우 간단합니다. Pod 사양(spec)에서 hostUsers: false를 설정하기만 하면 됩니다. 컨테이너 이미지를 변경하거나 복잡한 설정을 할 필요가 없습니다. 인터페이스는 알파(Alpha) 단계에서 도입된 것과 동일하게 유지됩니다. Pod(또는 PodTemplate)의 spec에서 호스트 사용자 네임스페이스를 명시적으로 거부(opt-out)하면 됩니다.
apiVersion: v1
kind: Pod
metadata:
name: isolated-workload
spec:
hostUsers: false
containers:
- name: app
image: fedora:42
securityContext:
runAsUser: 0
사용자 네임스페이스가 실제로 어떻게 작동하는지에 대한 자세한 내용과 '높음(HIGH)' 등급의 CVE가 완화되는 데모를 보려면 이전 블로그 포스트들을 참조하세요: 사용자 네임스페이스 알파(Alpha), 사용자 네임스페이스 알파 단계의 스테이트풀(Stateful) Pod, 사용자 네임스페이스 베타(Beta), 그리고 사용자 네임스페이스 기본 활성화.
참여하기
사용자 네임스페이스에 관심이 있거나 기여하고 싶다면 다음 링크를 확인해 보세요:
감사의 말
이 기능은 완성되기까지 수년이 걸렸습니다. 첫 번째 KEP는 10년 전 다른 기여자들에 의해 열렸으며, 저희는 지난 6년 동안 이를 위해 활발히 작업해 왔습니다. SIG Node, 컨테이너 런타임, 그리고 리눅스 커널에 걸쳐 기여해 주신 모든 분께 감사드립니다. 특히 여러 차례의 알파 및 베타 사이클을 통해 설계를 구체화하는 데 도움을 주신 리뷰어들과 초기 도입자분들께 특별한 감사를 전합니다.