幾張圖幫你理解 docker 基本原理及快速入門

寫的非常好的一篇文章,不知道爲什麼被刪除了。 利用Google快照,做個存檔。

快照地址:地址

作者地址:青牛

什麼是docker
Docker 是一個開源項目,誕生於 2013 年初,最初是 dotCloud 公司內部的一個業餘項目。它基於 Google 公司推出的 Go 語言實現。 項目後來加入了 Linux 基金會,遵從了 Apache 2.0 協議,項目代碼在 GitHub 上進行維護。

Docker 自開源後受到廣泛的關注和討論,以至於 dotCloud 公司後來都改名爲 Docker Inc。Redhat 已經在其 RHEL6.5 中集中支持 Docker;Google 也在其 PaaS 產品中廣泛應用。

Docker 項目的目標是實現輕量級的操作系統虛擬化解決方案。 Docker 的基礎是 Linux 容器(LXC)等技術。在 LXC 的基礎上 Docker 進行了進一步的封裝,讓用戶不需要去關心容器的管理,使得操作更爲簡便。用戶操作 Docker 的容器就像操作一個快速輕量級的虛擬機一樣簡單。

下面的圖片比較了 Docker 和傳統虛擬化方式的不同之處,可見容器是在操作系統層面上實現虛擬化,直接複用本地主機的操作系統,而傳統方式則是在硬件層面實現。

virtualization

docker

爲什麼用docker
作爲一種新興的虛擬化方式,Docker 跟傳統的虛擬化方式相比具有衆多的優勢。

Docker 在如下幾個方面具有較大的優勢:

更快速的交付和部署
Docker在整個開發週期都可以完美的輔助你實現快速交付。Docker允許開發者在裝有應用和服務本地容器做開發。可以直接集成到可持續開發流程中。

例如:開發者可以使用一個標準的鏡像來構建一套開發容器,開發完成之後,運維人員可以直接使用這個容器來部署代碼。 Docker 可以快速創建容器,快速迭代應用程序,並讓整個過程全程可見,使團隊中的其他成員更容易理解應用程序是如何創建和工作的。 Docker 容器很輕很快!容器的啓動時間是秒級的,大量地節約開發、測試、部署的時間。

高效的部署和擴容
Docker 容器幾乎可以在任意的平臺上運行,包括物理機、虛擬機、公有云、私有云、個人電腦、服務器等。 這種兼容性可以讓用戶把一個應用程序從一個平臺直接遷移到另外一個。

Docker的兼容性和輕量特性可以很輕鬆的實現負載的動態管理。你可以快速擴容或方便的下線的你的應用和服務,這種速度趨近實時。

更高的資源利用率
Docker 對系統資源的利用率很高,一臺主機上可以同時運行數千個 Docker 容器。容器除了運行其中應用外,基本不消耗額外的系統資源,使得應用的性能很高,同時系統的開銷儘量小。傳統虛擬機方式運行 10 個不同的應用就要起 10 個虛擬機,而Docker 只需要啓動 10 個隔離的應用即可。

更簡單的管理
使用 Docker,只需要小小的修改,就可以替代以往大量的更新工作。所有的修改都以增量的方式被分發和更新,從而實現自動化並且高效的管理。

Docker引擎
docker引擎是一個c/s結構的應用,主要組件見下圖:

docker engine components flow

Server是一個常駐進程
REST API 實現了client和server間的交互協議
CLI 實現容器和鏡像的管理,爲用戶提供統一的操作界面
Docker構架
Docker使用C/S架構,Client 通過接口與Server進程通信實現容器的構建,運行和發佈。client和server可以運行在同一臺集羣,也可以通過跨主機實現遠程通信。

docker architecture

核心概念
鏡像(image)
Docker 鏡像(Image)就是一個只讀的模板。例如:一個鏡像可以包含一個完整的操作系統環境,裏面僅安裝了 Apache 或用戶需要的其它應用程序。鏡像可以用來創建 Docker 容器,一個鏡像可以創建很多容器。Docker 提供了一個很簡單的機制來創建鏡像或者更新現有的鏡像,用戶甚至可以直接從其他人那裏下載一個已經做好的鏡像來直接使用。

鏡像(Image)就是一堆只讀層(read-only layer)的統一視角,也許這個定義有些難以理解,看看下面這張圖:
image ufs

右邊我們看到了多個只讀層,它們重疊在一起。除了最下面一層,其它層都會有一個指針指向下一層。這些層是Docker內部的實現細節,並且能夠在docker宿主機的文件系統上訪問到。統一文件系統(Union File System)技術能夠將不同的層整合成一個文件系統,爲這些層提供了一個統一的視角,這樣就隱藏了多層的存在,在用戶的角度看來,只存在一個文件系統。

