SlideShare a Scribd company logo
1 of 42
Download to read offline
도커 없이 컨테이너 만들기
8편
Sam.0
실습과 함께 완성해보는
실습은 . . .
● 맥 환경에서 VirtualBox + Vagrant 기반으로 준비되었습니다
○ 맥 이외의 OS 환경도 괜찮습니다만
○ 원활한 실습을 위해서
○ “VirtualBox or VMware + Vagrant”는 권장드립니다.
● 실습환경 구성을 위한 Vagrantfile을 제공합니다.
실습을 위한 사전 준비 사항 실습 환경 구성하기 클릭
Vagrantfile
● 오른쪽의 텍스트를 복사하신 후
● 로컬에 Vagrantfile로 저장하여
사용하면 됩니다.
● vagrant 사용법은 공식문서를
참고해 주세요
https://www.vagrantup.com/docs/i
ndex
실습을 위한 사전 준비 사항 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 go <<<<<<"
curl -O https://storage.googleapis.com/golang/go1.15.7.linux-amd64.tar.gz > /dev/null 2>&1 &&
tar xf go1.15.7.linux-amd64.tar.gz &&
sudo mv go /usr/local/ &&
echo 'PATH=$PATH:/usr/local/go/bin' | tee /home/vagrant/.bash_profile
echo ">>>>> install docker <<<<<<"
sudo apt-get -y install apt-transport-https ca-certificates curl gnupg-agent software-properties-common > /dev/null 2>&1 &&
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - &&
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" &&
sudo apt-get update &&
sudo apt-get -y install docker-ce docker-ce-cli containerd.io > /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
실습 환경 구성하기 클릭
# sudo -Es
실습 계정 (root)
# cd /tmp
실습 폴더
vagrant + virtual vm
ubuntu 18.04
docker 20.10.5 * 도커 이미지 다운로드 및 컨테이너 비교를 위한 용도로 사용합니다.
기타 설치된 툴
~ tree, jq, brctl, … 등 실습을 위한 툴
Vagrantfile 제공 환경
실습을 위한 사전 준비 사항 실습 환경 구성하기 클릭
초기의 컨테이너
root isolation + mount isolation 으로 충분하다고 생각
아니 근데… ?
container
호스트의 프로세스들이 다 보이네 …
pid namespace 내 것만 딱 ~ 보일 수는 없을까요?
container 이렇게 ~
1979
chroot
2000
Jails
2013
2002
mount ns
2006
Linux
2.6.19
uts, ipc ns
2009
net ns
2012
user ns
LXC
(LinuX Containers)
2008
pid ns, cgroup
PID Namespace
PID Namespace : isolates Process IDs
pid ?
- process identifier
- unique
- from 1
process tree ?
- tree-like structure
- parent --(fork)--> child
- tracking process
1
2 3
5
8 9
4
6 7
0
Level 5
Level 4
Level 3
Level 2
Level 1
Q) if process dies ?
process dies?
- x (parent)
- y, z (child)
- parent --(wait)-- child
1
2 3
x
y z
.
.
.
wait child
2.child exit
3.update CHILD’S exit status
1. wait
child process가 죽으면?
부모가 wait하여 정리
process dies? zombie
- parent NO wait ?
- Zombie (서류상으로만 남아있음)
1
2 3
x
z
.
.
.
NO wait
부모가 wait하지 않으면 ?
y
child exit
alive
~ 부모가 종료할 때까지 남아 있게 됨
(부모가 아주 오래 오래 ~ 살면? ㅋㅋ )
process dies?
- x (parent)
- y, z (child)
1
2 3
x
y z
.
.
.
parent exit
부모 프로세스가 먼저 죽으면?
process dies? orphan
- x (parent) ~ die
- y, z (child) ~ orphan
- pid 1 (new parent)
1
2 3 y z
...
부모 프로세스가 먼저 죽으면?
pid 1 ~ orphan(y,z)을 거두고 종료되면 정리 (reaping)
pid 1 ?
- init process
- created by kernel (pid 0)
- root of process tree (in user-space)
- reaping zombie, orphan
- if dies → panic (reboot required)
0
2 3
1
난 특별 ~
pid namespace isolate the process ID number space
- pid number space
- unique view for application
- has own process tree 1
2 3
4
1
2 3
4
5
PID namespace (child)
PID namespace (parent)
pid namespace isolate the process ID number space
- enable container migration
(isolated pid number space)
Host #A --(migration)--> Host #B
1
2 3
4
1
2 3
x
y
PID namespace (child)
PID namespace (parent)
.
.
.
Host #A
Host #B
migration
참고: 컨테이너 라이브 마이그레이션
pid namespace isolate the process ID number space
- unshare & fork (required)
- (forked) child becomes “1”
- child has “2 pids” 1(6)
2(7) 3(8)
4(9)
1
2 3
4
5
PID namespace (child)
PID namespace (parent)
fork
pid namespace isolate the process ID number space
- nested hierarchical structure
(parent & child namespace)
- parent sees processes in child
1(6)
2(7) 3(8)
4(9)
1
2 3
4
5
PID namespace (child)
PID namespace (parent)
fork
pid 1 in pid namespace
- signal handling
- reaping zombie, orphan
- lifecycle ~ pid1 dies, pid ns dies
(실습) pid namespace 생성
터미널 #1
# unshare -fp --mount-proc
unshare
- p : unshare the PID namespace
- f : fork
- --mount-proc : mount the proc filesystem
pid namespace 를 생성해 봅시다
터미널 #2
# ps -ef | grep unshare
# lsns -p <pid>
# lsns <mnt inode>
(실습) pid namespace 생성 --mount-proc ? proc 파일시스템 마운트 옵션
--mount-proc : mount the proc filesystem
proc 파일시스템이란? (man page)
(실습) pid namespace 생성
/proc (procfs)
- pseudo filesystem (memory based virtual filesystem)
- 커널이 관리하는 시스템 정보의 제공과 제어
- 커널 데이터 구조의 접근을 쉽게 할 수 있음
- 시스템 모니터링과 분석에 활용
(실습) pid namespace 생성
컨테이너 (pid namespace) 안에서 프로세스 정보를 조회하고 제어하기
위함
proc 파일시스템이란?
터미널 #2 (host ~ parent namespace)
# lsns -t pid -p 16922
터미널 #1 (child namespace)
/# lsns -t pid -p 1
(실습) pid namespace 생성 pid namespace 정보 확인
부모 눈에는 자식들 노는게
그저 다 보이는 구만 . . .
!
터미널 #1
/# exit
(실습) pid namespace 생성 exit 하여 pid namespace를 닫아 주세요
터미널 #1
# vi signal.py
import sys
import signal
import time
def signal_handler(signum, frame):
print("Gracefully shutting down after receiving signal(%s) " % signum)
# sys.exit(0)
if __name__ == "__main__":
signal.signal(signal.SIGTERM, signal_handler)
signal.signal(signal.SIGINT, signal_handler)
while True:
time.sleep(0.5) # simulate work
print("Interrupt me")
(실습) pid1 ~ signal handling 특별한 pid1의 시그널 처리를 확인해 봅시다
0.5초 sleep 하고 “Interrupt me”를
출력하는 무한루프 코드입니다.
SIGTERM과 SIGINT 시그널 발생 시
signal_handler를 호출합니다.
signal_handler는 signum을 포함한
메시지를 출력합니다.
종료코드(sys.exit)는 주석처리해
둡니다.
터미널 #1 (child namespace)
# unshare -fp python signal.py
Interrupt me
Interrupt me
Interrupt me
. . .
(실습) pid1 ~ signal handling child pid namespace에서 signal.py를 실행
# ps -ef | grep signal.py
. . .
root 7617 7602 unshare -fp python signal.py
root 7618 7617 python signal.py
. . .
터미널 #1 (child namespace)
Interrupt me
Interrupt me
Interrupt me
. . .
(실습) pid1 ~ signal handling child pid namespace에서 signal.py를 실행
호스트 상에서 PID (7618) 확인
터미널 #2 (host)
* pid는 각 자 실습환경마다 다릅니다.
# nsenter -m -p -t 7618
/#
터미널 #1 (child namespace)
. . .
Interrupt me
Interrupt me
Interrupt me
. . .
(실습) pid1 ~ signal handling child namespace에 attach 해봅시다
pid namespace에 nsenter하여
pid1(signal.py) 확인
터미널 #2
/# ps -ef
root 1 0 python signal.py
root 2 0 -bash
root 6 2 ps -ef
/# exit
터미널 #1 (child namespace)
. . .
Interrupt me
Interrupt me
Interrupt me
. . .
(실습) pid1 ~ signal handling 특별한 pid1은 signal.py
pid namespace에 nsenter하여
pid1(signal.py) 확인
터미널 #2 (child namespace)
# kill -SIGHUP 7618
터미널 #1 (child namespace)
. . .
Interrupt me
Interrupt me
Interrupt me
. . .
(실습) pid1 ~ signal handling 시그널을 날려보세요
SYNOPSYS : kill -<signum> <pid>
* SIGINT, SIGTERM이외의 시그널은 무시됩니다 (단, SIGKILL 예외)
터미널 #2 (host ~ parent namespace)
# kill -SIGINT 7618
# kill -SIGTERM 7618
터미널 #1 (child namespace)
. . .
Gracefully shutting down after receiving signal(2)
. . .
Gracefully shutting down after receiving signal(15)
. . .
(실습) pid1 ~ signal handling SIGINT와 SIGTERM 시그널도 보내보세요
코드에 작성한 대로 signal_handler에서 처리한 로그를 출력해 줍니다.
터미널 #2 (host ~ parent namespace)
# kill -SIGKILL 7618
터미널 #1 (child namespace)
. . .
Killed
#
(실습) pid1 ~ signal handling only SIGKILL로만 죽일 수 있음
signal.py는 pid 1(init process) 이지만 시그널 처리를 안함
→ 사용자 구현에 의존
터미널 #2 (host ~ parent namespace)
child namespace에서 pid1인
signal.py가 죽으면서
해당 pid namespace는 닫힙니다.
# ps aux | grep sleep
. . .
root 7941 docker run busybox sleep 3600
root 8017 sleep 3600
. . .
터미널 #1 (child namespace)
(실습) docker container ~ signal handling 도커 컨테이너의 pid1은 어떨까요? (시그널 처리를 할까요?)
# docker run --rm --name busybox busybox sleep 3600
터미널 #2 (host ~ parent namespace)
# docker exec busybox ps -ef
. . .
1 root sleep 3600
. . .
터미널 #1 (child namespace)
(실습) docker container ~ signal handling pid1은 sleep 3600
# docker run --rm --name busybox busybox sleep 3600
터미널 #2 (host ~ parent namespace)
# kill -SIGHUP 8017
# kill -SIGINT 8017
# kill -SIGTERM 8017
# kill -SIGKILL 8017
터미널 #1 (child namespace)
(실습) docker container ~ signal handling SIGKILL로만 죽일 수 있음
도커 역시 pid 1을 ...
→ 사용자 구현에 의존
# docker run --rm --name busybox busybox sleep 3600
터미널 #2 (host ~ parent namespace)
터미널 #1 (child namespace)
# docker run --rm --name busybox --init busybox sleep 3600
(실습) docker ~ Simple init process 도커 컨테이너 기동 옵션 --init
도커는 옵션으로
→ 심플 init process를 제공합니다
터미널 #1 (child namespace)
# docker run --rm --name busybox --init busybox sleep 3600
(실습) docker ~ Simple init process
# ps aux | grep sleep
. . .
root 8399 7687 docker run --rm --name busybox
--init busybox sleep 3600
root 8487 8458 /sbin/docker-init -- sleep 3600
root 8537 8487 sleep 3600
. . .
아까와는 다르게 docker-init 이라는 프로세스가 보입니다
터미널 #2 (host ~ parent namespace)
터미널 #1 (child namespace)
# docker run --rm --name busybox --init busybox sleep 3600
(실습) docker ~ Simple init process
# docker exec busybox ps -ef
. . .
1 root /sbin/docker-init -- sleep 3600
8 root sleep 3600
컨테이너 안에서 보면 ~ pid1은 docker-init
터미널 #2 (host ~ parent namespace)
터미널 #1 (child namespace)
/# docker run --rm --name busybox --init busybox sleep 3600
#
(실습) docker ~ Simple init process docker-init (pid1)이 시그널 처리를 해줌
# kill -SIGHUP 8487
--- 오메 ~ 바로 죽어 버려야 ---
# kill -SIGINT 8487
# kill -SIGTERM 8487
# kill -SIGKILL 8487
터미널 #2 (host ~ parent namespace)
END
목차 보기
수고 많으셨습니다 다음편에서 봬요 :-)

