Posts Kubernetes 0
Post
Cancel

Kubernetes 0

Kubernetes 0


💿 도커 컨테이너와 가상머신

가상머신: 운영체제 위헤 하드웨어를 에뮬레이션하고 그 위에 운영체제를 올리고 프로세스를 실행

컨테이너: 하드웨어 에뮬레이션 없이 리눅스 커널을 공유해서 바로 프로세스를 실행

$ docker version
Client: Docker Engine - Community
 Version:           19.03.5
  ...

$ docker run -it ubuntu:latest bash
root@bfccfb4136ae:/# uname -a
Linux f44e33a332f2 4.15.0-70-generic #79-Ubuntu SMP Tue Nov 12 10:36:11 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

root@bfccfb4136ae:/# cat /etc/*-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.3 LTS"
...
1
2
3
4
5
6
7
8
$ docker run -it centos:latest bash
[root@bb0a9b851dbd /]# uname -a
Linux bb0a9b851dbd 4.15.0-70-generic #79-Ubuntu SMP Tue Nov 12 10:36:11 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

[root@bb0a9b851dbd /]# cat /etc/*-release
CentOS Linux release 8.0.1905 (Core)
NAME="CentOS Linux"
VERSION="8 (Core)"

위의 2개의 명령어를 통해

  • cat를 통해 파일시스템(배포판)이 다름
  • uname -a의 출력 결과가 같음(커널이 같다)
    • 둘다 Utuntu 18.04 Vagrant 가상머신에서 실행

이를 통해

  • 도커 데스크탑은 리눅스킷 기반의 경량 가상머신 위에서 도커를 실행
  • 컨테이너는 호스트 시스템의 커널을 사용한다.
  • 컨테이너는 이미지에 따라서 실행되는 환경이 달라진다.

컨테이너가 서로 다른 파일 시스템을 가질 수 있는 이유는 이미지(파일의 집합)를 루트 파일 시스템으로 강제로 인식시켜 프로세스를 실행하기 때문(즉 자신의 루트 /가 아닌 그 아래의 특정 디렉터리를 루트로 인식)


💿 도커 컨테이너와 프로세스

도커 컨테이너는 가상머신이 아니고 프로세스다.

1
2
3
4
5
6
$ echo $$
5673

$ docker run -it ubuntu:latest bash
root@9a09675d42ed:/# echo $$
1

일반적으로 1번 프로세스는 pstree에서 확인해 보면 모든 프로세스가 물려있는 프로세스

컨테이너?

리눅스 커널에 포함된 프로세스 격리 기술들을 사용해서 생성된 특별한 프로세스

1
2
root@47672c55680d:/# kill -9 1
root@47672c55680d:/#

1번 프로세스는 원래 죽일수도 없다.

위와 같은 사실에 비추어 볼때 그러면 어떻게 1번 프로세스가 2개일 수 있냐?(도커는 1번을 죽일수 있고 host의 1번을 죽일 수 없다.)

  • 리눅스의 네임스페이스 때문
  • PID 네임스페이스가 분리되어 있기 때문에 1번이 됨

💿 Namespace

1번

$ echo $$
5673

$ mkdir busybox-image
$ docker run --name busybox-image busybox:latest
$ docker export busybox-image > ./busybox-image/image.tar
$ cd busybox-image; tar xf image.tar; cd ..
$ sudo unshare -p -f --mount-proc chroot ./busybox-image /bin/sh
/ # echo $$
1

2번

$ sudo unshare -p /bin/sh
# echo $$
2170
  • 2번째는 unshare를 통해 네임스페이스를 분리하더라도 호스트의 파일 시스템을 그대로 사용하고 있어서 PID 관련 정보는 /proc 아래의 정보를 사용하기 때문
  • 그래서 –mount-proc으로 /proc을 분리하고 독자적인 환경을 위해 이미지(busybox-image)를 사용

2개의 PID

  1. 프로세스가 바라보는 PID
  2. 호스트가 바라보는 PID

2번을 실행해서 프로세스를 보면

1
2
3
4
5
6
$ ps aux --sort +start_time | tail -n 5
root      2376  0.0  0.1  21472  3700 pts/0    S    03:49   0:00 bash
root      2386  0.0  0.0   7456   732 pts/0    S    03:49   0:00 unshare -p -f --mount-proc chroot ./busybox-image /bin/sh
root      2387  0.0  0.0   1312     4 pts/0    S+   03:49   0:00 /bin/sh
vagrant   2396  0.0  0.1  37516  3480 pts/1    R+   03:50   0:00 ps aux --sort +start_time
vagrant   2397  0.0  0.0   7508   856 pts/1    S+   03:50   0:00 tail -n 5
  • 이렇게 나오는데 2387을 죽이면 sh unshare로 실행된 sh도 같이 종료됨
  • 둘이 같은 프로세스이기 때문
  • 즉 프로세스가 보기에는 자신의 PID가 1번이지만 호스트 입장에서는 2387이라는 뜻

💿 도커 컨테이너와 프로세스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ diff \
  <(ls -Al /proc/1/ns | awk '{ print $9 $10 $11 }') \
  <(ls -Al /proc/2899/ns | awk '{ print $9 $10 $11 }')

3,7c3,7
< ipc->ipc:[4026531839]
< mnt->mnt:[4026531840]
< net->net:[4026531993]
< pid->pid:[4026531836]
< pid_for_children->pid:[4026531836]
---
> ipc->ipc:[4026532238]
> mnt->mnt:[4026532236]
> net->net:[4026532298]
> pid->pid:[4026532239]
> pid_for_children->pid:[4026532239]
9c9
< uts->uts:[4026531838]
---
> uts->uts:[4026532237]
  • ipc, mnt, net, pid, pid_for_children, uts 네임스페이스가 다르다는 것을 확인할 수 있습니다
  • 네임스페이스는 다르지만 ps로 일반적인 프로세스라는 것을 한 번 확인 가능

컨테이너는 특별한 프로세스다~~~ 이말이야~!


https://www.44bits.io/ko/post/is-docker-container-a-virtual-machine-or-a-process#%EB%8F%84%EC%BB%A4-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EA%B0%80-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EC%BB%A4%EB%84%90%EA%B3%BC-%ED%8C%8C%EC%9D%BC-%EC%8B%9C%EC%8A%A4%ED%85%9C-%ED%99%95%EC%9D%B8%ED%95%98%EA%B8%B0)

This post is licensed under CC BY 4.0 by the author.