컨테이너❓
: 리눅스 커널 및 운영체제의 격리 및 자원 제어 기능과 관련된 기술을 활용해서 만든 실행환경
: 파일 시스템 격리

$ chroot /my/container /bin/bash
# /my/container를 루트로 인식
# 프로세스에게 격리된 파일 시스템 제공
👉🏻 별도 파일 시스템 처럼 동작
: 리소스 격리
clone() # 새로운 프로세스를 생성하고 이를 새로 지정된 네임스페이스에 연결
unshare() # 현재 프로세스를 새로 지정된 네임스페이스에 연결
setns() # 이미 존재하는 네임스페이스에 프로세스를 연결
: 컨테이너별로 개별적인 PID 트리 구성
$ unshare --fork --pid --mount-proc=/proc /bin/sh
$ ps axf
: 네임스페이스 별로 hostname을 격리
$ 터미널1 unshare -u /bin/bash
$ 터미널1 hostname happy
$ 터미널1,2 hostname
# 결과
$ 서로 다른 hostname
----------------------------
$ 터미널1,2 ls -l /proc/$$/ns/uts
# 결과
서로 다른 id
: 각 Network 네임스페이스 별로 개별적인 인터페이스와 IP 구성을 가짐

$ ip netns add guestnet # 새로운 NET namespace (guestnet) 생성
$ ip netns exec guestnet ip link
# 결과
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
$ ip netns exec guestnet ip link set lo up # guestnet namespace의 loopback 활성화
$ ip netns exec guestnet ip link
# 결과
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
$ ip link add host type veth peer name guest # host, guest namesapce veth로 연결
$ ip link
# 결과
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
link/ether 0a:12:c1:32:ba:91 brd ff:ff:ff:ff:ff:ff
3: guest@host: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 3e:77:07:ba:f4:b9 brd ff:ff:ff:ff:ff:ff
4: host@guest: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 5e:f3:c3:b4:17:01 brd ff:ff:ff:ff:ff:ff
$ ip link set guest netns guestnet # guest를 guestnet에 할당
$ ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
link/ether 0a:12:c1:32:ba:91 brd ff:ff:ff:ff:ff:ff
4: host@if3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 5e:f3:c3:b4:17:01 brd ff:ff:ff:ff:ff:ff link-netns guestnet
# 3번이 빠져있음. guest net으로 들어가서!
$ ip netns exec guestnet ip link # guestnet의 ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
3: guest@if4: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 3e:77:07:ba:f4:b9 brd ff:ff:ff:ff:ff:ff link-netnsid 0
$ ip link set host up
$ ip address add 2.2.2.1/24 dev host # host(veth) 에 IP 할당
$ ip address show dev host
4: host@if3: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default qlen 1000
link/ether 5e:f3:c3:b4:17:01 brd ff:ff:ff:ff:ff:ff link-netns guestnet
inet 2.2.2.1/24 scope global host
valid_lft forever preferred_lft forever
$ ip netns exec guestnet ip link set guest up
$ ip netns exec guestnet ip address add 2.2.2.2/24 dev guest # guest(veth)에 IP 할당
$ ip netns exec guestnet ip address show dev guest
3: guest@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 3e:77:07:ba:f4:b9 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 2.2.2.2/24 scope global guest
valid_lft forever preferred_lft forever
inet6 fe80::3c77:7ff:feba:f4b9/64 scope link
valid_lft forever preferred_lft forever
# ping 테스트
$ ping 2.2.2.2
# 결과
PING 2.2.2.2 (2.2.2.2) 56(84) bytes of data.
64 bytes from 2.2.2.2: icmp_seq=1 ttl=64 time=0.034 ms
64 bytes from 2.2.2.2: icmp_seq=2 ttl=64 time=0.030 ms
64 bytes from 2.2.2.2: icmp_seq=3 ttl=64 time=0.032 ms
64 bytes from 2.2.2.2: icmp_seq=4 ttl=64 time=0.030 ms
^C
--- 2.2.2.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3085ms
rtt min/avg/max/mdev = 0.030/0.031/0.034/0.001 ms
$ ip netns exec guestnet ping 2.2.2.1
# 결과
PING 2.2.2.1 (2.2.2.1) 56(84) bytes of data.
64 bytes from 2.2.2.1: icmp_seq=1 ttl=64 time=0.016 ms
64 bytes from 2.2.2.1: icmp_seq=2 ttl=64 time=0.028 ms
64 bytes from 2.2.2.1: icmp_seq=3 ttl=64 time=0.029 ms
64 bytes from 2.2.2.1: icmp_seq=4 ttl=64 time=0.028 ms
^C
--- 2.2.2.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3098ms
rtt min/avg/max/mdev = 0.016/0.025/0.029/0.005 ms
mnt (마운트)
uts (호스트 이름)
ipc (프로세스 간 통신)
user (사용자/권한)
: 자원 제한 및 관리
# 터미널 2
$ top
# 터미널 1
$ /root/a.out &
$ /root/b.out &
$ ls -l tasks cpu.shares
$
$ 실습 추가
: 파일 시스템
읽기 전용 이미지 + 쓰기 가능한 레이어 → 최종 컨테이너 파일 시스템
$ mkdir overlayfs
$ cd overlayfs/
$ mkdir container image1 image2 work merge
$ touch image1/{a,b} image2/c
$ mount -t overlay overlay -o lowerdir=image2:image1,upperdir=container,workdir=work merge
$ df
# 결과
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/root 7941576 2172708 5752484 28% /
tmpfs 490184 0 490184 0% /dev/shm
tmpfs 196076 888 195188 1% /run
tmpfs 5120 0 5120 0% /run/lock
/dev/xvda15 106832 6190 100642 6% /boot/efi
tmpfs 98036 4 98032 1% /run/user/1000
overlay 7941576 2172708 5752484 28% /root/overlayfs/merge
$ tree . -l work
.
├── container
├── image1
│ ├── a
│ └── b
├── image2
│ └── c
├── merge
│ ├── a
│ ├── b
│ └── c
└── work
└── work
work
└── work
1 directory, 0 files
# a 지우면 이미지는 그대로, 컨테이너만 수정 생김
# d 추가해도 컨테이너만 수정 생김
: 네트워크 보안/방화벽