컨테이너의 이해: 심화편
개요
컨테이너가 어떻게 독립적인 환경을 유지하는지 이해하기 위해, 네임스페이스
와 croups
개념을 알아야 합니다.
네임스페이스 (Namespaces)
리눅스 네임스페이스는 컨테이너가 마치 별도의 독립된 시스템처럼 동작할 수 있도록 하는 기술입니다.
1. 종류
네임스페이스 | 역할 | 컨테이너 적용 사례 |
---|---|---|
PID | 프로세스 ID를 분리하여 독립적인 프로세스 공간 제공 | 각 컨테이너 내부에서 PID 1이 init 프로세스 역할 수행 |
Mount | 컨테이너별로 독립적인 파일 시스템 제공 | 컨테이너 내부에서 호스트의 특정 디렉토리 마운트 |
Network | 컨테이너마다 독립적인 네트워크 인터페이스 제공 | 컨테이너 간 통신을 위해 브리지 네트워크 사용 |
UTS | 컨테이너마다 개별적인 호스트네임 제공 | 컨테이너별로 서로 다른 hostname 사용 |
IPC | 컨테이너 간 공유 메모리 및 메시지 큐 분리 | 각 컨테이너의 공유 메모리 공간 분리 |
User | 컨테이너 내부의 사용자 ID와 호스트의 사용자 ID를 매핑 | 비루트(Non-root) 컨테이너 실행 |
2. 실습
1) PID 네임스페이스 실습 - 프로세스 격리 확인
💡 목표: 네임스페이스를 이용해 별도의 프로세스 공간을 만들고, 격리 여부를 확인합니다.
1️⃣ 새로운 PID 네임스페이스 생성
unshare --fork --pid --mount-proc bash
unshare
: 새로운 네임스페이스를 생성하는 명령어--fork
: 새로운 네임스페이스에서 새로운 프로세스를 실행--pid
: PID 네임스페이스 생성--mount-proc
:/proc
파일 시스템을 새롭게 마운트
2️⃣ 현재 프로세스 확인
ps aux
-> 네임스페이스 내부에서는 PID 1번이 새로 시작된 bash
프로세스가 됩니다.
-> 호스트에서는 이 프로세스를 볼 수 있습니다.
3️⃣ 호스트에서 실행 중인 PID와 비교
ps aux | grep bash
-> PID가 서로 다름을 확인할 수 있습니다.
—
2) Network 네임스페이스 실습 - 네트워크 격리
💡 목표: 컨테이너와 유사하게 격리된 네트워크 환경을 구성하고 확인합니다.
1️⃣ 새로운 네트워크 네임스페이스 생성
ip netns add test_ns
-> test_ns
라는 네임스페이스가 생성됨
2️⃣ 네트워크 네임스페이스 목록 확인
ip netns list
-> test_ns
가 정상적으로 생성되었는지 확인
3️⃣ 네트워크 인터페이스 확인
ip netns exec test_ns ip a
4️⃣ 네트워크 인터페이스 추가
ip link add veth0 type veth peer name veth1
ip link set veth1 netns test_ns
- veth0와 veth1이라는 가상 네트워크 인터페이스를 생성
- veth1을 test_ns 네트워크 네임스페이스로 이동
5️⃣ 네트워크 인터페이스 활성화
ip link set veth0 up
ip netns exec test_ns ip link set veth1 up
- 호스트와 네임스페이스 내부에서 각각 인터페이스를 활성화
6️⃣ IP 주소 할당
ip addr add 192.168.1.1/24 dev veth0
ip netns exec test_ns ip addr add 192.168.1.2/24 dev veth1
- veth0과 veth1에 각각 IP를 할당하여 통신 가능하도록 설정
7️⃣ 핑 테스트
ip netns exec test_ns ping -c 3 192.168.1.1
→ test_ns 내부에서 호스트의 veth0와 정상적으로 통신하는지 확인.
cgroups (Control Groups)
croups는 프로세스별 리소스 사용량을 제한하는 기능을 제공합니다.
1. 주요 기능
기능 | 설명 | 예제 |
---|---|---|
CPU 제한 | 특정 프로세스가 사용할 CPU 양 제한 | cpuset.cpus="0" |
메모리 제한 | 특정 프로세스가 사용할 메모리 제한 | memory.limit_in_bytes="256" |
디스크 I/O 제한 | 특정 프로세스의 디스크 사용량 제한 | blkio.throttle.read_bps_device |
2. 실습
1) CPU 사용 제한
💡 목표: 특정 프로세스가 사용할 CPU를 제한하여 성능을 제어합니다.
1️⃣ cgroups 디렉토리 생성
sudo mkdir -p /sys/fs/cgroup/cpu/demo
2️⃣ 현재 프로세스 ID 확인
echo $$ # 현재 bash 프로세스 ID 확인
-> 현재 실행 중인 bash는
1868
입니다.
3️⃣ 프로세스를 cgroups에 추가
echo 1868 | sudo tee /sys/fs/croup/cpu/demo/cgroup.procs
-> 1868
번 프로세스가 demo
그룹에 속하게 됨.
4️⃣ CPU 사용량 제한 (50% 제한)
echo 50000 | sudo tee /sys/fs/cgroup/cpu/demo/cpu.cfs_quota_us
echo 100000 | sudo tee /sys/fs/cgroup/cpu/demo/cpu.cfs_period_us
- cpu.cfs_quota_us = 50000 → 50ms 동안 실행
- cpu.cfs_period_us = 100000 → 100ms 단위로 제한
- 결과적으로 CPU 사용량이 50% 로 제한됨.
5️⃣ CPU 제한된 상태에서 작업 실행
stress --cu 1
-> CPU 사용량이 50% 이상 올라가지 않음을 확인할 수 있음.
2) 메모리 사용 제한
💡 목표: 특정 프로세스가 사용할 최대 메모리를 제한합니다.
1️⃣ 메모리 제한 디렉토리 생성
sudo mkdir -p /sys/fs/cgroup/memory/demo
2️⃣ 프로세스를 cgroups에 추가
echo 1868 | sudo tee /sys/fs/cgroup/memory/demo/cgroup.procs
3️⃣ 메모리 제한 설정 (256MB)
echo 268435456 | sudo tee /sys/fs/cgroup/memory/demo/memory.limit_in_bytes
4️⃣ 제한된 상태에서 메모리 사용 테스트
stress --vm 1 --vm-bytes 300M
-> 256MB를 초과하면 OOM 발생
결론
- cgroups를 활용해 컨테이너별 CPU 및 메모리 제한을 설정하여 과부하 방지
- 네임스페이스를 활용하여 컨테이너 간 격리를 철저히 유지
- 컨테이너 간 네트워크 트래픽을 제어하여 보안성 확보
댓글남기기