天天看點

阿裡P8架構師談:Docker簡介、組成架構、使用步驟、以及生态産品

Docker簡介

Docker是DotCloud開源的、可以将任何應用包裝在Linux container中運作的工具。

Docker基于Go語言開發,代碼托管在Github上,目前超過10000次commit。

基于Docker的沙箱環境可以實作輕型隔離,多個容器間不會互相影響;Docker可以自動化打包和部署任何應用,友善地建立一個輕量級私有PaaS雲,也可以用于搭建開發測試環境以及部署可擴充的web應用等。

Docker vs VM

從下圖可以看出,VM是一個運作在主控端之上的完整的作業系統,VM運作自身作業系統會占用較多的CPU、記憶體、硬碟資源。

Docker不同于VM,隻包含應用程式以及依賴庫,基于libcontainer運作在主控端上,并處于一個隔離的環境中,這使得Docker更加輕量高效,啟動容器隻需幾秒鐘之内完成。

由于Docker輕量、資源占用少,使得Docker可以輕易的應用到建構标準化的應用中。但Docker目前還不夠完善,比如隔離效果不如VM,共享主控端作業系統的一些基礎庫等;網絡配置功能相對簡單,主要以橋接方式為主;檢視日志也不夠友善靈活。

阿裡P8架構師談:Docker簡介、組成架構、使用步驟、以及生态産品

另外,IBM發表了一篇關于虛拟機和Linux container性能對比的論文,論文中實際測試了虛拟機和Linux container在CPU、記憶體、存儲IO以及網絡的負載情況,結果顯示Docker容器本身幾乎沒有什麼開銷,但是使用AUFS會一定的性能損耗,不如使用Docker Volume,Docker的NAT在較高網絡資料傳輸中會引入較大的工作負載,帶來額外的開銷。不過container的性能與native相差不多,各方面的性能都一般等于或者優于虛拟機。Container和虛拟機在IO密集的應用中都需要調整優化以更好的支援IO操作,兩者在IO密集型的應用中都應該謹慎使用。

Docker Component

阿裡P8架構師談:Docker簡介、組成架構、使用步驟、以及生态産品

Docker是CS架構,主要由下面三部分組成:

Docker daemon: 運作在主控端上,Docker守護程序,使用者通過Docker client(Docker指令)與Docker daemon互動

Docker client: Docker 指令行工具,是使用者使用Docker的主要方式,Docker client與Docker daemon通信并将結果傳回給使用者,Docker client也可以通過socket或者RESTful api通路遠端的Docker daemon

Docker hub/registry: 共享和管理Docker鏡像,使用者可以上傳或者下載下傳上面的鏡像,官方位址為https://registry.hub.docker.com/,也可以搭建自己私有的Docker registry。

了解了Docker的組成,再來了解一下Docker的兩個主要概念:

Docker image:鏡像是隻讀的,鏡像中包含有需要運作的檔案。鏡像用來建立container,一個鏡像可以運作多個container;鏡像可以通過Dockerfile建立,也可以從Docker hub/registry上下載下傳。

Docker container:容器是Docker的運作元件,啟動一個鏡像就是一個容器,容器是一個隔離環境,多個容器之間不會互相影響,保證容器中的程式運作在一個相對安全的環境中。

Docker網絡

Docker的網絡功能相對簡單,沒有過多複雜的配置,Docker預設使用birdge橋接方式與容器通信,啟動Docker後,主控端上會産生docker0這樣一個虛拟網絡接口, docker0不是一個普通的網絡接口, 它是一個虛拟的以太網橋,可以為綁定到docker0上面的網絡接口自動轉發資料包,這樣可以使容器與主控端之間互相通信。

每次Docker建立一個容器,會産生一對虛拟接口,在主控端上執行ifconfig,會發現多了一個類似veth****這樣的網絡接口,它會綁定到docker0上,由于所有容器都綁定到docker0上,容器之間也就可以通信。

在主控端上執行ifconfig,會看到docker0這個網絡接口, 啟動一個container,再次執行ifconfig, 會有一個類似veth****的interface,每個container的預設路由是主控端上docker0的ip,在container中執行netstat -r可以看到如下圖所示内容:

