Upload
xpressengine
View
812
Download
0
Embed Size (px)
Citation preview
누구세요?
• 김훈민. (동생 이름이 정음)
• 결혼 3년차 남편이자 두 아이의 아빠.
• ~2011 웹 개발.
• ~2014 성능팀, 오픈소스 메모리 캐시인 Arcus 개발/운영.
• ~2015 빌드 배포 시스템인 nDeploy팀 소속.
다룰 내용
• Docker & Linux Container
• Tutorial
• Container Orchestration
지옥에서 온 테이블
node.js 웹 서버
Java API 서버
MySQL 서버
메시지 큐 서버
개발자 PC
동료 PC
팀 개발 장비
QA 개발 장비
스테이징 장비
리얼 장비
* Table based on http://www.slideshare.net/dotCloud/docker-intro-november
지옥에서 온 테이블
node.js 웹 서버
Java API 서버
MySQL 서버
메시지 큐 서버
개발자 PC
동료 PC
팀 개발 장비
QA 개발 장비
스테이징 장비
리얼 장비
* Table based on http://www.slideshare.net/dotCloud/docker-intro-november
공용 장비에 손을 대는 순간...
가상 머신으로 해결!?
• 개발 및 배포 환경을 어느 정도 표준화 할 수 있습니다.
• 하지만 최초 설정 이후에는 마찬가지 비용이 발생합니다.
• 시스템 설정 변경
• 시스템 라이브러리 업그레이드
• …
H/W
OS
Hypervisor
VM VM
지옥에서 온 테이블 2
핸드폰
시계
옷장
피아노
기차 물류창고 지게차 항구 배 트럭
http://aceno1.co.kr/box/box1
표준화된 컨테이너
핸드폰
시계
옷장
피아노
기차 물류창고 지게차 항구 배 트럭
각 플랫폼, 모듈을 어디에서든 실행할 수 있는
코드를 위한 컨테이너가 있으면 되겠네요!
리눅스 컨테이너
• 이미 오래 전 부터 LinuX Container 라는 기능이 있었습니다.
• 호스트 환경과 독립된 리눅스 시스템(컨테이너)를 실행하기 위한 시스템 레벨의 가상화 방법. (Hypervisor 없는 VM?)
• cgroup
• namespace
• chroot
• Linux Security Modules(LSM), Mandatory Access Control(MAC)
cgroup
• 2006년 구글에서 개발하여 2.6.24 커널에 포함.
• 각종 시스템 리소스에 대한 접근 제어와 리소스 제약을 담당.
• 각 리소스는 subsystem이라 부릅니다.
• /sys/fs/cgroup 디렉토리에서 각 subsystem을 확인할 수 있음.
• 만약 /sys 디렉토리가 없다면:
• sudo mount -t sysfs sysfs /sys
cgroup subsystem
• /sys/fs/cgroup
• /cpu, /cpuacct, /cpuset
• /memory
• /blkio
• /devices
• /freezer, /perf_event
https://www.kernel.org/doc/Documentation/cgroups/
namespace
• 글로벌 리소스에 대한 프로세스 수준의 격리(isolation)를 제공.
• MNT (마운트 지점, 파일시스템)
• PID (프로세스)
• NET (NIC, 라우팅)
• IPC (System V IPC 리소스)
• UTS (호스트/도메인 이름)
• USER (UID + GID)
• 격리된 프로세스는 자기 자신이 시스템에서 유일하다고 착각한다: /proc/1
https://www.kernel.org/doc/Documentation/namespaces/
chroot
• 프로세스의 root 디렉토리를 변경 할 수 있다.
• chroot
• parent 디렉토리를 유지하면서 root 디렉토리를 마운트.
• pivot_root
• parent 디렉토리 없이 root 디렉토리를 마운트.
https://access.redhat.com/articles/1353593
리눅스 컨테이너
• 어플리케이션을 격리(isolate)하고 패키징(package) 합니다.
• 물리/VM 장비의 여러 요소들을 격리해줍니다.
• 리소스 (CPU, 메모리, I/O 등) — cgroup
• 네임스페이스 (PID, USER, NET 등) — namespace
• 파일시스템 — chroot
* http://www.darkroastedblend.com/2006/12/biggest-ships-in-world-part-3.html
리눅스 컨테이너를
생성하고 실행하며 배포하는 방식을
대중화 한 플랫폼.
Docker
• Docker
• Daemon (libcontainer+libnetwork)
• Client
• Docker Hub: 컨테이너를 유통하는 서비스.
• …
Docker
• 도커 Daemon을 통해 리눅스 컨테이너를 실행하면:
• 도커 이미지를 이용하여 새로운 컨테이너를 위한 파일 시스템을 구성합니다.
• 컨테이너를 위한 네트워킹 설정을 변경해줍니다.
• 격리된 컨테이너 프로세스를 실행합니다.
Docker Toolbox
• 윈도우와 맥에 도커 개발 환경을 꾸며 줍니다.
• https://www.docker.com/docker-toolbox
• 맥에서는 homebrew로 설치 가능.
• $ brew install Caskroom/cask/dockertoolbox
Docker Toolbox
• docker: 도커 클라이언트.
• docker-machine: 도커 서버를 실행할 수 있는 VM 관리.
• docker-compose: 여러 개의 도커 컨테이너를 실행.
• kitematic: 개발 장비의 도커 컨테이너를 쉽게 관리할 수 있는 앱.
• virtualbox: VM
docker-machine
• $ docker-machine create -d virtualbox dev
• dev라는 이름을 가진 virtualbox 도커 VM을 생성.
• $ docker-machine ls
• 생성된 도커 VM 리스트를 확인.
• $ docker-machine ssh dev
• dev VM에 접속.
docker-machine
• $ docker-machine env dev
• dev 도커 VM을 사용할 수 있는 환경변수 설정을 확인한다.
• $ eval $(docker-machine env dev)
• 현재 쉘에서 dev 도커 VM을 사용할 수 있도록 환경변수를 설정.
• $ docker-machine stop dev
• $ docker-machine rm dev
docker
• $ docker run -it --rm busybox top
• -it : 실행된 컨테이너와 상호작용 할 수 있도록 설정.
• --rm : 컨테이너 실행이 끝나면 삭제.
• busybox : 실행할 컨테이너.
• top : 컨테이너가 실행할 명령의 옵션.
docker
• $ docker ps
• $ docker logs <container_id>
• $ docker rm <container_id>
• $ docker rmi <image_id>
• $ docker exec <container_id> <command>
XpressEngine
이렇게 구성하려 합니다
XE Core
MariaDB
:80
:3306
https://github.com/hoonmin/xecore
Docker Image
• <네임스페이스>/<이름>:<태그>
• mariadb:latest
• php:5.6-apache
• hoonmin/xecore:1.8.14
• hoonmin/xecore:latest
DockerfileFROM php:5.6-apache RUN apt-get update && apt-get install -y libpng12-dev libjpeg-dev \ && rm -rf /var/lib/apt/lists/*
# 필요한 PHP extension을 설치 합니다. RUN docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr \ && docker-php-ext-install gd RUN docker-php-ext-install mysqli
# XE Core를 다운로드 합니다. RUN curl -o /var/www/xe.tar.gz \ -OL https://github.com/xpressengine/xe-core/releases/download/1.8.14/xe.1.8.14.tar.gz
# 호스트의 저장소와 연결할 수 있는 볼륨을 정의합니다. VOLUME /var/www/html WORKDIR /var/www/html
# 실행 커맨드 CMD ["apache2-foreground"]
Docker Image
• docker build -t hoonmin/xecore:1.8.14 .
• -t : 빌드 할 이미지 이름
• hoonmin : 이미지의 네임스페이스 (그룹)
• xecore : 이미지 이름
• 1.8.14 : 이미지의 태그
• . : Dockerfile이 위치한 디렉토리
Docker Container: xecore
• docker run -it --rm hoonmin/xecore:1.8.14
• -it : foreground로 동작시키는 경우, 쉘에서 상호작용 가능하게.
• --rm : 실행이 끝난 컨테이너를 삭제합니다.
• hoonmin/xecore:1.8.14 : 이미지 이름
• docker ps
• 실행 중인 도커 컨테이너의 리스트를 확인합니다.
Docker Container: mariadb
• docker run -d -e MYSQL_ROOT_PASSWORD=root --name db --p 3306:3306 mariadb
• -d : background 프로세스로 동작시킵니다.
• -e : 컨테이너 안에서 사용될 환경 변수를 설정합니다.
• --name : 컨테이너의 이름을 지정합니다.
• -p 3306:3306 : 컨테이너가 노출한 포트를 호스트의 포트와 매핑합니다. <host_port>:<container_port>
Docker Hub
• https://hub.docker.com/
• 회원 가입이 필요합니다.
• docker login
• docker push hoonmin/xecore:1.8.14
DB를 밖으로 노출하기 싫어요
XE Core
MariaDB
:80
Link
• 같은 호스트에 있는 컨테이너를 연결하여 호스트에 포트를 노출시키지 않아도 직접 통신할 수 있게 해줍니다.
• docker run -d --name db -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=xe -e MYSQL_USER=xe -e MYSQL_PASSWORD=xe mariadb
• docker run -d -p 80:80 --link db:db hoonmin/xecore:1.8.14
• --link <name>:<alias>
두 컨테이너를 함께 실행할 수 없나요?
XE Core
MariaDB
:80docker-compose XE Core :80
docker-compose
• 여러 개의 도커 컨테이너를 묶어 함께 실행할 수 있습니다.
• docker-compose.yml 파일을 정의해야 합니다.
• docker-compose up -d
• up : 정의된 컨테이너를 실행.
• -d : 백그라운드로 실행.
docker-compose.yml xecore: image: hoonmin/xecore:1.8.14 ports: - 80:80 db: image: mariadb environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: xe MYSQL_USER: xe MYSQL_PASSWORD: xe ports: - 3306:3306
도커 호스트가 여러 개
XE Core :80XE Core :80
XE Core
MariaDB
:80XE Core :80
docker-swarm
• 여러 개의 도커 호스트를 마치 하나인 것 처럼 묶어주는 서비스.
• master는 node를 관리하며 도커 API와 동일한 API를 제공.
Master
Node
docker-swarm 설치
• docker run swarm create : 토큰값 확인
• docker-machine create -d virtualbox --swarm --swarm-master --swarm-discovery token://d9a8bec868295f81eb28b331c7d8ac8b swarm-master
• docker-machine create -d virtualbox --swarm --swarm-discovery token://d9a8bec868295f81eb28b331c7d8ac8b swarm-node-01
swarm을 이용하여 배포
• eval $(docker-machine env --swarm swarm-master)
• swarm-master 도커 VM 환경에서 swarm API를 사용.
• docker-compose up -d
• 도커 컨테이너가 swarm-master, swarm-node-01 두 대의 서버에 적절히 배분되어 실행됩니다.
• docker-compose scale xecore=2
• xecore 컨테이너의 개수를 2개로 늘립니다.
DB 연결이 안되는데요…?
XE Core :80XE Core :80
XE Core
MariaDB
:80XE Core :80
docker overlay networking
XE Core :80XE Core :80
XE Core
MariaDB
:80XE Core :80
overlay my_net
docker networking
• libnetwork
• 도커의 네트워크 관련 코드가 들어 있는 라이브러리.
• 도커 1.7 부터 실험적으로 포함되었다가 1.9 버전에서 정식 출시.
• docker network ls
• docker network create -d overlay my_net
built-in overlay network
• overlay network
• 같은 L2 (MAC) 네트워크에 연결되어 있지 않은 서버들이 서로 L2 통신을 할 수 있도록, 터널링 등의 기술을 활용.
networking을 위한 도커 VM
• docker-machine create -d virtualbox consul
• docker $(docker-machine config consul) run -d -p 8500:8500 -h consul progrium/consul -server -bootstrap
• docker-machine create -d virtual box
• --swarm —swarm-master
• --swarm-discovery="consul://$(docker-machine ip consul):8500”
• --engine-opt="cluster-store=consul://$(docker-machine ip consul):8500
• --engine-opt=“cluster-advertise=eth1:0” swarm-master
다시 docker-compose
• 도커 1.9 부터 docker-compose와 networking이 연동됩니다.
• docker-compose --x-networking --x-network-driver=overlay up -d
• --x-networking : networking 실험 기능을 활성화 합니다.
• - -x-network-driver : networking 드라이버를 선택합니다.
• null, host, bridge, overlay, calico, …
Docker Networking
컨테이너 하나
docker0 (10.1.15.1/24)
veth2c8f4f4 (10.1.15.2/24)
NGINX
veth13f8c56
eth0 (192.168.0.100)
컨테이너 둘
docker0 10.1.15.1/24
eth0 (veth2c8f4f4) 10.1.15.2/24
NGINX
veth13f8c56
eth0 192.168.0.100
eth0 (veth80d8ec5) 10.1.15.3/24
JENKINS
vetha451781
NGINX 포트를 노출
docker0 10.1.15.1/24
eth0 (veth2c8f4f4) 10.1.15.2/24
NGINX:80
eth0 192.168.0.100
eth0 (veth80d8ec5) (10.1.15.3/24)
JENKINS:8080
DNAT :80 —> 10.1.15.2:80 (iptables)
-p 80:80
NGINX와 JENKINS 연결
docker0 10.1.15.1/24
eth0 (veth2c8f4f4) 10.1.15.2/24
NGINX:80
eth0 192.168.0.100
eth0 (veth80d8ec5) (10.1.15.3/24)
JENKINS:8080
DNAT :80 —> 10.1.15.2:80 (iptables)
link
JENKINS_PORT_8080_TCP
호스트가 다르다면?
docker0 10.1.15.1/24
eth0 (veth2c8f4f4) 10.1.15.2/24
NGINX:80
eth0 192.168.0.100
docker0 10.1.20.1/24
eth0 (veth80d8ec5) 10.1.20.2/24
JENKINS:8080
eth0 192.168.0.200
DNAT 80 DNAT 8080
포트가 여러 개 필요하다면?
docker0 10.1.15.1/24
eth0 (veth2c8f4f4) 10.1.15.2/24
NGINX:80
eth0 192.168.0.100
DNAT 80
docker0 10.1.20.1/24
eth0 10.1.20.2/24
JENKINS:8080
eth0 192.168.0.200
eth0 (10.1.20.3/24)
JENKINS:8080
?
Overlay Network
docker0 10.1.15.1/24
eth0 (veth2c8f4f4) 10.1.15.2/24
NGINX:80
eth0 192.168.0.100
docker0 10.1.20.1/24
eth0 10.1.20.2/24
JENKINS:8080
eth0 192.168.0.200
eth0 (10.1.20.3/24)
JENKINS:8080
CoreOS Flannel
docker0 10.1.15.1/24
eth0 (veth2c8f4f4) 10.1.15.2/24
NGINX:80
eth0 192.168.0.100
docker0 10.1.20.1/24
eth0 10.1.20.2/24
JENKINS:8080
eth0 192.168.0.200
eth0 (10.1.20.3/24)
JENKINS:8080
flannel.1 10.1.15.0/16
flannel.1 10.1.20.0/16
overlay
vxlan
TIPS
Timezone
• 도커 컨테이너가 실행될 때 timezone이 디폴트로 맞춰집니다.
• 그런데 이 timezone을 설정할 좋은 방법이 아직은 없습니다.
• https://github.com/docker/docker/issues/12084
• -v /etc/localtime:/etc/localtime로 볼륨 설정.
• ENTRYPOINT에 별도의 스크립트를 둬서 런타임에 설정.
Private Registry
• docker run -d -p 5000:5000 registry:2.2
• 예전 v1 버전은 가능하면 사용하지 마세요.
• 꼭 필요하다면 검색기능 OFF
• LDAP 등의 인증을 붙이려면 별도의 인증 서버를 사용해야 합니다.
• https://github.com/cesanta/docker_auth
• UI가 필요한 경우:
• https://github.com/SUSE/Portus
스토리지 드라이버
• DeviceMapper
• 스토리지 pool 크기에 주의. (100GB default)
• AUFS, Overlay (추천)
• 비슷한 성향의 파일시스템. Overlay는 3.18 커널부터 지원.
• 파일 개수가 많아지면 느려지거나 쓰기가 불가능해질 수 있다.
• overlay는 inode 개수를 모니터링 해주어야 한다. (df -ih)
• BTRFS
docker-proxy
• 포트를 publish 하면 다음과 같이 두 개의 장치가 마련됩니다.
• iptables DNAT rule, docker-proxy 프로세스
• 왜 뜨는가?
• 도커 호스트에서 localhost:<published_port>로 접근하기 위함.
• https://github.com/docker/docker/issues/8356
• 없애는 방법 (2.6.x 커널 제외)
• docker daemon --userland-proxy=false ..