컨테이너 격리 확인

박도준·2022년 1월 12일
1

Kubernetes & Docker

목록 보기
10/12



아래 실습은 macOS(v11.1)에서 진행되었습니다.



Vagrant 설치

VirtualBox를 통해 VM을 프로비저닝하기 위해 Vagrant를 설치한다.

# brew를 이용하여 설치
$ brew install --cask vagrant

# 설치 확인
$ vagrant --version

VirtualBox 설치

Mac에서 6.1.28버전 이후에서는 host-only network 사용 대역 제약이 있으니, 6.1.26 버전 사용을 권장한다.

https://download.virtualbox.org/virtualbox/6.1.26/


Vagrant -> VirtualBox -> VM

Vagrant에서는 Vagrantfile을 통해 VM을 프로비저닝하는데, Vagrantfile에는 어떤 box 파일을 사용할 것인지, VM에 대한 하드웨어 설정(CPU,메모리 사이즈,네트워크 등) 등을 정의한다.

Vagrantfile을 프로비저닝 한 후, vagrant ssh 명령어를 통해 접속한다.

| Vagrantfile은 가시다님께서 제공한 것을 사용 🙏

# Ubuntu 배포 관련 Vagrantfile 파일 다운
$ curl -O https://raw.githubusercontent.com/gasida/NDKS/main/1/Ubuntu/Vagrantfile

# vagrant 프로비저닝
$ vagrant up

# Ubuntu SSH 접속
$ vagrant ssh

VM에 접속 후, 계정 정보 및 버전을 확인해본다.

# 현재 사용 계정 정보 확인
$ whoami

# 버전 확인
$ lsb_release -a


도커 컨테이너 설치

Install link

설치 후, 프로세스, 네트워크 정보 등을 확인해본다.

# 프로세스 확인
$ ps -ef

# 네트워크 정보 확인
$ ip -c addr

# 이더넷 브리지 정보 확인
$ brctl show



컨테이너 격리

네임스페이스는 프로세스를 실행할 때 시스템의 리소스를 분리해서 실행할 수 있도록 도와주는 기능이다.

단일 네임스페이스에서는 한 시스템의 프로세스들이 기본적으로 시스템의 리소스들을 공유해서 실행된다. 실제로 리눅스에서는 1번 프로세스(init)에 할당되어있는 네임스페이스들을 자식 프로세스들이 모두 공유해서 사용하는 구조로 이루어져있다.

네임스페이스를 살펴보면 아래와 같다.


(O'REILLY - Networking and Kubernetes 책)

위 그림을 보면 Node가 Ubuntu 호스트이고, 파란 네모가 컨테이너를 나타낸다. 그림처럼 UID, PID, NET, IPC의 네임스페이스가 호스트와 격리되어 있는 것을 볼 수 있다.


PID

다양한 네임스페이스 중 PID를 예시로 살펴본다.

PID 네임스페이스는 프로세스의 ID를 격리할 수 있는 네임스페이스이다. 리눅스에서 PID는 init 프로세스 1을 시작하며 그 외에 모든 프로세스는 항상 1보다 큰 PID를 부여받는다.

❓ 만약 컨테이너와 같이 새로운 PID 네임스페이스로 분리하면 어떻게 될까?
👉 PID가 다시 1부터 시작합니다. 단, 이 프로세스는 디폴트 네임스페이스와 분리된 PID 네임스페이스에 동시에 속하게 되며, 분리된 새로운 네임스페이스에서는 PID가 1부터 시작하지만, 디폴트 네임스페이스 관점에서는 어떤 한 프로세스에서 fork되었기 때문에 1보다 큰 PID 값을 가지게 된다.

(https://netpple.github.io/docs/make-container-without-docker/container-internal-2)

pstree -p 명령어를 통해 확인 가능하다.

더 자세한 내용은 여기




실습을 통해 확인

# Ubuntu 컨테이너 bash 접속 후 명령어 실행
$ ![](https://velog.velcdn.com/images%2Fdojun527%2Fpost%2Feca517ce-ae3b-4aa6-b9ff-757e1d9106b1%2F%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-01-12%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2011.58.28.png)

# 현재 bash 쉘의 프로세스 ID
$ ps $$


# 컨테이너 내부의 네임스페이스 정보
$ ls -l /proc/$$/ns
total 0
lrwxrwxrwx 1 root root 0 Jan 12 14:59 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 root root 0 Jan 12 14:59 ipc -> 'ipc:[4026532260]'
lrwxrwxrwx 1 root root 0 Jan 12 14:59 mnt -> 'mnt:[4026532258]'
lrwxrwxrwx 1 root root 0 Jan 12 14:59 net -> 'net:[4026532263]'
lrwxrwxrwx 1 root root 0 Jan 12 14:59 pid -> 'pid:[4026532261]'
lrwxrwxrwx 1 root root 0 Jan 12 14:59 pid_for_children -> 'pid:[4026532261]'
lrwxrwxrwx 1 root root 0 Jan 12 14:59 user -> 'user:[4026531837]'
lrwxrwxrwx 1 root root 0 Jan 12 14:59 uts -> 'uts:[4026532259]'
# 호스트 shell의 네임스페이스 정보
$ ls -l /proc/$$/ns
total 0
lrwxrwxrwx 1 root root 0 Jan 12 15:01 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 root root 0 Jan 12 15:01 ipc -> 'ipc:[4026531839]'
lrwxrwxrwx 1 root root 0 Jan 12 15:01 mnt -> 'mnt:[4026531840]'
lrwxrwxrwx 1 root root 0 Jan 12 15:01 net -> 'net:[4026531992]'
lrwxrwxrwx 1 root root 0 Jan 12 15:01 pid -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 Jan 12 15:01 pid_for_children -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 Jan 12 15:01 user -> 'user:[4026531837]'
lrwxrwxrwx 1 root root 0 Jan 12 15:01 uts -> 'uts:[4026531838]'

📍 위의 두 네임스페이스를 비교해보면 ipc,mnt,net,pid,uts가 다른 것을 볼 수 있다. -> 호스트 환경과 격리된 환경이다.

위에서 PID를 봤듯이 컨테이너는 호스트로부터 격리는 되었지만 하나의 프로세스에서 fork되어 생성되었기 때문에, 호스트에서 컨테이너 내의 프로세스에 접근하여 종료할 수 있다.

# 터미널 1(컨테이너) : Ubuntu 컨테이너 bash 접속 후 명령어 실행
$ sleep 1000


# 터미널 2(호스트)
$ ps -C sleep
    PID TTY          TIME CMD
   4912 pts/0    00:00:00 sleep
   
# 컨테이너 내부에서 실행되고 있는 sleep 프로세스 kill
$ kill -9 4912


컨테이너와 호스트의 네임스페이스를 비교했을 때 Cgroup은 같았는데, 이는 호스트의 커널을 공유해서 사용하기 때문이다.

  • Cgroup : 프로세스들의 자원의 사용(CPU, 메모리, 네트워크 등)을 제한하고 격리시키는 리눅스 커널 기능

👉 컨테이너는 하나의 독립적인 운영체제가 아닌, 호스트의 커널을 공유하여 동작하는 리눅스 프로세스이다.



참고자료

https://www.44bits.io/ko/keyword/linux-namespace

https://www.44bits.io/ko/post/is-docker-container-a-virtual-machine-or-a-process

profile
Better late than never

0개의 댓글