More Related Content

What's hot

Docker Casual Talk #2 - Dockerizing newrelic-sysmond
Docker Casual Talk #2 - Dockerizing newrelic-sysmondDocker Casual Talk #2 - Dockerizing newrelic-sysmond
Docker Casual Talk #2 - Dockerizing newrelic-sysmondDaegwon Kim
 
랩탑으로 tensorflow 도전하기 - tensorflow 설치
랩탑으로 tensorflow 도전하기 - tensorflow 설치랩탑으로 tensorflow 도전하기 - tensorflow 설치
랩탑으로 tensorflow 도전하기 - tensorflow 설치Lee Seungeun
 
[오픈소스컨설팅]Docker기초 실습 교육 20181113_v3
[오픈소스컨설팅]Docker기초 실습 교육 20181113_v3[오픈소스컨설팅]Docker기초 실습 교육 20181113_v3
[오픈소스컨설팅]Docker기초 실습 교육 20181113_v3Ji-Woong Choi
 
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기흥배 최
 
도커 학습과 Boot2Docker
도커 학습과 Boot2Docker도커 학습과 Boot2Docker
도커 학습과 Boot2Dockerpyrasis
 
리눅스서버세팅-김태호
리눅스서버세팅-김태호리눅스서버세팅-김태호
리눅스서버세팅-김태호ETRIBE_STG
 
