무엇이 보이는가를 제한하는 리눅스 커널 기능.
- PID — 프로세스 목록. 컨테이너 안에서 자기가 PID 1 이 된다
- Network — 네트워크 인터페이스·라우팅·포트. 컨테이너마다 자기 IP
- Mount — 마운트 지점. 자기 루트 파일시스템만 본다
- UTS — 호스트명·도메인명
- IPC — 공유 메모리·세마포어
- User — UID/GID 매핑. 안에서는 root, 밖에서는 일반 사용자
- Cgroup — cgroup 계층 자체를 가린다
$ docker run --rm alpine ps -ef
PID USER COMMAND
1 root ps -ef ← 안에서는 자기가 1번이다
$ docker run --rm --pid=host alpine ps -ef | head -3
1 root /sbin/init ← 호스트 네임스페이스면 전부 보인다
PID 네임스페이스가 만드는 결과
컨테이너 안 프로세스는 자기 PID 를 1 로 본다 호스트에서는 다른 번호다 (48231 같은)
- 안에서 kill 1 을 하면 자기 자신을 죽인다
- 안에서는 호스트나 다른 컨테이너의 프로세스를 볼 수 없다
- PID 1 이라는 사실이 시그널 처리 방식을 바꾼다 (별도 항목)
User 네임스페이스와 rootless
-
안에서는 UID 0(root), 밖에서는 UID 100000 같은 비특권 사용자로 매핑한다
-
컨테이너를 탈출해도 호스트에서는 일반 사용자다
-
rootless 모드는 데몬 자체를 비특권으로 돌린다
- 보안 경계가 한 겹 늘어난다
- 대신 1024 미만 포트 bind · 일부 네트워크·스토리지 기능에 제약이 있다
-
기본 설정에서는 User 네임스페이스가 꺼져 있는 경우가 많다
-
컨테이너의 root 가 호스트의 root 와 같은 UID 다
-
그래서 USER 지시자로 비루트를 지정하는 것이 중요하다
네임스페이스는 공유할 수 있다
# 실행 중인 컨테이너의 네임스페이스에 들어가 진단한다
docker run --rm -it \
--pid=container:web --network=container:web \
nicolaka/netshoot sh
셸이 없는 이미지(distroless)를 디버깅하는 정석 방법이다 쿠버네티스의 임시 컨테이너(kubectl debug --target)도 같은 원리다
- 파드 안 컨테이너들이 네트워크·IPC 네임스페이스를 공유하는 것도 이것이다
- 같은 파드 안에서는 localhost 로 서로를 부른다
격리를 푸는 순간이 곧 위험 지점이다
- --pid=host — 호스트 프로세스를 전부 본다. 죽일 수도 있다
- --net=host — 호스트 포트를 그대로 쓴다. 다른 서비스와 충돌·도청 가능
- --ipc=host — 호스트 공유 메모리 접근
- --userns=host — User 네임스페이스 격리 해제
모니터링 에이전트가 --pid=host 를 요구하는 경우가 흔하다 필요한 것은 맞지만, 그 컨테이너의 이미지 신뢰도를 다르게 봐야 한다
마운트 네임스페이스와 이미지
컨테이너가 자기 루트 파일시스템만 보는 것이 마운트 네임스페이스 덕이다 chroot 와 비슷하지만 훨씬 강하다 — chroot 는 탈출 기법이 알려져 있고, 마운트 정보 자체는 공유됐다
여기에 union filesystem 이 얹혀 '이미지 레이어 + 쓰기 레이어' 가 하나의 루트로 보인다
- namespace 와 이미지가 만나는 지점이다
면접 함정
- ❌ "namespace가 자원을 제한한다" → 제한은 cgroup이다. namespace는 가시성만이다.
- ❌ "컨테이너 안 root는 무해하다" → User 네임스페이스를 켜지 않으면 호스트 root와 같은 UID다.