張旭 @zx1986
Docker 是什麽?
從結果來看, 您可以使用 Docker 將 Application
封裝到一個相當類似於虛擬主機 (VM) 的隔離環
境 (術語叫 Container) 中執行。
Docker 是什麽?
想像一下,只要執行一行指令,您開發的網站就可
以掛載到一個已經配置好的「主機」中,立即提供服
務,啟動過程可以迅速到就像執行一次 ls 指令那
樣。
Docker 是什麽?
想像一下,您配置好的環境可以憑藉一個設定檔
(Dockerfile),在任何支援 Docker Container 的平
台運行起來,就像是將一台一模一樣的「主機」搬過
去插電 (或是虛擬主機複製) 運作起來一樣。
Docker 是什麽?
想像一下,寫一個設定檔 (docker-compose.yml),
使用一行指令,您就可以喚起多台「主機」,每臺負
責不同的服務,例如 HAProxy、Apache、MySQL、
Memcached,瞬間就可以全部啟動,且彼此間網路
是互通的,服務是可以對外開放的。
Docker 的特色 - 1
● 作業系統層級的虛擬化產品
● 實作涉及 Linux Kernel 功能
● 100% 原生硬體的效能
● 虛擬主機等級的隔離及資源分配
● 應用程式等級的輕量及方便
Docker 的特色 - 2
● 在呼叫 Linux 的核心提供的虛擬化模組時,0.9 版前還需依賴
LXC、libvirt 及 systemd-nspawn 的功能,0.9 版之後,就預設
使用自己開發的 libcontainter 來呼叫。
● 由唯讀的多層次映像檔 (Image) 做為模板 (產生 Container)
● 產生 Container 後,保持最上層可寫入 (用來提供服務)
底層原理
Container 技術發展史
● 1979 - chroot
● 2008 - LXC
● 2013 - LMCTFY (Let Me Contain That For You - Google)
● 2013 - Docker
● 2014 - Rocket
● 2016 - Windows Containers
LXC (LinuX Containers)
● Kernel Namespaces - PID, User, Mount, Network 隔離
● Cgroups - CPU, Memory, Disk I/O 隔離
● Chroot - File System 隔離
Docker 0.9 以後已經改用自行開發的 libcontainter 來實作。
Docker is more than LXC
● AUFS - Another Union File System,相當於把 Host
(Server) 的目錄當成 Guest (Container) 的 Disk。
● Base Image - 透過 base image,可以在 Docker上執行各種
的 Distribution Linux 而不受限於 Host 的 OS 種類,Image
裡面其實就是一堆必要檔案的集合。
技術名詞
Docker 術語
● Image
● Container
● Registry
Docker 術語 - Image
A Docker image is a read-only template.
● 唯讀的映像檔
● 相當於 VM 的樣板機
● 不可變更的 (immutable)
Docker 術語 - Container
A Docker container holds everything that is needed for an
application to run. Each container is created from a Docker
image.
● 以 Image 為基板,放到記憶體中執行的
● Docker 執行起來的最小單位
● Container 裡面必須有一個前景 (foreground) 執行的程式
Docker 術語 - Registry
Docker registries hold images.
● 存放 Image 的倉庫
● 類似 Github 之於 Git Repository 的角色
運作架構
簡單的 Docker Client / Server 架構
詳細一點的 Docker Client / Server 架構
原生與寄生的 Docker Server 差異
Docker Client 只要設定好正確的環境變數,
即可對遠端 Docker Server 進行操作:
DOCKER_TLS_VERIFY="1"
DOCKER_HOST="tcp://192.168.99.100:2376"
DOCKER_CERT_PATH="/machines/certs/"
DOCKER_MACHINE_NAME="dev"
Docker Client
From Anywhere
妥善授權給 Docker Client
使用方法
安裝 Docker Client / Server
Docker 安裝 - Mac
$ brew install docker-machine
$ brew install docker
https://docs.docker.com/docker-for-mac
原生的,會把 docker-compose 也裝起來,COOL
Docker 安裝 - Ubuntu 14.04
$ sudo apt-get install apt-transport-https ca-certificates
$ sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80
--recv-keys 58118E89F3A912897C070ADBF76221572C52609D
$ sudo vim /etc/apt/sources.list.d/docker.list
deb https://apt.dockerproject.org/repo ubuntu-trusty main
$ sudo apt-get update
$ sudo apt-get purge lxc-docker
$ sudo apt-get install docker-engine
Docker 安裝 - CentOS
$ sudo vim /etc/yum.repos.d/docker.repo
$ sudo yum install docker-engine
[docker-repo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/$releasever/
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg
Dockerfile
Dockerfile - 1
● 想象 Dockerfile 是一道食譜,大家根據食譜就可以烹調
(docker build) 出同樣一道菜 (Docker Image) 來。
● 可以勉強將 Dockerfile 先想像成 Ruby 的 Gemfile、
NodeJS 的 package.json 來理解, 但 Dockerfile 絕不僅僅
是宣告相依套件而已。
● Dockerfile 手冊
:https://docs.docker.com/engine/reference/builder/
Dockerfile - 2
FROM centos:6
MAINTAINER zx1986 <zx1986@gmail.com>
EXPOSE 80 3306
USER root
ENV LANG en_US.UTF-8
ENV TZ=Asia/Taipei
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN rpm -iUvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm
RUN yum -y update && yum -y groupinstall "Development Tools"
RUN yum -y update && yum -y install python-pip && pip install meld3==1.0.0 supervisor
CMD ["/usr/bin/supervisord"]
● 一個簡單的 Dockerfile 範例
docker [client]
Docker 常用指令
● docker images
● docker pull ubuntu
● docker run -it ubuntu bash
● docker ps -a
● docker stop
● docker rm
docker-compose
docker-compose 安裝
$ curl -L
https://github.com/docker/compose/releases/download/1.8.1/docker-co
mpose-`uname -s`-`uname -m` > docker-compose
$ chmod a+x docker-compose
$ mv docker-compose /usr/local/bin/
$ docker-compose --version
docker-compose.yml
● yaml 格式 (YAML Ain't Markup Language)
● 給 docker-compose 指令看的設定檔。
● 根據 docker-compose.yml 的設定,docker-compose 可以一次啓
動多個 docker container,並設定之間的互通關聯、資料共享等。
● docker-compose 背後其實很多個 docker 指令的組合、搭配,類似
git-flow 工具的背後其實是很多 git 指令的組合。
● docker-compose.yml 手冊:
https://docs.docker.com/compose/compose-file/
docker-compose 常用指令
● docker-compose up -d
● docker-compose ps
● docker-compose restart
● docker-compose logs -f
● docker-compose stop
● docker-compose rm
應用思考
Microservice - Martin Fowler
● 微服務架構 (各自專注做好一件事)
● 怎樣算是 Microservice?
○ 兩個 Pizza 可以餵飽的團隊 (人數)
○ 兩週可以開發完成的項目 (時間)
Container 到底該專一還是多工?
● 專注於單一應用 (服務) 才符合 Docker 的精神?
● 把 Docker 當成 VM 那樣使用?
● Container 裡面要跑其他多個背景服務 (daemon) 怎麼辦?
推薦閱讀 http://phusion.github.io/baseimage-docker
Docker 的風險
● 一定要做分散式叢集服務
● 做好翻船的準備(請備妥救生艇 - 替代方案)
參考資料
● https://philipzheng.gitbooks.io/docker_practice/content/
● https://speakerdeck.com/fntsrlike/docker-chu-tan-shi-yan-shi-zhong-de-yun-huo-jing
● https://speakerdeck.com/sskorc/docker-and-php
● https://speakerdeck.com/akalyaev/inside-docker
● https://speakerdeck.com/ndemoor/what-is-docker
● https://speakerdeck.com/slok/ship-it-with-docker
● https://linux.cn/article-6975-1.html
● http://lab.howie.tw/2014/08/docker-docker-lxc-hypervisor.html

Docker