이것이 리눅스다 - 김종욱
이것이 리눅스다 - 김종욱이것이 리눅스다 - 김종욱
이것이 리눅스다 - 김종욱Jong Wook Kim
 
20150502 unix v6로 배우는 커널의 원리와 구조 1 김지은
20150502 unix v6로 배우는 커널의 원리와 구조 1 김지은20150502 unix v6로 배우는 커널의 원리와 구조 1 김지은
20150502 unix v6로 배우는 커널의 원리와 구조 1 김지은jieun kim
 
하이퍼레저 패브릭 실습자료
하이퍼레저 패브릭 실습자료하이퍼레저 패브릭 실습자료
하이퍼레저 패브릭 실습자료TIMEGATE
 
20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은
20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은
20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은jieun kim
 
[세미나] Vagrant 이지원
[세미나] Vagrant 이지원[세미나] Vagrant 이지원
[세미나] Vagrant 이지원지원 이
 
(참고) Elk stack 설치 및 kafka
(참고) Elk stack 설치 및 kafka(참고) Elk stack 설치 및 kafka
(참고) Elk stack 설치 및 kafkaNoahKIM36
 
우분투 커널 컴파일
우분투 커널 컴파일우분투 커널 컴파일
우분투 커널 컴파일he4722
 
[H3 2012] 내컴에선 잘되던데? - vagrant로 서버와 동일한 개발환경 꾸미기
[H3 2012] 내컴에선 잘되던데? - vagrant로 서버와 동일한 개발환경 꾸미기[H3 2012] 내컴에선 잘되던데? - vagrant로 서버와 동일한 개발환경 꾸미기
[H3 2012] 내컴에선 잘되던데? - vagrant로 서버와 동일한 개발환경 꾸미기KTH, 케이티하이텔
 
[2D4]Python에서의 동시성_병렬성
[2D4]Python에서의 동시성_병렬성[2D4]Python에서의 동시성_병렬성
[2D4]Python에서의 동시성_병렬성NAVER D2
 
