Docker快速入門——Docker簡介
一、Docker簡介
1、Docker簡介
Docker是Docker Inc公司開源的一項基於Ubuntu LXC技術構建的應用容器引擎,源代碼托管在GitHub上,完全基於go語言開發並遵守Apache2.0協議開源。Docker可以讓開發者打包應用以及依賴包到一個輕量級、可移植的容器中,然後發布到任何流行的Linux版本機器上,也可以實現虛擬化。Docker容器完全使用沙箱機制,容器相互之間不會有任何接口,並且容器性能開銷極低。
Docker最初是在Ubuntu 12.04上開發實現的,RedHat從RHEL6.5開始對Docker 進行支持。
Docker最初基於LXC實現,從0.7版本後開始去除LXC,轉而使用自行開發的libcontainer。從1.11開始,進一步演進為使用runC和containerd。
Github Docker源碼:https://github.com/docker/docker
2、Docker引擎
Docker引擎是一個客戶端服務器應用程序,包含如下三個組件:
A、服務器,是一種稱為守護進程並且長時間運行的程序。
B、用於指定程序可以用來與守護進程通信的REST API接口。
C、命令行界面(CLI)工具的客戶端。
Docker引擎組件的流程如下:
3、Docker的優點
Docker優點如下:
A、更高效地利用系統資源
由於容器不需要進行硬件虛擬以及運行完整操作系統等額外開銷,Docker對系統資源的利用率更高。無論是應用執行速度、內存損耗或者文件存儲速度,都要比傳統虛擬機技術更高效。因此,相比虛擬機技術,一個相同配置的主機,往往可以運行更多數量的應用。
傳統的虛擬機技術啟動應用服務往往需要數分鐘,而Docker容器應用直接運行於宿主內核,無需啟動完整的操作系統,因此可以做到秒級、甚至毫秒級的啟動時間,大大節約了開發、測試、部署的時間。
C、一致的運行環境
開發過程中一個常見的問題是環境一致性問題。由於開發環境、測試環境、生產環境不一致,導致有些bug並未在開發過程中被發現。而Docker的鏡像提供了除內核外完整的運行時環境,確保了應用運行環境一致性。
D、持續交付和部署
使用Docker可以通過定制應用鏡像來實現持續集成、持續交付、部署。開發人員可以通過Dockerfile來進行鏡像構建,並結合持續集成(Continuous Integration) 系統進行集成測試;而運維人員則可以直接在生產環境中快速部署鏡像,甚至結合持續部署(Continuous Delivery/Deployment)系統進行自動部署,而且使用Dockerfile使鏡像構建透明化,不僅僅開發團隊可以理解應用運行環境,也方便運維團隊理解應用運行所需條件,幫助更好的生產環境中部署鏡像。
由於Docker 確保了執行環境的一致性,使得應用的遷移更加容易。Docker可以在很多平臺上運行,無論是物理機、虛擬機、公有雲、私有雲,甚至是筆記本,其運行結果是一致的。因此用戶可以很輕易的將在一個平臺上運行的應用,遷移到另一個平臺上,而不用擔心運行環境的變化導致應用無法正常運行的情況。
F、更輕松的維護和擴展
Docker使用的分層存儲以及鏡像的技術,使得應用重復部分的復用更為容易,也使得應用的維護更新更加簡單,基於基礎鏡像進一步擴展鏡像也變得非常簡單。此外,Docker團隊同各個開源項目團隊一起維護了一大批高質量的官方鏡像,既可以直接在生產環境使用,又可以作為基礎進一步定制,大大的降低了應用服務的鏡像制作成本。
4、Docker與虛擬機
虛擬機是一個運行在宿主機上的完整的操作系統,虛擬機運行自身操作系統會占用較多的CPU、內存、硬盤資源。Docker不同於虛擬機,只包含應用程序以及依賴庫,基於libcontainer運行在宿主機上,並處於一個隔離的環境中,使得Docker更加輕量高效,啟動容器只需幾秒鐘內完成。由於Docker輕量、資源占用少,使得Docker可以輕易的應用到構建標準化的應用中。但Docker目前還不夠完善,缺點如下:
A、隔離效果不如VM,共享宿主機操作系統的一些基礎庫等。
B、網絡配置功能相對簡單,主要以橋接方式為主。
C、查看日誌也不夠方便靈活。
二、Docker架構
1、Docker架構簡介
Docker架構遵循C/S架構,分為客戶端、Docker主機、Docker鏡像倉庫三部分。
客戶端(Client):Docker提供命令行界面(CLI)工具,客戶端與Docker守護進程交互。當使用docker命令時,客戶端將相應Docker命令發送到Docker 主機的Docker守護進程進行運行,客戶端可以構建,運行和停止應用程序。客戶端還可以遠程與Docker_Host進行交互。
Docker主機:包含容器、鏡像和Docker守護程序,提供完整的環境來執行和運行應用程序。Docker守護進程是一個用於監聽Docker API請求的進程。 它還管理Docker對象,如:映像,容器,網絡等。守護進程還可以與其他守護進程通信以管理Docker服務。
鏡像倉庫(Registry):全局鏡像倉庫,可以訪問並使用鏡像在Docker環境中運行應用程序。Docker鏡像倉庫用於存儲Docker鏡像。Docker提供Docker Hub和Docker Cloud,是任何人都可以使用的公共鏡像倉庫。Docker配置為默認在Docker Hub上查找映像。當使用docker pull或docker run命令時,從配置的鏡像倉庫中提取所需的鏡像;當使用docker push命令時,鏡像被推送到配置的鏡像倉庫中。
2、Docker鏡像
Docker鏡像是一個特殊的文件系統,除了提供容器運行時所需的程序、庫、資源、配置等文件外,還包含了一些為運行時準備的一些配置參數(如匿名卷、環境變量、用戶等)。鏡像不包含任何動態數據,其內容在構建後也不會被改變。
Docker充分利用Union FS 的技術,將其設計為分層存儲的架構。Docker鏡像是由一組文件系統組成,或是由多層文件系統聯合組成。Docker鏡像構建時,會一層層構建,前一層是後一層的基礎。每一層構建完就不會再發生改變,後一層上的任何改變只發生在自己本層。比如,刪除前一層文件的操作,實際不是真的刪除前一層的文件,而是僅在當前層標記為該文件已刪除。在最終容器運行的時候,雖然不會看到文件,但是實際上文件會一直跟隨鏡像。因此,在構建鏡像時需要額外小心,每一層盡量只包含該層需要添加的東西,任何額外的東西應該在該層構建結束前清理掉。
分層存儲的特征使得鏡像的復用、定制變的更為容易,可以使用構建好的鏡像作為基礎層,然後進一步添加新的層以定制自己所需的內容,構建新的鏡像。
3、Docker容器
Docker鏡像是靜態的定義,Docker容器是Docker鏡像運行時的實體。Docker容器可以被創建、啟動、停止、刪除、暫停等。
Docker容器的實質是進程,但與直接在宿主執行的進程不同,Docker容器進程運行於屬於自己的獨立的命名空間。因此Docker容器可以擁有自己的root文件系統、自己的網絡配置、自己的進程空間,甚至自己的用戶ID空間。Docker容器內的進程是運行在一個隔離的環境裏,使得容器封裝的應用比直接在宿主運行更加安全。Docker容器也是使用分層存儲,每一個Docker容器運行時,以鏡像為基礎層,在其上創建一個當前容器的存儲層。容器存儲層的生存周期和容器一樣,容器消亡時容器存儲層也隨之消亡。因此,任何保存於容器存儲層的信息都會隨容器刪除而丟失。
按照Docker最佳實踐的要求,Docker容器不應該向其存儲層內寫入任何數據,容器存儲層要保持無狀態化。所有的文件寫入操作都應該使用數據卷(Volume)、或者綁定宿主目錄,在數據卷或宿主目錄位置的讀寫會跳過容器存儲層,直接對宿主(或網絡存儲)發生讀寫,其性能和穩定性更高。數據卷的生存周期獨立於容器,容器消亡,數據卷不會消亡。因此,使用數據卷後,容器刪除或者重新運行後,數據卻不會丟失。
4、Docker鏡像倉庫(Registry)
Docker鏡像倉庫(Registry)默認的Registry是Docker公司運營提供的公共鏡像倉庫即Docker Hub。但本地訪問Docker Hub速度通常很慢,因此需要一個本地的私有倉庫只供局域網內使用。
三、Docker安裝指南
1、Mac平臺安裝
Homebrew的Cask已經支持Docker for Mac:
加速器配置使用網易的鏡像地址:http://hub-mirror.c.163.com。
在任務欄點擊Docker for mac應用圖標->Perferences... ->Daemon ->Registry mirrors。
在列表中填寫加速器地址。修改完成後,點擊 Apply & Restart 按鈕,Docker就會重啟並應用配置的鏡像地址。
通過docker info來查看是否配置成功。
2、Linux平臺安裝
Docker運行在RHEL7上,要求系統為64位、系統內核版本為3.10以上。
Docker運行在?RHEL6.5?或更高的版本要求系統為64位、系統內核版本為2.6.32-431或者更高版本。
本文使用RHEL7.3安裝Docker。
安裝Docker:sudo yum install docker
啟動Docker:sudo systemctl start docker
錯誤信息:Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details.
查看錯誤信息:systemctl status docker.service
錯誤原因:SELinux不支持Docker服務
解決方法:編輯sudo vim /etc/sysconfig/docker
OPTIONS=‘--selinux-enabled=false --log-driver=journald --signature-verification=false‘
if [ -z "${DOCKER_CERT_PATH}" ]; then
DOCKER_CERT_PATH=/etc/docker
fi
運行示例:sudo docker run hello-world
3、Windows平臺安裝
Win7、Win8需要利用docker toolbox來安裝,國內可以使用阿裏雲的鏡像來下載,
Docker ToolBox下載地址:
http://mirrors.aliyun.com/docker-toolbox/windows/docker-toolbox/
Docker ToolBox是一個工具集,主要包含:
A、Docker CLI客戶端,用來運行docker引擎創建鏡像和容器
B、Docker Machine,用於在Windows的命令行中運行docker引擎命令
C、Docker Compose,用來運行docker-compose命令
D、Kitematic,Docker的GUI版本
E、Docker QuickStart shell,配置好Docker的命令行環境
F、Oracle VM Virtualbox,虛擬機
下載完成後直接點擊安裝,安裝成功後,會出現三個圖標:
點擊Docker QuickStart圖標來啟動Docker Toolbox終端。
如果系統顯示User Account Control窗口來運行VirtualBox,選擇 Yes。
對於Win10專業版系統,Docker有專門的的安裝包,需要開啟Hyper-V。
Win10專業版系統Docker下載地址:
https://store.docker.com/editions/community/docker-ce-desktop-windows
4、Docker鏡像加速器安裝
Docker使用daemon.json文件作為Docker服務的配置文件,Linux操作系統使用/etc/docker/daemon.json,Windows操作系統使用%programdata%\docker\config\daemon.json來配置Docker服務。如果相應目錄下不存在daemon.json文件,需要創建。
{
"registry-mirrors": ["http://hub-mirror.c.163.com"]
}
網易的鏡像地址:http://hub-mirror.c.163.com。
四、Docker核心技術
1、隔離性
為了實現每個用戶實例之間相互隔離,硬件虛擬化方法的解決方案是VM,而LXC的解決方案是container,即kernel namespace。其中pid、net、ipc、mnt、uts、user等namespace將container的進程、網絡、消息、文件系統、UTS(UNIX Time-sharing System)和用戶空間隔離開。
A、pid namespace
不同用戶的進程通過pid namespace隔離開,且不同namespace中可以有相同pid。所有的LXC進程在Docker中的父進程為Docker進程,每個lxc 進程具有不同的namespace。同時由於允許嵌套,因此可以很方便的實現 Docker in Docker。
B、net namespace
通過pid namespace,每個namespace中的pid能夠相互隔離,但網絡端口還共享host的端口。網絡隔離是通過net namespace實現的,每個net namespace有獨立的network devices,IP addresses,IP routing tables,/proc/net目錄。通過net namespace,每個container的網絡就能隔離開來。Docker默認采用veth的方式將container中的虛擬網卡同host上的一個 docker bridge:docker0連接在一起。
C、ipc namespace
container中進程交互采用linux常見的進程間交互方法(interprocess communication - IPC),包括常見的信號量、消息隊列和共享內存。然而與VM不同,container的進程間交互還是host上具有相同pid namespace中的進程間交互,因此需要在IPC資源申請時加入namespace信息——每個IPC 資源有一個唯一的32位 ID。
D、mnt namespace
mnt namespace允許不同namespace的進程看到的文件結構不同,每個namespace中的進程所看到的文件目錄就被隔離開了。每個namespace 中的container在/proc/mounts的信息只包含所在namespace的mount point。
E、uts namespace
UTS(UNIX Time-sharing System)namespace允許每個container擁有獨立的hostname和domain name,使其在網絡上可以被視作一個獨立的節點而非Host上的一個進程。
F、user namespace
每個container可以有不同的user和group id,可以在container內部用container內部的用戶執行程序而非Host上的用戶。
2、可配額/可度量
cgroups實現了對資源的配額和度量。cgroups使用非常簡單,提供類似文件的接口,在/cgroup目錄下新建一個文件夾即可新建一個group,在此文件夾中新建task文件,並將pid 寫入該文件,即可實現對該進程的資源控制。groups可以限制blkio、cpu、cpuacct、cpuset、devices、freezer、memory、net_cls、ns九大子系統的資源,每個子系統的詳細說明如下:
有序列表blkio子系統設置限制每個塊設備的輸入輸出控制。例如:磁盤,光盤以及usb等等。
cpu子系統使用調度程序為cgroup任務提供cpu的訪問。
cpuacct:產生cgroup任務的cpu資源報告。
cpuset:如果是多核心的cpu,cpuset子系統會為cgroup任務分配單獨的 cpu和內存。
devices允許或拒絕cgroup任務對設備的訪問。
freezer暫停和恢復cgroup任務。
memory設置每個cgroup的內存限制以及產生內存資源報告。
net_cls標記每個網絡包以供cgroup方便使用。
ns名稱空間子系統。
3、便攜性
AUFS(Another Union FS)是一種Union FS,支持將不同目錄掛載到同一個虛擬文件系統下的文件系統。AUFS支持為每一個成員目錄設定readonly、readwrite和whiteout-able權限。同時AUFS裏有分層的概念,對readonly 權限的branch可以邏輯上進行修改(增量地,不影響readonly部分的)。
通常Union FS有兩個用途,一是可以實現不借助LVM、RAID將多個disk 掛到同一個目錄下;一個是將一個readonly的branch和一個writeable的 branch聯合在一起(Live CD可以允許在OS image不變的基礎上允許用戶在其上進行一些寫操作)。
典型的啟動Linux運行需要兩個FS:bootfs + rootfs
bootfs(boot file system)主要包含bootloader 和 kernel,bootloader 主要是引導加載kernel,當boot成功後kernel被加載到內存中後bootfs就被 umount。 rootfs(root file system)包含的就是典型Linux系統中的/dev,/proc,/bin,/etc 等標準目錄和文件。
不同的linux發行版,bootfs基本是一致的,但rootfs會有差別,因此不同的發行版可以共用bootfs。
典型的Linux在啟動後,首先將rootfs設置為readonly,進行一系列檢查,然後將其切換為readwrite供用戶使用。在Docker中,初始化時也是將rootfs 以readonly方式加載並檢查,然而接下來利用union mount的方式將一個 readwrite文件系統掛載在readonly的rootfs之上,並且允許再次將下層的 FS(file system)設定為readonly,並且向上疊加,readonly和writeable組成的結構構成一個container的運行時態,每一個FS被稱作一個FS層。
基於AUFS的特性,每一個對readonly層文件/目錄的修改都只會存在於上層的writeable層中。由於不存在競爭,多個container可以共享readonly的FS層。所以Docker將readonly的FS層稱作image-——對於container 而言整個rootfs都是read-write的,但事實上所有的修改都寫入最上層的 writeable層中,image不保存用戶狀態,只用於模板、新建和復制使用。
上層的image依賴下層的image,因此Docker中把下層的image稱作父image,沒有父image的image稱作base image。因此想要從一個image 啟動一個container,Docker會先加載image本身和依賴的父images以及 base image,用戶的進程運行在writeable的layer中。所有parent image 中的數據信息以及ID、網絡和lxc管理的資源限制等具體container的配置,構成一個Docker概念上的container。
4、安全性
Docker的安全特性包括三個方面:
A、由kernel namespaces和cgroups實現的Linux系統固有的安全標準;
B、Docker Deamon的安全接口;
C、Linux本身的安全加固解決方案,例如AppArmor,SELinux;
Docker快速入門——Docker簡介