倉庫(repository)
倉庫(Repository)是集中存放鏡像文件的場所。有時候會把倉庫和倉庫註冊服務器(Registry)混爲一談,並不嚴格區分。實際上,倉庫註冊服務器上往往存放着多個倉庫,每個倉庫中又包含了多個鏡像,每個鏡像有不同的標籤(tag)。

倉庫分爲公開倉庫(Public)和私有倉庫(Private)兩種形式。最大的公開倉庫是 Docker Hub,存放了數量龐大的鏡像供用戶下載。國內的公開倉庫包括 時速雲 、網易雲 等,可以提供大陸用戶更穩定快速的訪問。當然,用戶也可以在本地網絡內創建一個私有倉庫。

當用戶創建了自己的鏡像之後就可以使用 push 命令將它上傳到公有或者私有倉庫,這樣下次在另外一臺機器上使用這個鏡像時候,只需要從倉庫上 pull 下來就可以了。

Docker 倉庫的概念跟 Git 類似,註冊服務器可以理解爲 GitHub 這樣的託管服務。

容器(container)
Docker 利用容器(Container)來運行應用。容器是從鏡像創建的運行實例。它可以被啓動、開始、停止、刪除。每個容器都是相互隔離的、保證安全的平臺。可以把容器看做是一個簡易版的 Linux 環境(包括root用戶權限、進程空間、用戶空間和網絡空間等)和運行在其中的應用程序。

容器的定義和鏡像幾乎一模一樣,也是一堆層的統一視角,唯一區別在於容器的最上面那一層是可讀可寫的。

container ufs

一個運行態容器被定義爲一個可讀寫的統一文件系統加上隔離的進程空間和包含其中的進程。下面這張圖片展示了一個運行中的容器。

container running

正是文件系統隔離技術使得Docker成爲了一個非常有潛力的虛擬化技術。一個容器中的進程可能會對文件進行修改、刪除、創建,這些改變都將作用於可讀寫層。

Docker安裝部署
docker安裝非常簡單,支持各種平臺,請到官網自行安裝下載docker下載

Docker常用命令
獲取鏡像
docker pull
從倉庫獲取所需要的鏡像。

使用示例:

docker pull centos:centos6
實際上相當於 docker pull registry.hub.docker.com/centos:centos6
命令,即從註冊服務器 registry.hub.docker.com 中的 centos 倉庫來下載標記爲 centos6 的鏡像。
有時候官方倉庫註冊服務器下載較慢,可以從其他倉庫下載。 從其它倉庫下載時需要指定完整的倉庫註冊服務器地址。

查看鏡像列表#
docker images
列出了所有頂層(top-level)鏡像。實際上,在這裏我們沒有辦法區分一個鏡像和一個只讀層,所以我們
提出了top-level鏡像。只有創建容器時使用的鏡像或者是直接pull下來的鏡像能被稱爲頂層(top-level)
鏡像,並且每一個頂層鏡像下面都隱藏了多個鏡像層。

使用示例:

$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos centos6 6a77ab6655b9 8 weeks ago 194.6 MB
ubuntu latest 2fa927b5cdd3 9 weeks ago 122 MB
在列出信息中,可以看到幾個字段信息

來自於哪個倉庫,比如 ubuntu
鏡像的標記,比如 14.04
它的 ID 號(唯一)
創建時間
鏡像大小
利用 Dockerfile 來創建鏡像
docker build
使用 docker commit 來擴展一個鏡像比較簡單,但是不方便在一個團隊中分享。我們可以使用
docker build 來創建一個新的鏡像。爲此,首先需要創建一個 Dockerfile,包含一些如何創建鏡像的
指令。新建一個目錄和一個 Dockerfile。

mkdir hainiu
cd hainiu
touch Dockerfile
Dockerfile 中每一條指令都創建鏡像的一層,例如:

FROM centos:centos6
MAINTAINER sandywei <[email protected]>

move all configuration files into container

RUN yum install -y httpd
EXPOSE 80
CMD ["sh","-c","service httpd start;bash"]
Dockerfile 基本的語法是

使用#來註釋
FROM 指令告訴 Docker 使用哪個鏡像作爲基礎
接着是維護者的信息
RUN開頭的指令會在創建中運行,比如安裝一個軟件包,在這裏使用yum來安裝了一些軟件
更詳細的語法說明請參考 Dockerfile

編寫完成 Dockerfile 後可以使用 docker build 來生成鏡像。

$ docker build -t hainiu/httpd:1.0 .

Sending build context to Docker daemon 2.048 kB
Step 1 : FROM centos:centos6
---> 6a77ab6655b9
Step 2 : MAINTAINER sandywei <[email protected]>
---> Running in 1b26493518a7
---> 8877ee5f7432
Removing intermediate container 1b26493518a7
Step 3 : RUN yum install -y httpd
---> Running in fe5b6f1ef888

.....