Ipython server(Jupyter Server) 만들기
Ipython server(Jupyter Server) 만들기Ipython server(Jupyter Server) 만들기
Ipython server(Jupyter Server) 만들기Hyun-sik Yoo
 
하둡 고가용성(HA) 설정
하둡 고가용성(HA) 설정하둡 고가용성(HA) 설정
하둡 고가용성(HA) 설정NoahKIM36
 
Zookeeper 활용 nifi clustering
Zookeeper 활용 nifi clusteringZookeeper 활용 nifi clustering
Zookeeper 활용 nifi clusteringNoahKIM36
 
리얼리눅스 제 1 회 세미나: "리눅스, 제대로 알고 코딩하자!"
리얼리눅스 제 1 회 세미나: "리눅스, 제대로 알고 코딩하자!"리얼리눅스 제 1 회 세미나: "리눅스, 제대로 알고 코딩하자!"
리얼리눅스 제 1 회 세미나: "리눅스, 제대로 알고 코딩하자!"리얼리눅스
 

What's hot (20)

Docker Casual Talk #2 - Dockerizing newrelic-sysmond
Docker Casual Talk #2 - Dockerizing newrelic-sysmondDocker Casual Talk #2 - Dockerizing newrelic-sysmond
Docker Casual Talk #2 - Dockerizing newrelic-sysmond
 
랩탑으로 tensorflow 도전하기 - tensorflow 설치
랩탑으로 tensorflow 도전하기 - tensorflow 설치랩탑으로 tensorflow 도전하기 - tensorflow 설치
랩탑으로 tensorflow 도전하기 - tensorflow 설치
 
Linux tutorial
Linux tutorialLinux tutorial
Linux tutorial
 
[오픈소스컨설팅]Docker기초 실습 교육 20181113_v3
[오픈소스컨설팅]Docker기초 실습 교육 20181113_v3[오픈소스컨설팅]Docker기초 실습 교육 20181113_v3
[오픈소스컨설팅]Docker기초 실습 교육 20181113_v3
 
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
 
도커 학습과 Boot2Docker
도커 학습과 Boot2Docker도커 학습과 Boot2Docker
도커 학습과 Boot2Docker
 
리눅스서버세팅-김태호
리눅스서버세팅-김태호리눅스서버세팅-김태호
리눅스서버세팅-김태호
 
이것이 리눅스다 - 김종욱
이것이 리눅스다 - 김종욱이것이 리눅스다 - 김종욱
이것이 리눅스다 - 김종욱
 
20150502 unix v6로 배우는 커널의 원리와 구조 1 김지은
20150502 unix v6로 배우는 커널의 원리와 구조 1 김지은20150502 unix v6로 배우는 커널의 원리와 구조 1 김지은
20150502 unix v6로 배우는 커널의 원리와 구조 1 김지은
 
하이퍼레저 패브릭 실습자료
하이퍼레저 패브릭 실습자료하이퍼레저 패브릭 실습자료
하이퍼레저 패브릭 실습자료
 
20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은
20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은
20150509 unix v6로 배우는 커널의 원리와 구조 3 김지은
 
[세미나] Vagrant 이지원
[세미나] Vagrant 이지원[세미나] Vagrant 이지원
[세미나] Vagrant 이지원
 
(참고) Elk stack 설치 및 kafka
(참고) Elk stack 설치 및 kafka(참고) Elk stack 설치 및 kafka
(참고) Elk stack 설치 및 kafka
 
우분투 커널 컴파일
우분투 커널 컴파일우분투 커널 컴파일
우분투 커널 컴파일
 
[H3 2012] 내컴에선 잘되던데? - vagrant로 서버와 동일한 개발환경 꾸미기
[H3 2012] 내컴에선 잘되던데? - vagrant로 서버와 동일한 개발환경 꾸미기[H3 2012] 내컴에선 잘되던데? - vagrant로 서버와 동일한 개발환경 꾸미기
[H3 2012] 내컴에선 잘되던데? - vagrant로 서버와 동일한 개발환경 꾸미기
 
[2D4]Python에서의 동시성_병렬성
[2D4]Python에서의 동시성_병렬성[2D4]Python에서의 동시성_병렬성
[2D4]Python에서의 동시성_병렬성
 
Ipython server(Jupyter Server) 만들기
Ipython server(Jupyter Server) 만들기Ipython server(Jupyter Server) 만들기
Ipython server(Jupyter Server) 만들기
 
하둡 고가용성(HA) 설정
하둡 고가용성(HA) 설정하둡 고가용성(HA) 설정
하둡 고가용성(HA) 설정
 
Zookeeper 활용 nifi clustering
Zookeeper 활용 nifi clusteringZookeeper 활용 nifi clustering
Zookeeper 활용 nifi clustering
 
리얼리눅스 제 1 회 세미나: "리눅스, 제대로 알고 코딩하자!"
리얼리눅스 제 1 회 세미나: "리눅스, 제대로 알고 코딩하자!"리얼리눅스 제 1 회 세미나: "리눅스, 제대로 알고 코딩하자!"
리얼리눅스 제 1 회 세미나: "리눅스, 제대로 알고 코딩하자!"
 

Similar to 도커없이컨테이너 만들기 8편 - pid namespace

Hideroot - Inc0gnito 2016
Hideroot - Inc0gnito 2016Hideroot - Inc0gnito 2016
Hideroot - Inc0gnito 2016perillamint
 