阿裡P8架構師談:Docker簡介、組成架構、使用步驟、以及生态産品

容器中的預設網關跟docker0的位址是一樣的:

阿裡P8架構師談:Docker簡介、組成架構、使用步驟、以及生态産品

當容器退出之後,veth*虛拟接口也會被銷毀。

除bridge方式,Docker還支援host、container、none三種網絡通信方式,使用其它通信方式,隻要在Docker啟動時,指定--net參數即可,比如:

docker run -i -t --net=host ubuntu /bin/bash

host方式可以讓容器無需建立自己的網絡協定棧,而直接通路主控端的網絡接口,在容器中執行ip addr會發現與主控端的網絡配置是一樣的,host方式讓容器直接使用主控端的網絡接口,傳輸資料的效率會更加高效,避免bridge方式帶來的額外開銷,但是這種方式也可以讓容器通路主控端的D-bus等網絡服務,可能會帶來意想不到的安全問題,應謹慎使用host方式;container方式可以讓容器共享一個已經存在容易的網絡配置; none方式不會對容器的網絡做任務配置,需要使用者自己去定制。

Docker 使用

首先要在主控端上安裝Docker,Docker安裝參考官方安裝文檔。

Docker指令也比較類似Git,支援push以及pull操作上傳以及下載下傳Docker鏡像。

1.檢視目前Docker的版本

docker version

2.檢視目前系統Docker資訊

docker info

3.檢視主控端上的鏡像,Docker鏡像儲存在/var/lib/docker目錄下:

docker images

4.從Docker hub上下載下傳某個鏡像:

docker pull ubuntu:latest

執行docker pull ubuntu會将Ubuntu這個倉庫下面的所有鏡像下載下傳到本地repository。

5.啟動一個容器使用docker run:

docker run -i -t ubuntu /bin/bash 啟動一個容器

docker run -i -t --rm ubuntu /bin/bash --rm表示容器退出後立即删除該容器

docker run -t -i --name test_container ubuntu /bin/bash --name指定容器的名稱,否則會随機配置設定一個名稱

docker run -t -i --net=host ubuntu /bin/bash --net=host容器以Host方式進行網絡通信

docker run -t -i -v /host:/container ubuntu /bin/bash -v綁定挂在一個Volume,在主控端和Docker容器中共享檔案或目錄

6.檢視目前有哪些容器正在運作,使用docker ps:

7.啟動或停止某個container使用docker start/stop container_id:

8.使用docker commit可以将container的變化作為一個新的鏡像,比如:

xzs@host:~(0)$ docker commit -m="test docker commit" 50a1261f7a8b docker_test

55831c956ebf46a1f9036504abb1b29d7e12166f18f779cccce66f5dc85de38e

xzs@host:~(0)$ docker images | grep docker_test

docker_test latest 55831c956ebf 10 seconds ago 290.7 MB

除了從Docker hub上下載下傳鏡像,也可以寫Dockerfile建立一個鏡像,以建立一個Django程式為例,Dockerfile如下所示:

xzs@host:/tmp/docker(0)$ cat Dockerfile

FROM ubuntu:12.04

MAINTAINER Your Name

RUN apt-get update

RUN apt-get install -y python-software-properties python-pip

ADD myproject /opt/code

RUN pip install -r /opt/code/requirement.txt

9.寫完Dockerfile,在Dockerfile所在目錄執行docker build建立鏡像:

docker build -t docker_test .

docker run -i -t docker_test /bin/bash -c "cd /opt/code;python manage.py runserver 0.0.0.0:8080"

10.将制作的鏡像上傳到private registry:

docker tag test docker.example.com/test

docker push docker.example.com/test

11.删除鏡像:docker rm

經過長時間使用,主機上存儲了很多已無用的鏡像,想将它們删除則用docker rm或者docker rmi,比如:

docker rm container_id

docker rmi image_id

Docker生态

随着Docker迅速火遍全球, 以Docker為基礎的生态系統也迅速的發展起來,從以部署和運作container為基礎的CoreOS到各種各樣的管理工具和PaaS軟體,Docker以及生态産品都在迅猛發展,以下介紹幾個代表性的軟體。

