목차
- 1. 왜 컨테이너 없이 격리를 보려고 했는가
- 2. 네임스페이스 개념 설명: 쉽게 말해 무엇이 분리되나
- 자주 쓰는 네임스페이스 종류
- 기술별 차이 한눈에 보기
- 3. 실제 사례 연구: 백업 검증 스크립트를 안전하게 분리하기
- 4. 실전 구현: unshare로 프로세스 격리 만들기
- 4-1. 가장 기본적인 격리 셸 실행
- 4-2. 격리 환경 안에서 hostname 바꾸기
- 4-3. 마운트 뷰 분리와 작업 디렉터리 고립
- 4-4. 네트워크를 완전히 막고 실행하기
- 4-5. 실제 테스트 스크립트 실행 예시
- 5. 조금 더 현실적인 시스템 설계 포인트
- 6. ⚠️ 주의사항과 트러블슈팅: 제가 실제로 막혔던 지점
- 6-1. /proc가 기대와 다르게 보이는 문제
- 6-2. 네트워크가 완전히 끊긴 줄 알았는데 아니었던 문제
- 6-3. 마운트가 호스트까지 영향을 주는 것처럼 보이는 문제
- 6-4. 이게 보안 경계인가요? 라는 질문
- 7. 검증과 결과: 무엇이 달라졌는지 확인하기
- 8. 자주 묻는 질문 정리
- Q1. chroot만 쓰면 안 되나요?
- Q2. 이게 Docker를 완전히 대체하나요?
- Q3. 어떤 상황에서 특히 유용했나요?
- 9. 마무리: 네임스페이스를 알면 컨테이너가 더 잘 보입니다
[리눅스] 컨테이너 없이 네임스페이스로 프로세스 격리하기
리눅스 네임스페이스 사례를 찾다 보면 대부분 Docker나 Kubernetes 이야기로 바로 넘어가더라고요. 근데 현장에서는 꼭 컨테이너 런타임(container runtime)이 있어야만 프로세스 격리를 할 수 있는 건 아닙니다. 저도 홈랩에서 작은 배치 작업, 외부에서 받은 스크립트 검증, 네트워크가 민감한 유지보수 작업을 분리할 때 처음부터 컨테이너를 올리기엔 오버헤드가 애매한 경우가 있었거든요.
그래서 이번 글에서는 컨테이너 원리의 핵심인 Namespace(네임스페이스, 커널 자원 뷰 분리)를 직접 써서 프로세스를 격리한 사례를 정리해보겠습니다. 제가 직접 해보니 처음엔 이게 뭔가 싶었는데, 구조를 한 번 이해하고 나니까 특정 작업을 빠르게 샌드박스(sandbox, 제한된 실행 공간)로 감싸는 데 꽤 유용했습니다. 특히 보안 강화와 시스템 설계 관점에서 어디까지 가능한지 감이 잡히더라고요.
호스트와 격리된 프로세스가 PID, 네트워크, 마운트 관점에서 어떻게 분리되는지 보여주는 개요 이미지입니다.
1. 왜 컨테이너 없이 격리를 보려고 했는가
실무에서 늘 Docker가 정답은 아니었습니다. 예를 들어 이런 경우가 있었습니다.
- 운영 서버에 컨테이너 엔진 설치를 최소화해야 하는 경우
- 일회성 스크립트를 네트워크에서 분리해 실행하고 싶은 경우
- 빌드 작업이나 백업 검증 작업을 호스트와 다른 PID 뷰로 띄우고 싶은 경우
- 문제 재현용 프로세스를 빠르게 분리해 테스트하고 싶은 경우
저는 홈랩에서 외부 저장소에서 받은 백업 복구 스크립트를 바로 호스트에서 돌리기 좀 꺼려졌습니다. 사실 스크립트 한 줄 잘못되면 마운트 포인트를 건드리거나, 예상 못 한 네트워크 접근을 할 수도 있거든요. 그때 느낀 게, “아 컨테이너 이미지를 만들기 전에 커널 기능만으로도 1차 격리는 가능하겠구나”였습니다.
2. 네임스페이스 개념 설명: 쉽게 말해 무엇이 분리되나
쉽게 말해 Namespace(네임스페이스)는 프로세스가 보는 세상 자체를 따로 만드는 기능입니다. 같은 리눅스 커널 위에서 돌지만, 프로세스 입장에서는 자기만의 PID 목록, 네트워크 인터페이스, 호스트 이름, 마운트 뷰를 보게 되는 거죠.
컨테이너 원리를 아주 거칠게 줄이면 이겁니다. Namespace로 보이는 범위를 나누고, Cgroup(컨트롤 그룹, 자원 사용 제한)으로 CPU/메모리를 제한하고, 파일시스템 레이어를 얹는다. 오늘은 그중 Namespace 쪽에 집중해보겠습니다.
자주 쓰는 네임스페이스 종류
- PID Namespace: 프로세스 ID 공간 분리
- Mount Namespace: 마운트 포인트 뷰 분리
- Network Namespace: 네트워크 인터페이스, 라우팅 테이블 분리
- UTS Namespace: hostname, domainname 분리
- IPC Namespace: 프로세스 간 통신 자원 분리
- User Namespace: 사용자/권한 매핑 분리
여기서 중요한 포인트! 네임스페이스만 쓴다고 완전한 보안 샌드박스가 되는 건 아닙니다. 그래도 적어도 “호스트와 같은 뷰를 그대로 공유하지 않게 한다”는 점에서 상당히 큰 차이가 납니다.
기술별 차이 한눈에 보기
| 기술 | 격리 범위 | 장점 | 한계 |
|---|---|---|---|
| chroot(루트 변경) | 파일 경로 중심 | 단순함 | 보안 격리 수단으로는 약함 |
| Namespace(네임스페이스) | PID, 네트워크, 마운트 등 커널 자원 뷰 | 가볍고 빠름 | 자원 제한은 별도 구성 필요 |
| Container(컨테이너) | Namespace + Cgroup + 이미지/런타임 | 운영 자동화에 유리 | 런타임 의존성과 운영 복잡도 증가 |
3. 실제 사례 연구: 백업 검증 스크립트를 안전하게 분리하기
제가 실험한 시나리오는 이렇습니다. 백업 파일 무결성을 확인하고 압축을 풀어보는 스크립트를 테스트해야 했는데, 호스트 네트워크를 그대로 쓰게 두고 싶지 않았고, /tmp 아래에서 이것저것 생성하는 것도 호스트와 분리하고 싶었습니다. 그래서 아래 목표를 잡았습니다.
- 호스트와 다른 PID 공간에서 실행할 것
- 호스트 네트워크를 끊거나 별도 네트워크만 사용할 것
- 마운트 뷰를 분리해서 /proc, 작업 디렉터리를 별도로 보이게 할 것
- 가능하면 hostname도 바꿔서 “격리된 환경”임을 명확히 할 것
이 작업은 컨테이너 엔진 없이도 unshare와 nsenter만으로 꽤 깔끔하게 구성할 수 있었습니다.
unshare 실행 후 PID, UTS, Mount, Network 네임스페이스가 분리되는 흐름을 설명하는 구성 이미지입니다.
4. 실전 구현: unshare로 프로세스 격리 만들기
실제로 써보니까 첫 진입점은 unshare가 제일 직관적이었습니다. 아래 예시는 격리된 셸(shell, 명령 실행 환경)을 띄우는 기본 형태입니다.
4-1. 가장 기본적인 격리 셸 실행
sudo unshare \
--fork \
--pid \
--mount \
--uts \
--ipc \
--net \
--mount-proc \
bash
옵션 의미는 이렇습니다.
--fork: 새로운 프로세스로 진입--pid: 새로운 PID Namespace 생성--mount: 새로운 Mount Namespace 생성--uts: hostname 분리--ipc: IPC 자원 분리--net: Network Namespace 분리--mount-proc: 새 PID 공간에 맞는 /proc 마운트
이 상태로 들어가서 ps를 치면, 호스트 전체 프로세스가 아니라 격리된 프로세스 뷰만 보입니다. 처음 확인했을 때 “오, 진짜 분리됐네” 싶더라고요. 이런 순간이 좀 재밌습니다 ㅎㅎ
4-2. 격리 환경 안에서 hostname 바꾸기
hostname isolated-lab
uname -n
UTS Namespace 덕분에 호스트 이름을 바꿔도 호스트 본체에는 영향이 없습니다. 작은 부분 같아도 테스트 로그를 볼 때 꽤 유용합니다.
4-3. 마운트 뷰 분리와 작업 디렉터리 고립
제가 삽질했던 부분이 여기였습니다. Mount Namespace를 만들었는데도 기존 마운트 전파(propagation) 설정 때문에 예상과 다르게 보이는 경우가 있더라고요. 그래서 보통은 아래처럼 먼저 private으로 바꿔주는 쪽이 안전했습니다.
mount --make-rprivate /
mkdir -p /tmp/lab-root
mount -t tmpfs tmpfs /tmp/lab-root
cd /tmp/lab-root
이렇게 하면 작업 디렉터리를 메모리 기반 tmpfs로 띄워서 테스트 흔적을 최소화할 수 있습니다. 외부 스크립트를 검증할 때 꽤 편했습니다.
4-4. 네트워크를 완전히 막고 실행하기
Network Namespace를 새로 만들면 기본적으로 인터페이스가 거의 없는 상태로 시작합니다. “네트워크 없는 환경에서 이 스크립트가 깨끗하게 도는지” 확인할 때 딱 좋습니다.
ip link set lo up
ip addr
ping -c 1 8.8.8.8
루프백(loopback)만 올리고 외부 인터페이스를 연결하지 않으면 외부 통신은 되지 않습니다. 저는 백업 검증 스크립트가 혹시라도 외부로 뭔가 호출하는지 확인할 때 이 방법을 자주 썼습니다.
4-5. 실제 테스트 스크립트 실행 예시
cat > /tmp/verify-backup.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
mkdir -p work
cd work
echo "test file" > sample.txt
tar -czf sample.tar.gz sample.txt
tar -xzf sample.tar.gz
ps -ef
ip addr || true
hostname
EOF
chmod +x /tmp/verify-backup.sh
/tmp/verify-backup.sh
여기서 보게 되는 ps, ip addr, hostname 결과가 전부 호스트와 다르게 보이면 1차 격리는 성공입니다. 이게 컨테이너 원리 이해에도 정말 도움이 됩니다.
격리된 프로세스 공간과 제한된 네트워크 환경이 실제 명령 결과에서 어떻게 보이는지 보여주는 예시 이미지입니다.
5. 조금 더 현실적인 시스템 설계 포인트
단순 데모를 넘어서 실제 운영에 붙이려면 몇 가지를 같이 봐야 합니다.
- User Namespace를 함께 검토해서 권한 매핑을 분리할 것
- Cgroup으로 CPU/메모리 제한을 따로 둘 것
- seccomp 같은 시스템 콜 필터링까지 가면 더 단단해질 것
- 파일시스템은 가능하면 읽기 전용(read-only) 바인드 마운트도 고려할 것
즉, Namespace는 시작점입니다. 보안 강화라는 말이 과장되지 않으려면, “무엇을 분리했고 무엇은 아직 공유하는가”를 명확히 이해해야 합니다. 저도 처음엔 네임스페이스만 쓰면 거의 컨테이너랑 같은 줄 알았는데, 운영 관점에서는 그 사이에 꽤 많은 층이 있더라고요.
6. ⚠️ 주의사항과 트러블슈팅: 제가 실제로 막혔던 지점
여기서는 진짜 삽질 포인트만 적어보겠습니다. 혹시 비슷한 경험 있으신가요? 아래 부분에서 많이 막힙니다.
6-1. /proc가 기대와 다르게 보이는 문제
원인: 새 PID Namespace를 만들었는데 /proc를 새로 마운트하지 않은 경우입니다.
해결: --mount-proc 옵션을 쓰거나, 진입 후 직접 proc를 마운트합니다.
mount -t proc proc /proc
6-2. 네트워크가 완전히 끊긴 줄 알았는데 아니었던 문제
원인: 별도 네임스페이스를 안 만들고 호스트 네트워크를 그대로 쓴 경우입니다.
해결: --net 사용 여부를 먼저 확인하세요. 그리고 격리 환경 안에서 ip addr를 꼭 확인해야 합니다.
6-3. 마운트가 호스트까지 영향을 주는 것처럼 보이는 문제
원인: 마운트 전파 설정이 공유(shared) 상태인 경우입니다.
해결: 작업 초기에 아래 명령으로 전파 범위를 조정합니다.
mount --make-rprivate /
6-4. 이게 보안 경계인가요? 라는 질문
중요한 답은 “상황에 따라 다릅니다”입니다. Namespace만으로 충분한 경우도 있지만, 신뢰할 수 없는 코드를 장시간 돌리거나 외부 입력이 많은 환경이라면 추가 방어 계층이 필요합니다. 그래서 저는 보통 아래 순서로 생각합니다.
- Namespace로 뷰 분리
- Cgroup으로 자원 제한
- 권한 최소화
- 읽기 전용 마운트, 임시 작업 공간 분리
- 필요시 VM(가상머신) 수준 격리 검토
7. 검증과 결과: 무엇이 달라졌는지 확인하기
격리가 제대로 되었는지는 감으로 보면 안 됩니다. 저는 아래 항목을 체크리스트처럼 확인했습니다.
ps -ef출력에서 호스트 전체 프로세스가 보이지 않는지hostname결과가 격리된 값으로 나오는지ip addr결과에 호스트 인터페이스가 안 보이는지- 작업 중 생성한 파일이 의도한 임시 공간에만 남는지
- 작업 종료 후 흔적 정리가 쉬운지
결론부터 말하면, 컨테이너 없이도 특정 목적의 프로세스 격리는 충분히 실용적이었습니다. 특히 테스트성 작업, 분석성 작업, 외부 스크립트 검증 같은 용도에서는 빠르게 적용할 수 있었고요. 반대로 이미지 배포, 재현 가능한 패키징, 대규모 운영 자동화까지 가면 컨테이너 쪽이 더 낫습니다.
PID, 네트워크, 마운트, hostname 항목별로 격리 전후 차이를 정리한 결과 요약 이미지입니다.
8. 자주 묻는 질문 정리
Q1. chroot만 쓰면 안 되나요?
chroot는 파일 경로 뷰를 바꾸는 데는 유용하지만, PID나 네트워크까지 분리해주지는 않습니다. 그래서 프로세스 격리 목적이면 네임스페이스가 훨씬 적합합니다.
Q2. 이게 Docker를 완전히 대체하나요?
아닙니다. Docker 같은 컨테이너 도구는 이미지 관리, 배포, 네트워크 구성, 볼륨 운영까지 묶어서 편의성을 제공합니다. 네임스페이스는 그 아래 레이어를 이해하고 직접 다루는 방식에 가깝습니다.
Q3. 어떤 상황에서 특히 유용했나요?
저는 홈랩에서 아래 같은 상황에 잘 맞았습니다.
- 일회성 유지보수 스크립트 검증
- 네트워크 차단 상태 재현
- 호스트 프로세스 목록과 분리된 테스트 셸 구성
- 컨테이너 엔진 없는 환경에서의 임시 샌드박스
9. 마무리: 네임스페이스를 알면 컨테이너가 더 잘 보입니다
이번 리눅스 네임스페이스 사례를 통해 느낀 건, 컨테이너는 갑자기 하늘에서 떨어진 기술이 아니라는 점이었습니다. 결국 커널 기능을 조합해서 보안 강화와 운영 편의성을 만든 결과물이더라고요. 제가 직접 해보니 Docker 명령어만 외우던 때보다, 장애를 볼 때도 구조가 훨씬 잘 읽혔습니다.
처음엔 unshare 옵션이 낯설고, /proc나 마운트 전파 때문에 좀 헷갈릴 수 있습니다. 저도 처음엔 꽤 헤맸거든요. 근데 한 번 손으로 만들어보면 시스템 설계 감각이 정말 좋아집니다. 다음 글에서는 이 흐름을 이어서 Cgroup(컨트롤 그룹, 자원 제한)과 함께 묶어 더 실전적인 샌드박스를 만드는 방법도 다뤄볼 예정입니다. 이전 글에서 다룬 리눅스 프로세스 관리 글이 있다면 같이 보셔도 흐름이 잘 이어질 겁니다. ✅
'IT > Linux' 카테고리의 다른 글
| [Linux] Linux 커널 튜닝으로 보는 네트워크 I/O 벤치마크 분석 (0) | 2026.07.05 |
|---|---|
| [Linux] rsyslog Loki 마이그레이션: 레거시 로그 시스템 현대화 경험 (0) | 2026.07.02 |
| [Linux] CentOS 7에서 AlmaLinux 9로: 성공적인 서버 마이그레이션 전략과 실제 경험 (1) | 2026.07.01 |
| [Linux] 리눅스 시스템 장애, 프로세스 비정상 종료 원인 분석 및 해결 사례 연구 (0) | 2026.07.01 |
| [Linux] Linux Namespace 격리 기술, 실제 적용과 검증 방법 (0) | 2026.06.27 |
| [Linux] cgroup vs namespace: 컨테이너 격리의 핵심 비교 분석 (0) | 2026.06.26 |