리눅스 커널 기초 태스크관리
리눅스 커널 기초 태스크관리리눅스 커널 기초 태스크관리
리눅스 커널 기초 태스크관리Seungyong Lee
 
[2014 CodeEngn Conference 11] 이경식 - 동적 추적 프레임워크를 이용한 OS X 바이너리 분석
[2014 CodeEngn Conference 11] 이경식 - 동적 추적 프레임워크를 이용한 OS X 바이너리 분석[2014 CodeEngn Conference 11] 이경식 - 동적 추적 프레임워크를 이용한 OS X 바이너리 분석
[2014 CodeEngn Conference 11] 이경식 - 동적 추적 프레임워크를 이용한 OS X 바이너리 분석GangSeok Lee
 
Linux Kernel Boot Process , SOSCON 2015, By Mario Cho
Linux Kernel Boot Process , SOSCON 2015, By Mario ChoLinux Kernel Boot Process , SOSCON 2015, By Mario Cho
Linux Kernel Boot Process , SOSCON 2015, By Mario ChoMario Cho
 
Hyperledger fabric practice(pdf)
Hyperledger fabric practice(pdf)Hyperledger fabric practice(pdf)
Hyperledger fabric practice(pdf)wonyong hwang
 
Android+init+process
Android+init+processAndroid+init+process
Android+init+processHong Jae Kwon
 
kics2013-winter-biomp-slide-20130127-1340
kics2013-winter-biomp-slide-20130127-1340kics2013-winter-biomp-slide-20130127-1340
kics2013-winter-biomp-slide-20130127-1340Samsung Electronics
 
Git 더하기 GitHub(구름IDE 환경)
Git 더하기 GitHub(구름IDE 환경)Git 더하기 GitHub(구름IDE 환경)
Git 더하기 GitHub(구름IDE 환경)Junyoung Lee
 
안드로이드 플랫폼 설명
안드로이드 플랫폼 설명안드로이드 플랫폼 설명
안드로이드 플랫폼 설명Peter YoungSik Yun
 
소셜게임 서버 개발 관점에서 본 Node.js의 장단점과 대안
소셜게임 서버 개발 관점에서 본 Node.js의 장단점과 대안소셜게임 서버 개발 관점에서 본 Node.js의 장단점과 대안
소셜게임 서버 개발 관점에서 본 Node.js의 장단점과 대안Jeongsang Baek
 
내컴에선 잘되던데? Vagrant로 서버와 동일한 개발환경 꾸미기
내컴에선 잘되던데? Vagrant로 서버와 동일한 개발환경 꾸미기내컴에선 잘되던데? Vagrant로 서버와 동일한 개발환경 꾸미기
내컴에선 잘되던데? Vagrant로 서버와 동일한 개발환경 꾸미기소리 강
 
(망고210& Gingerbread) u-boot 컴파일 및 다운로드
(망고210& Gingerbread) u-boot 컴파일 및 다운로드(망고210& Gingerbread) u-boot 컴파일 및 다운로드
(망고210& Gingerbread) u-boot 컴파일 및 다운로드종인 전
 
ARTIK 710 IoT class 02
ARTIK 710 IoT class 02ARTIK 710 IoT class 02
ARTIK 710 IoT class 02정출 김
 
안드로이드 와 디바이스 드라이버 적용 기법
안드로이드 와 디바이스 드라이버 적용 기법안드로이드 와 디바이스 드라이버 적용 기법
안드로이드 와 디바이스 드라이버 적용 기법chon2010
 
도커(Docker) 메트릭스 & 로그 수집
도커(Docker) 메트릭스 & 로그 수집도커(Docker) 메트릭스 & 로그 수집
도커(Docker) 메트릭스 & 로그 수집Daegwon Kim
 
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기Jaeseung Ha
 
이호민 - 우분투 환경에서의 임베디드 개발환경 구축 및 어플리케이션 개발 (2010Y06M24D)
이호민 - 우분투 환경에서의 임베디드 개발환경 구축 및 어플리케이션 개발 (2010Y06M24D)이호민 - 우분투 환경에서의 임베디드 개발환경 구축 및 어플리케이션 개발 (2010Y06M24D)
이호민 - 우분투 환경에서의 임베디드 개발환경 구축 및 어플리케이션 개발 (2010Y06M24D)Ubuntu Korea Community
 

Similar to 도커없이컨테이너 만들기 8편 - pid namespace (20)

Hideroot - Inc0gnito 2016
Hideroot - Inc0gnito 2016Hideroot - Inc0gnito 2016
Hideroot - Inc0gnito 2016
 
리눅스 커널 기초 태스크관리
리눅스 커널 기초 태스크관리리눅스 커널 기초 태스크관리
리눅스 커널 기초 태스크관리
 
[2014 CodeEngn Conference 11] 이경식 - 동적 추적 프레임워크를 이용한 OS X 바이너리 분석
[2014 CodeEngn Conference 11] 이경식 - 동적 추적 프레임워크를 이용한 OS X 바이너리 분석[2014 CodeEngn Conference 11] 이경식 - 동적 추적 프레임워크를 이용한 OS X 바이너리 분석
[2014 CodeEngn Conference 11] 이경식 - 동적 추적 프레임워크를 이용한 OS X 바이너리 분석
 
Linux Kernel Boot Process , SOSCON 2015, By Mario Cho
Linux Kernel Boot Process , SOSCON 2015, By Mario ChoLinux Kernel Boot Process , SOSCON 2015, By Mario Cho
Linux Kernel Boot Process , SOSCON 2015, By Mario Cho
 