Step 5 : CMD sh -c service httpd start
---> Running in b2b94c1601c2
---> 5f9aa91b0c9e
Removing intermediate container b2b94c1601c2
Successfully built 5f9aa91b0c9e
其中 -t 標記來添加 tag,指定新的鏡像的用戶信息。 “.” 是 Dockerfile 所在的路徑(當前目錄),
也可以替換爲一個具體的 Dockerfile 的路徑。注意一個鏡像不能超過 127 層。

用docker images 查看鏡像列表

$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hainiu/httpd 1.0 5f9aa91b0c9e 3 minutes ago 292.4 MB
centos centos6 6a77ab6655b9 8 weeks ago 194.6 MB
ubuntu latest 2fa927b5cdd3 9 weeks ago 122 MB
細心的朋友可以看到最後一層的ID(5f9aa91b0c9e)和 image id 是一樣的

上傳鏡像
docker push
用戶可以通過 docker push 命令,把自己創建的鏡像上傳到倉庫中來共享。例如,用戶在 Docker Hub 上完成註冊後,可以推送自己的鏡像到倉庫中。

運行實例:

$ docker push hainiu/httpd:1.0
創建容器
docker create <image-id>
docker create 命令爲指定的鏡像(image)添加了一個可讀寫層,構成了一個新的容器。注意,這個容器並沒有運行。

docker create 命令提供了許多參數選項可以指定名字,硬件資源,網絡配置等等。

運行示例:

創建一個centos的容器,可以使用倉庫+標籤的名字確定image,也可以使用image-id指定image。返回容器id

#查看本地images列表
$ docker images

#用倉庫+標籤
$ docker create -it --name centos6_container centos:centos6

#使用image-id
$ docker create -it --name centos6_container 6a77ab6655b9 bash
b3cd0b47fe3db0115037c5e9cf776914bd46944d1ac63c0b753a9df6944c7a67

#可以使用 docker ps查看一件存在的容器列表,不加參數默認只顯示當前運行的容器
$ docker ps -a
可以使用 -v 參數將本地目錄掛載到容器中。

$ docker create -it --name centos6_container -v /src/webapp:/opt/webapp centos:centos6
這個功能在進行測試的時候十分方便,比如用戶可以放置一些程序到本地目錄中,來查看容器是否正常工作。本地目錄的路徑必須是絕對路徑,如果目錄不存在 Docker 會自動爲你創建它。

啓動容器
docker start <container-id>
Docker start命令爲容器文件系統創建了一個進程隔離空間。注意,每一個容器只能夠有一個進程隔離空間。

運行實例:

#通過名字啓動
$ docker start -i centos6_container

#通過容器ID啓動
$ docker start -i b3cd0b47fe3d
進入容器
docker exec <container-id>
在當前容器中執行新命令,如果增加 -it參數運行bash 就和登錄到容器效果一樣的。

docker exec -it centos6_container bash
停止容器#
docker stop <container-id>
刪除容器#
docker rm <container-id>
運行容器
docker run <image-id>
docker run就是docker create和docker start兩個命令的組合,支持參數也是一致的,如果指定容器
名字是,容器已經存在會報錯,可以增加 --rm 參數實現容器退出時自動刪除。

運行示例:

docker create -it --rm --name centos6_container centos:centos6
查看容器列表
docker ps
docker ps 命令會列出所有運行中的容器。這隱藏了非運行態容器的存在,如果想要找出這些容器,增加 -a 參數。

刪除鏡像
docker rmi <image-id>
刪除構成鏡像的一個只讀層。你只能夠使用docker rmi來移除最頂層(top level layer)
(也可以說是鏡像),你也可以使用-f參數來強制刪除中間的只讀層。

commit容器#
docker commit <container-id>
將容器的可讀寫層轉換爲一個只讀層,這樣就把一個容器轉換成了不可變的鏡像。

鏡像保存#
docker save <image-id>
創建一個鏡像的壓縮文件,這個文件能夠在另外一個主機的Docker上使用。和export命令不同,這個命令
爲每一個層都保存了它們的元數據。這個命令只能對鏡像生效。

使用示例:

#保存centos鏡像到centos_images.tar 文件
$ docker save -o centos_images.tar centos:centos6

#或者直接重定向
$ docker save -o centos_images.tar centos:centos6 > centos_images.tar
容器導出
docker export <container-id>
創建一個tar文件,並且移除了元數據和不必要的層,將多個層整合成了一個層,只保存了當前統一視角看到
的內容。expoxt後的容器再import到Docker中,只有一個容器當前狀態的鏡像;而save後的鏡像則不同,
它能夠看到這個鏡像的歷史鏡像。

inspect
docker inspect <container-id> or <image-id>
docker inspect命令會提取出容器或者鏡像最頂層的元數據

版權聲明:原創作品,允許轉載,轉載時務必以超鏈接的形式表明出處和作者信息。否則將追究法律責任。來自海牛部落-青牛,http://hainiubl.com/topics/13

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章