首先介紹CoreOS,它的出現極大地推動了Docker技術的推廣和發展,CoreOS是專門為大規模服務部署而設計的一種新的Linux發行版,通過運作輕量級的容器友善擴充和維護大規模的服務。它具有以下特點:

CoreOS使用container管理服務(容器即服務),即以容器的角度去管理服務,服務的代碼和依賴都打包到容器裡,打包後的容器直接在CoreOS上運作管理。通過容器使用者不再需要關注虛拟機環境等,極大地降低了服務和系統環境的耦合性。另外部署在CoreOS的多個容器都運作在各自獨立的環境中,不會互相影響。

CoreOS專門為cluster等大規模部署而設計,提供了Etcd進行服務發現,以及Fleet管理容器保證服務可用。

CoreOS更加精簡,比如RAM使用比普通Linux低40%。

CoreOS采用雙分區模式(Dual-Partition),主分區為主動模式,負責系統運作,被動模式分區負責系統更新,更新時将整個CoreOS系統下載下傳下來。

CoreOS是為叢集服務而設計的,提供了Etcd、Fleet等管理工具管理容器和服務。Etcd是一種類似Zookeeper的分布式key/value存儲服務,用于服務發現和配置管理。Fleet是容器管理工具,保證服務的可用性,當某個機器的服務不可用時,Fleet會将服務遷移到其它機器上運作。

Docker生态中還有一個非常重要的容器管理工具--Kubernetes,它是Google開源的用于在叢集環境中管理、維護、自動擴充容器,通過Kubernetes可以很友善地在多個機器上管理和部署容器服務。現在已經得到IBM、Microsoft、RedHat等多個大公司的支援。

在Kubernetes中pod是一個基本單元,一個pod可以是提供相同功能的多個container,這些容器會被部署在同一個minion上。Replication controller定義了多個pod或者容器需要運作,如果目前叢集中運作的pod或容器達不到配置的數量,replication controller會排程容器在多個minion上運作,保證叢集中的pod數量。service則定義真實對外提供的服務,一個service會對應後端運作的多個container。

Kubernetes的架構由一個master和多個minion組成,master通過api提供服務,接受kubectl的請求來排程管理整個叢集。minion是運作Kubelet的機器,它接受master的指令建立pod或者容器。

最後介紹一下基于Docker實作的PaaS軟體,Docker PaaS軟體中以Deis和Flynn最為知名。Deis是基于Docker和CoreOS實作的輕量級的PaaS,受到Heroku的啟發,遵循“十二要素”建構應用方法。

Deis是以應用程式為中心設計的,分為build、release、run三個階段,使用者執行"git push"後,Deis使用Docker 容器編譯并将編譯結果儲存在Docker鏡像;釋出階段,一次build和配置檔案産生一個數字辨別的釋出鏡像,将釋出鏡像儲存到Docker registry中以供後續釋出到線上運作;運作階段應用鏡像會被排程到主機上運作,并更新相應的路由。

Flynn與Deis類似,也是以應用為中心,Flynn元件分為兩層,layer0是底層資源的抽象,主要負責資源排程以及服務發現等,為上層應用容器的運作提供底層資源排程支援;layer1處理具體應用,通過Docker容器編譯、部署和維護上層應用程式。

總結

Docker從2013年釋出第一個版本以來,已經火遍全球,技術疊代也比較頻繁,其周邊産品和技術也越來越豐富,由于Docker更新頻繁,會出現新版本有時不相容舊版本的情況,Docker周邊産品基本都處于開發階段還不具備生産環境下使用。

Docker的輕量級容器不僅實作了資源隔離,而且幾乎可以運作在任何地方,使得部署和擴充變得非常容易,随着Docker的日趨完善,希望Docker被越來越多的公司應用到生産環境中。

1、具有1-5工作經驗的,面對目前流行的技術不知從何下手,

需要突破技術瓶頸的。2、在公司待久了,過得很安逸,

但跳槽時面試碰壁。需要在短時間内進修、跳槽拿高薪的。

3、如果沒有工作經驗,但基礎非常紮實,對java工作機制,

常用設計思想,常用java開發架構掌握熟練的。

4、覺得自己很牛B,一般需求都能搞定。

但是所學的知識點沒有系統化,很難在技術領域繼續突破的。

5. 群号:809340374