Hyperledger fabric practice(pdf)
Hyperledger fabric practice(pdf)Hyperledger fabric practice(pdf)
Hyperledger fabric practice(pdf)
 
Android+init+process
Android+init+processAndroid+init+process
Android+init+process
 
kics2013-winter-biomp-slide-20130127-1340
kics2013-winter-biomp-slide-20130127-1340kics2013-winter-biomp-slide-20130127-1340
kics2013-winter-biomp-slide-20130127-1340
 
04 프로세스
04 프로세스04 프로세스
04 프로세스
 
Git 더하기 GitHub(구름IDE 환경)
Git 더하기 GitHub(구름IDE 환경)Git 더하기 GitHub(구름IDE 환경)
Git 더하기 GitHub(구름IDE 환경)
 
안드로이드 플랫폼 설명
안드로이드 플랫폼 설명안드로이드 플랫폼 설명
안드로이드 플랫폼 설명
 
소셜게임 서버 개발 관점에서 본 Node.js의 장단점과 대안
소셜게임 서버 개발 관점에서 본 Node.js의 장단점과 대안소셜게임 서버 개발 관점에서 본 Node.js의 장단점과 대안
소셜게임 서버 개발 관점에서 본 Node.js의 장단점과 대안
 
내컴에선 잘되던데? Vagrant로 서버와 동일한 개발환경 꾸미기
내컴에선 잘되던데? Vagrant로 서버와 동일한 개발환경 꾸미기내컴에선 잘되던데? Vagrant로 서버와 동일한 개발환경 꾸미기
내컴에선 잘되던데? Vagrant로 서버와 동일한 개발환경 꾸미기
 
(망고210& Gingerbread) u-boot 컴파일 및 다운로드
(망고210& Gingerbread) u-boot 컴파일 및 다운로드(망고210& Gingerbread) u-boot 컴파일 및 다운로드
(망고210& Gingerbread) u-boot 컴파일 및 다운로드
 
ARTIK 710 IoT class 02
ARTIK 710 IoT class 02ARTIK 710 IoT class 02
ARTIK 710 IoT class 02
 
K8s in action02
K8s in action02K8s in action02
K8s in action02
 
안드로이드 와 디바이스 드라이버 적용 기법
안드로이드 와 디바이스 드라이버 적용 기법안드로이드 와 디바이스 드라이버 적용 기법
안드로이드 와 디바이스 드라이버 적용 기법
 
도커(Docker) 메트릭스 & 로그 수집
도커(Docker) 메트릭스 & 로그 수집도커(Docker) 메트릭스 & 로그 수집
도커(Docker) 메트릭스 & 로그 수집
 
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
 
이호민 - 우분투 환경에서의 임베디드 개발환경 구축 및 어플리케이션 개발 (2010Y06M24D)
이호민 - 우분투 환경에서의 임베디드 개발환경 구축 및 어플리케이션 개발 (2010Y06M24D)이호민 - 우분투 환경에서의 임베디드 개발환경 구축 및 어플리케이션 개발 (2010Y06M24D)
이호민 - 우분투 환경에서의 임베디드 개발환경 구축 및 어플리케이션 개발 (2010Y06M24D)
 
HI-ARC PS 101
HI-ARC PS 101HI-ARC PS 101
HI-ARC PS 101
 

도커없이컨테이너 만들기 8편 - pid namespace

  • 1. 도커 없이 컨테이너 만들기 8편 Sam.0 실습과 함께 완성해보는
  • 2. 실습은 . . . ● 맥 환경에서 VirtualBox + Vagrant 기반으로 준비되었습니다 ○ 맥 이외의 OS 환경도 괜찮습니다만 ○ 원활한 실습을 위해서 ○ “VirtualBox or VMware + Vagrant”는 권장드립니다. ● 실습환경 구성을 위한 Vagrantfile을 제공합니다. 실습을 위한 사전 준비 사항 실습 환경 구성하기 클릭
  • 3. Vagrantfile ● 오른쪽의 텍스트를 복사하신 후 ● 로컬에 Vagrantfile로 저장하여 사용하면 됩니다. ● vagrant 사용법은 공식문서를 참고해 주세요 https://www.vagrantup.com/docs/i ndex 실습을 위한 사전 준비 사항 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 go <<<<<<" curl -O https://storage.googleapis.com/golang/go1.15.7.linux-amd64.tar.gz > /dev/null 2>&1 && tar xf go1.15.7.linux-amd64.tar.gz && sudo mv go /usr/local/ && echo 'PATH=$PATH:/usr/local/go/bin' | tee /home/vagrant/.bash_profile echo ">>>>> install docker <<<<<<" sudo apt-get -y install apt-transport-https ca-certificates curl gnupg-agent software-properties-common > /dev/null 2>&1 && sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - && sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" && sudo apt-get update && sudo apt-get -y install docker-ce docker-ce-cli containerd.io > /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 실습 환경 구성하기 클릭
  • 4. # sudo -Es 실습 계정 (root) # cd /tmp 실습 폴더 vagrant + virtual vm ubuntu 18.04 docker 20.10.5 * 도커 이미지 다운로드 및 컨테이너 비교를 위한 용도로 사용합니다. 기타 설치된 툴 ~ tree, jq, brctl, … 등 실습을 위한 툴 Vagrantfile 제공 환경 실습을 위한 사전 준비 사항 실습 환경 구성하기 클릭
  • 5. 초기의 컨테이너 root isolation + mount isolation 으로 충분하다고 생각
  • 6. 아니 근데… ? container 호스트의 프로세스들이 다 보이네 …
  • 7. pid namespace 내 것만 딱 ~ 보일 수는 없을까요? container 이렇게 ~
  • 8. 1979 chroot 2000 Jails 2013 2002 mount ns 2006 Linux 2.6.19 uts, ipc ns 2009 net ns 2012 user ns LXC (LinuX Containers) 2008 pid ns, cgroup PID Namespace PID Namespace : isolates Process IDs
  • 9. pid ? - process identifier - unique - from 1
  • 10. process tree ? - tree-like structure - parent --(fork)--> child - tracking process 1 2 3 5 8 9 4 6 7 0 Level 5 Level 4 Level 3 Level 2 Level 1 Q) if process dies ?
  • 11. process dies? - x (parent) - y, z (child) - parent --(wait)-- child 1 2 3 x y z . . . wait child 2.child exit 3.update CHILD’S exit status 1. wait child process가 죽으면? 부모가 wait하여 정리
  • 12. process dies? zombie - parent NO wait ? - Zombie (서류상으로만 남아있음) 1 2 3 x z . . . NO wait 부모가 wait하지 않으면 ? y child exit alive ~ 부모가 종료할 때까지 남아 있게 됨 (부모가 아주 오래 오래 ~ 살면? ㅋㅋ )
  • 13. process dies? - x (parent) - y, z (child) 1 2 3 x y z . . . parent exit 부모 프로세스가 먼저 죽으면?
  • 14. process dies? orphan - x (parent) ~ die - y, z (child) ~ orphan - pid 1 (new parent) 1 2 3 y z ... 부모 프로세스가 먼저 죽으면? pid 1 ~ orphan(y,z)을 거두고 종료되면 정리 (reaping)
  • 15. pid 1 ? - init process - created by kernel (pid 0) - root of process tree (in user-space) - reaping zombie, orphan - if dies → panic (reboot required) 0 2 3 1 난 특별 ~
  • 16. pid namespace isolate the process ID number space - pid number space - unique view for application - has own process tree 1 2 3 4 1 2 3 4 5 PID namespace (child) PID namespace (parent)
  • 17. pid namespace isolate the process ID number space - enable container migration (isolated pid number space) Host #A --(migration)--> Host #B 1 2 3 4 1 2 3 x y PID namespace (child) PID namespace (parent) . . . Host #A Host #B migration 참고: 컨테이너 라이브 마이그레이션
  • 18. pid namespace isolate the process ID number space - unshare & fork (required) - (forked) child becomes “1” - child has “2 pids” 1(6) 2(7) 3(8) 4(9) 1 2 3 4 5 PID namespace (child) PID namespace (parent) fork
  • 19. pid namespace isolate the process ID number space - nested hierarchical structure (parent & child namespace) - parent sees processes in child 1(6) 2(7) 3(8) 4(9) 1 2 3 4 5 PID namespace (child) PID namespace (parent) fork
  • 20. pid 1 in pid namespace - signal handling - reaping zombie, orphan - lifecycle ~ pid1 dies, pid ns dies
  • 21. (실습) pid namespace 생성 터미널 #1 # unshare -fp --mount-proc unshare - p : unshare the PID namespace - f : fork - --mount-proc : mount the proc filesystem pid namespace 를 생성해 봅시다
  • 22. 터미널 #2 # ps -ef | grep unshare # lsns -p <pid> # lsns <mnt inode> (실습) pid namespace 생성 --mount-proc ? proc 파일시스템 마운트 옵션 --mount-proc : mount the proc filesystem
  • 23. proc 파일시스템이란? (man page) (실습) pid namespace 생성
  • 24. /proc (procfs) - pseudo filesystem (memory based virtual filesystem) - 커널이 관리하는 시스템 정보의 제공과 제어 - 커널 데이터 구조의 접근을 쉽게 할 수 있음 - 시스템 모니터링과 분석에 활용 (실습) pid namespace 생성 컨테이너 (pid namespace) 안에서 프로세스 정보를 조회하고 제어하기 위함 proc 파일시스템이란?
  • 25. 터미널 #2 (host ~ parent namespace) # lsns -t pid -p 16922 터미널 #1 (child namespace) /# lsns -t pid -p 1 (실습) pid namespace 생성 pid namespace 정보 확인 부모 눈에는 자식들 노는게 그저 다 보이는 구만 . . . !
  • 26. 터미널 #1 /# exit (실습) pid namespace 생성 exit 하여 pid namespace를 닫아 주세요
  • 27. 터미널 #1 # vi signal.py import sys import signal import time def signal_handler(signum, frame): print("Gracefully shutting down after receiving signal(%s) " % signum) # sys.exit(0) if __name__ == "__main__": signal.signal(signal.SIGTERM, signal_handler) signal.signal(signal.SIGINT, signal_handler) while True: time.sleep(0.5) # simulate work print("Interrupt me") (실습) pid1 ~ signal handling 특별한 pid1의 시그널 처리를 확인해 봅시다 0.5초 sleep 하고 “Interrupt me”를 출력하는 무한루프 코드입니다. SIGTERM과 SIGINT 시그널 발생 시 signal_handler를 호출합니다. signal_handler는 signum을 포함한 메시지를 출력합니다. 종료코드(sys.exit)는 주석처리해 둡니다.
  • 28. 터미널 #1 (child namespace) # unshare -fp python signal.py Interrupt me Interrupt me Interrupt me . . . (실습) pid1 ~ signal handling child pid namespace에서 signal.py를 실행
  • 29. # ps -ef | grep signal.py . . . root 7617 7602 unshare -fp python signal.py root 7618 7617 python signal.py . . . 터미널 #1 (child namespace) Interrupt me Interrupt me Interrupt me . . . (실습) pid1 ~ signal handling child pid namespace에서 signal.py를 실행 호스트 상에서 PID (7618) 확인 터미널 #2 (host) * pid는 각 자 실습환경마다 다릅니다.
  • 30. # nsenter -m -p -t 7618 /# 터미널 #1 (child namespace) . . . Interrupt me Interrupt me Interrupt me . . . (실습) pid1 ~ signal handling child namespace에 attach 해봅시다 pid namespace에 nsenter하여 pid1(signal.py) 확인 터미널 #2
  • 31. /# ps -ef root 1 0 python signal.py root 2 0 -bash root 6 2 ps -ef /# exit 터미널 #1 (child namespace) . . . Interrupt me Interrupt me Interrupt me . . . (실습) pid1 ~ signal handling 특별한 pid1은 signal.py pid namespace에 nsenter하여 pid1(signal.py) 확인 터미널 #2 (child namespace)
  • 32. # kill -SIGHUP 7618 터미널 #1 (child namespace) . . . Interrupt me Interrupt me Interrupt me . . . (실습) pid1 ~ signal handling 시그널을 날려보세요 SYNOPSYS : kill -<signum> <pid> * SIGINT, SIGTERM이외의 시그널은 무시됩니다 (단, SIGKILL 예외) 터미널 #2 (host ~ parent namespace)
  • 33. # kill -SIGINT 7618 # kill -SIGTERM 7618 터미널 #1 (child namespace) . . . Gracefully shutting down after receiving signal(2) . . . Gracefully shutting down after receiving signal(15) . . . (실습) pid1 ~ signal handling SIGINT와 SIGTERM 시그널도 보내보세요 코드에 작성한 대로 signal_handler에서 처리한 로그를 출력해 줍니다. 터미널 #2 (host ~ parent namespace)
  • 34. # kill -SIGKILL 7618 터미널 #1 (child namespace) . . . Killed # (실습) pid1 ~ signal handling only SIGKILL로만 죽일 수 있음 signal.py는 pid 1(init process) 이지만 시그널 처리를 안함 → 사용자 구현에 의존 터미널 #2 (host ~ parent namespace) child namespace에서 pid1인 signal.py가 죽으면서 해당 pid namespace는 닫힙니다.
  • 35. # ps aux | grep sleep . . . root 7941 docker run busybox sleep 3600 root 8017 sleep 3600 . . . 터미널 #1 (child namespace) (실습) docker container ~ signal handling 도커 컨테이너의 pid1은 어떨까요? (시그널 처리를 할까요?) # docker run --rm --name busybox busybox sleep 3600 터미널 #2 (host ~ parent namespace)
  • 36. # docker exec busybox ps -ef . . . 1 root sleep 3600 . . . 터미널 #1 (child namespace) (실습) docker container ~ signal handling pid1은 sleep 3600 # docker run --rm --name busybox busybox sleep 3600 터미널 #2 (host ~ parent namespace)
  • 37. # kill -SIGHUP 8017 # kill -SIGINT 8017 # kill -SIGTERM 8017 # kill -SIGKILL 8017 터미널 #1 (child namespace) (실습) docker container ~ signal handling SIGKILL로만 죽일 수 있음 도커 역시 pid 1을 ... → 사용자 구현에 의존 # docker run --rm --name busybox busybox sleep 3600 터미널 #2 (host ~ parent namespace)
  • 38. 터미널 #1 (child namespace) # docker run --rm --name busybox --init busybox sleep 3600 (실습) docker ~ Simple init process 도커 컨테이너 기동 옵션 --init 도커는 옵션으로 → 심플 init process를 제공합니다
  • 39. 터미널 #1 (child namespace) # docker run --rm --name busybox --init busybox sleep 3600 (실습) docker ~ Simple init process # ps aux | grep sleep . . . root 8399 7687 docker run --rm --name busybox --init busybox sleep 3600 root 8487 8458 /sbin/docker-init -- sleep 3600 root 8537 8487 sleep 3600 . . . 아까와는 다르게 docker-init 이라는 프로세스가 보입니다 터미널 #2 (host ~ parent namespace)
  • 40. 터미널 #1 (child namespace) # docker run --rm --name busybox --init busybox sleep 3600 (실습) docker ~ Simple init process # docker exec busybox ps -ef . . . 1 root /sbin/docker-init -- sleep 3600 8 root sleep 3600 컨테이너 안에서 보면 ~ pid1은 docker-init 터미널 #2 (host ~ parent namespace)
  • 41. 터미널 #1 (child namespace) /# docker run --rm --name busybox --init busybox sleep 3600 # (실습) docker ~ Simple init process docker-init (pid1)이 시그널 처리를 해줌 # kill -SIGHUP 8487 --- 오메 ~ 바로 죽어 버려야 --- # kill -SIGINT 8487 # kill -SIGTERM 8487 # kill -SIGKILL 8487 터미널 #2 (host ~ parent namespace)
  • 42. END 목차 보기 수고 많으셨습니다 다음편에서 봬요 :-)