算法工程師的修養(yǎng) | Docker容器技術(shù)使用指南
點(diǎn)擊上方“機(jī)器學(xué)習(xí)與生成對(duì)抗網(wǎng)絡(luò)”,關(guān)注星標(biāo)
獲取有趣、好玩的前沿干貨!
編輯 開源Linux 侵刪
目錄
第一部分 Docker 容器技術(shù)基礎(chǔ)及其應(yīng)用場(chǎng)景介紹
1.1 Docker 的基本概念
1.2 為什么使用 Docker
1.3 Docker 體系結(jié)構(gòu)簡(jiǎn)介
1.4 Docker 容器技術(shù)的應(yīng)用場(chǎng)景
第二部分 核心概念與安裝配置
2.1 核心概念
2.2 安裝 Docker
2.2.1 在 Red Hat Enterprise Linux 上安裝 Docker
2.2.2 在 Windows 上安裝 Docker
2.2.3 在 CentOS 環(huán)境下安裝 Docker
第三部分 使用 Docker 鏡像
3.1 獲取鏡像
3.2 查看鏡像信息
3.3 搜尋鏡像
3.4 刪除鏡像
3.5 創(chuàng)建鏡像
3.6 存出和載入鏡像
3.7 上傳鏡像
第四部分 操作 Docker 容器
4.1 創(chuàng)建容器
4.2 終止容器
4.3 進(jìn)入容器
4.4 刪除容器
4.5 導(dǎo)入和導(dǎo)出容器
4.6 實(shí)現(xiàn)容器的網(wǎng)絡(luò)端口映射
第五部分 Docker 容器實(shí)現(xiàn) Web 服務(wù)與應(yīng)用
5.1 Docker 容器實(shí)現(xiàn) Apache 服務(wù)
5.2 Docker 容器實(shí)現(xiàn) Nginx 服務(wù)
5.3 Docker 容器實(shí)現(xiàn) Python 應(yīng)用
5.4 Docker 容器實(shí)現(xiàn) MySQL 服務(wù)
第六部分 Docker 的運(yùn)行監(jiān)控
6.1 容器的監(jiān)控方案
6.2 單臺(tái)主機(jī)上容器的監(jiān)控
6.3 跨多臺(tái)主機(jī)上容器的監(jiān)控
6.4 Kubernetes 上容器的監(jiān)控
6.5 Mesos 的監(jiān)控方案
6.6 性能采集工具的對(duì)比
第一部分 Docker 容器技術(shù)基礎(chǔ)及其應(yīng)用場(chǎng)景介紹
1.1 Docker 的基本概念
Docker 容器是資源分割和調(diào)度的基本單位,封裝整個(gè)服務(wù)的運(yùn)行時(shí)環(huán)境,用于構(gòu)建、發(fā)布和運(yùn)行分布式應(yīng)用的一個(gè)框架。它是一個(gè)跨平臺(tái)、可移植并且簡(jiǎn)單易用的容器解決方案。Docker 的源代碼托管在 GitHub 上,基于 Go 語言開發(fā)并遵從 Apache 2.0 協(xié)議。
Docker 容器可以快速自動(dòng)化地部署應(yīng)用,并通過操作系統(tǒng)內(nèi)核技術(shù)(namespaces、 cgroups等)為容器提供資源隔離與安全保障。Docker 作為輕量級(jí)的虛擬化方式,實(shí)現(xiàn)了 PaaS 平臺(tái)的高效部署、運(yùn)行和維護(hù)。

1.2 為什么使用 Docker

( 1 ) 、持續(xù)部署與測(cè)試
Docker 消除了線上線下的環(huán)境差異,保證了應(yīng)用生命周期的環(huán)境一致性和標(biāo)準(zhǔn)化。開發(fā)人員使用鏡像實(shí)現(xiàn)標(biāo)準(zhǔn)開發(fā)環(huán)境的構(gòu)建,開發(fā)完成后通過封裝著完整環(huán)境和應(yīng)用的鏡像進(jìn)行遷移,由此,測(cè)試和運(yùn)維人員可以直接部署軟件鏡像來進(jìn)行測(cè)試和發(fā)布,大大簡(jiǎn)化了持續(xù)集成、測(cè)試和發(fā)布的過程。
Docker 是革命性的,它重新定義了軟件開發(fā)、測(cè)試、交付和部署的流程。我們交付的東西不再只是代碼、配置文件、數(shù)據(jù)庫定義等,而是整個(gè)應(yīng)用服務(wù)及其運(yùn)行環(huán)境。
( 2 ) 、優(yōu)異的跨平臺(tái)性
Docker 在原有 Linux 容器的基礎(chǔ)上進(jìn)行大膽革新,為容器設(shè)定了一 整套標(biāo)準(zhǔn)化的配置方法,將應(yīng)用及其依賴的運(yùn)行環(huán)境打包成鏡像。Docker 是可移植(或者說跨平臺(tái))的,可以在各種主流操作系統(tǒng)上使用。Java 可以做到“一次編譯,到處運(yùn)行”,而 Docker 可以 “構(gòu)建一次,在各平臺(tái)上運(yùn)行”(Build once,run anywhere)。越來越多的云平臺(tái)都支持 Docker,用戶再也無需擔(dān)心受到云平臺(tái)的捆綁,同時(shí)也讓應(yīng)用多平臺(tái)混合部署成為可能。
( 3 ) 、高資源利用率與隔離
Docker 容器沒有管理程序的額外開銷,與底層共享操作系統(tǒng),性能更加優(yōu)良,系統(tǒng)負(fù)載更低,在同等條件下可以運(yùn)行更多的應(yīng)用實(shí)例,可以更充分地利 用系統(tǒng)資源。同時(shí),Docker 擁有不錯(cuò)的資源隔離與限制能力,可以精確地對(duì)應(yīng)用分配 CPU、 內(nèi)存等資源,保證了應(yīng)用間不會(huì)相互影響。Docker 是輕量級(jí)虛擬化技術(shù)。與傳統(tǒng)的 VM 相比,它更輕量,啟動(dòng)速度更快,單臺(tái)硬件上可以同時(shí)跑成百上千個(gè)容器,所以非常適合在業(yè)務(wù)高峰期通過啟動(dòng)大量容器進(jìn)行橫向擴(kuò)展。Docker 容器技術(shù)的直接虛擬化不僅在技術(shù)方面使 CPU 利用率得到顯著提升,還因 80:20 法則可在業(yè)務(wù)上更大程度發(fā)揮 CPU 利用率,真正體現(xiàn)了虛擬化精髓。
( 4 ) 、環(huán)境標(biāo)準(zhǔn)化和版本控制
可以使用 Git 等工具對(duì) Docker 鏡像進(jìn)行版本控制,相比基于代碼的版本控制來說,能夠?qū)φ麄€(gè)應(yīng)用運(yùn)行環(huán)境實(shí)現(xiàn)版本控制,一旦出現(xiàn)故障可以快速回滾。相比以前的虛擬機(jī)鏡像,Docker 壓縮和備份速度更快,鏡像啟動(dòng)也像啟動(dòng)一個(gè)普通進(jìn)程一樣快速。
( 5 ) 、應(yīng)用鏡像倉庫
Docker 官方構(gòu)建了一個(gè)鏡像倉庫,組織和管理形式類似于 GitHub,其上 已累積了成千上萬的鏡像。因?yàn)?Docker 的跨平臺(tái)適配性,相當(dāng)于為用戶提供了一個(gè)非常 有用的應(yīng)用商店,所有人都可以自由地下載微服務(wù)組件,這為開發(fā)者提供了巨大便利。
1.3 Docker 體系結(jié)構(gòu)簡(jiǎn)介

Docker 是一個(gè)客戶/服務(wù)器(CIient/Server,CS)架構(gòu)(見上圖) 。Docker 客戶端是遠(yuǎn)程控制器,可通過 TCP REST 向 Docker Host 發(fā)送請(qǐng)求,包括創(chuàng)建容器、運(yùn)行容器、保存容器、刪除容器等請(qǐng)求。Docker 服務(wù)端的 Daemon 對(duì)客戶端的請(qǐng)求進(jìn)行相應(yīng)的管理,隨后通過 driver 轉(zhuǎn)發(fā)至容器中的 libcontainer 執(zhí)行環(huán)境。libcontainer 提供與不同 Linux 內(nèi)核隔離的接口,類似命名空間及控制組。這種架構(gòu)允許多個(gè)容器在共享同一個(gè) Linux 內(nèi)核的情況下完全隔離地運(yùn)行。

1.4 Docker 容器技術(shù)的應(yīng)用場(chǎng)景
一般認(rèn)為 Docker 技術(shù)有以下 8 個(gè)主要的應(yīng)用場(chǎng)景,參見下圖:

( 1 ) 、應(yīng)用場(chǎng)景 1:簡(jiǎn)化配置
這是 Docker 公司宣傳的 Docker 的主要使用場(chǎng)景。Docker 能將運(yùn)行環(huán)境和配置放在代碼中然后部署,同一個(gè) Docker 的配置可以在不同的環(huán)境中使用,這樣就降低了硬件要求和應(yīng)用環(huán)境之間耦合度。
( 2 ) 、應(yīng)用場(chǎng)景 2:代碼流水線(Code Pipeline)管理
代碼從開發(fā)者的機(jī)器到最終在生產(chǎn)環(huán)境上的部署,需要經(jīng)過很多的中間環(huán)境。而每一個(gè)中間環(huán)境都有微小的差別,Docker 給應(yīng)用提供了一個(gè)從開發(fā)到上線均一致的環(huán)境,讓代碼的流水線變得簡(jiǎn)單不少。
( 3 ) 、應(yīng)用場(chǎng)景 3:提高開發(fā)效率
Docker 能提升開發(fā)者的開發(fā)效率。不同的開發(fā)環(huán)境中,Docker 都可以把兩件事做好,一是可以在開發(fā)環(huán)境、生產(chǎn)環(huán)境之間直接遷移,二是可以讓我們快速搭建開發(fā)環(huán)境。開發(fā)環(huán)境的機(jī)器通常內(nèi)存比較小,之前使用虛擬的時(shí)候,我們經(jīng)常需要為開發(fā)環(huán)境的機(jī)器加內(nèi)存,而現(xiàn)在Docker 可以輕易的讓幾十個(gè)服務(wù)在 Docker 中跑起來。
( 4 ) 、應(yīng)用場(chǎng)景 4:隔離應(yīng)用
有很多種原因會(huì)讓我們選擇在一個(gè)機(jī)器上運(yùn)行不同的應(yīng)用,Docker 非常適合在較低的成本下實(shí)現(xiàn)多種應(yīng)用的隔離。
( 5 ) 、應(yīng)用場(chǎng)景 5:整合服務(wù)器
Docker 隔離應(yīng)用的能力使得 Docker 可以整合多個(gè)服務(wù)器以降低成本。由于沒有操作系統(tǒng)的內(nèi)存占用,以及能在多個(gè)實(shí)例之間共享沒有使用的內(nèi)存,Docker 可以比虛擬機(jī)提供更好的服務(wù)器整合解決方案。通常數(shù)據(jù)中心的服務(wù)器資源利用率只有 30%,通過使用 Docker 并進(jìn)行有效的資源分配可以大幅提高服務(wù)器資源的利用率。
( 6 ) 、應(yīng)用場(chǎng)景 6:調(diào)試能力
Docker 提供了很多的工具,包括可以為容器設(shè)置檢查點(diǎn)、設(shè)置版本和查看兩個(gè)容器之間的差別,這些特性可以幫助調(diào)試 Bug。
( 7 ) 、應(yīng)用場(chǎng)景 7:多租戶環(huán)境
另外一個(gè) Docker 的使用場(chǎng)景是在多租戶的應(yīng)用中,它可以避免關(guān)鍵應(yīng)用的重寫。我們一個(gè)特別的關(guān)于這個(gè)場(chǎng)景的例子是為物聯(lián)網(wǎng)的應(yīng)用開發(fā)一個(gè)快速、易用的多租戶環(huán)境。這種多租戶的基本代碼非常復(fù)雜,很難處理,重新規(guī)劃這樣一個(gè)應(yīng)用不但消耗時(shí)間,也浪費(fèi)金錢。
使用 Docker,可以為每一個(gè)租戶的應(yīng)用層的多個(gè)實(shí)例創(chuàng)建隔離的環(huán)境,這不僅簡(jiǎn)單而且成本低廉,當(dāng)然這一切得益于 Docker 環(huán)境的啟動(dòng)速度和其高效的 diff 命令。
( 8 ) 、應(yīng)用場(chǎng)景 8:快速部署
在虛擬機(jī)之前,購(gòu)入部署新的硬件資源需要消耗幾天的時(shí)間。虛擬化技術(shù)(Virtualization)將這個(gè)時(shí)間縮短到了分鐘級(jí)別。而 Docker 通過為進(jìn)程僅僅創(chuàng)建一個(gè)容器而無需啟動(dòng)一個(gè)操作系統(tǒng),再次將這個(gè)過程縮短到了秒級(jí)。這正是 Google 和 Facebook 都看重的特性。我們可以創(chuàng) 建銷毀 Docker 容器而無需擔(dān)心重新啟動(dòng)帶來的開銷。
第二部分 核心概念與安裝配置
本部分首先介紹 Docker 的三大核心概念。
? 鏡像(Image)
? 容器(Container)
? 倉庫(Repository)
只有理解了這三個(gè)核心概念,才能順利地理解 Docker 容器的整個(gè)生命周期。隨后將介紹如何在常見的操作系統(tǒng)平臺(tái)上安裝 Docker,包括 Redhat Linux、Windows、Centos 等主流操作系統(tǒng)平臺(tái)。
2.1 核心概念
Docker 的大部分操作都圍繞著它的三大核心概念——鏡像、容器和倉庫而展開。因此,準(zhǔn)確把握這三大核心概念對(duì)于掌握 Docker 技術(shù)尤為重要。
1 . Docker 鏡像
Docker 鏡像類似于虛擬機(jī)鏡像,可以將它理解為一個(gè)只讀的模板。例如,一個(gè)鏡像可以包含一個(gè)基本的操作系統(tǒng)環(huán)境,里面僅安裝了 Apache 應(yīng)用程序(或用戶需要的其他軟件)。可以把它稱為一個(gè)Apache 鏡像。
鏡像是創(chuàng)建 Docker 容器的基礎(chǔ)。通過版本管理和增量的文件系統(tǒng),Docker 提供了一套十分簡(jiǎn)單的機(jī)制來創(chuàng)建和更新現(xiàn)有的鏡像,用戶甚至可以從網(wǎng)上下載一個(gè)已經(jīng)做好的應(yīng)用鏡像, 并直接使用 。
2 . Docker 容器
Docker 容器類似于一個(gè)輕量級(jí)的沙箱,Docker 利用容器來運(yùn)行和隔離應(yīng)用。容器是從鏡像創(chuàng)建的應(yīng)用運(yùn)行實(shí)例。可以將其啟動(dòng)、開始、停止、刪除,而這些容器都是彼此相互隔離的、互不可見的。
可以把容器看做是一個(gè)簡(jiǎn)易版的 Linux 系統(tǒng)環(huán)境(包括 root 用戶權(quán)限、進(jìn)程空間、用戶空間和網(wǎng)絡(luò)空間等)以及運(yùn)行在其中的應(yīng)用程序打包而成的盒子。
3 . Docker 倉庫
Docker 倉庫類似于代碼倉庫,它是 Docker 集中存放鏡像文件的場(chǎng)所。
有時(shí)候會(huì)看到有資料將 Docker 倉庫和倉庫注冊(cè)服務(wù)器(Registry)混為一談,并不嚴(yán)格區(qū)分。實(shí)際上,倉庫注冊(cè)服務(wù)器是存放倉庫的地方,其上往往存放著多個(gè)倉庫。每個(gè)倉庫集中存放某一類鏡像,往往包括多個(gè)鏡像文件,通過不同的標(biāo)簽(tag)來進(jìn)行區(qū)分。例如存放 ubuntu操作系統(tǒng)鏡像的倉庫稱為 ubuntu 倉庫,其中可能包括 14.04、12.04 等不同版本的鏡像。
根據(jù)所存儲(chǔ)的鏡像公開分享與否,Docker 倉庫可以分為公開倉庫(Public)和私有倉庫(Private)兩種形式。目前,最大的公開倉庫是官方提供的 Docker Hub,其中存放了數(shù)量龐大的鏡像供用戶下載。國(guó)內(nèi)不少云服務(wù)提供商(如時(shí)速云、阿里云等)也提供了倉庫的本地源,可以提供穩(wěn)定的國(guó)內(nèi)訪問。
當(dāng)然,用戶如果不希望公開分享自己的鏡像文件,Docker 也支持用戶在本地網(wǎng)絡(luò)內(nèi)創(chuàng)建一個(gè)只能自己訪問的私有倉庫。當(dāng)用戶創(chuàng)建了自己的鏡像之后就可以使用 push 命令將它上傳到指定的公有或者私有倉庫。這樣用戶下次在另外一臺(tái)機(jī)器上使用該鏡像時(shí),只需要將其從倉庫上 pull 下來就可以了。
可以看出,Docker 利用倉庫管理鏡像的設(shè)計(jì)理念與 Git 非常相似,實(shí)際上在理念設(shè)計(jì)上借鑒了 Git 的很多優(yōu)秀思想。
2.2 安裝Docker
Docker 在主流的操作系統(tǒng)和云平臺(tái)上都可以使用,包括 Linux 操作系統(tǒng)(如 ubuntu、Debian、CentOS、Redhat 等)、MacOS 操作系統(tǒng)和 Windows 操作系統(tǒng),以及 AWS 等云平臺(tái)。
用戶可以訪問 Docker 官網(wǎng)的 Get Docker(https://www.docker.com/products/overview)頁面,查看獲取 Docker 的方式,以及 Docker 支持的平臺(tái)類型,如圖 2-2 所示。
在 Get Docker 頁面,我們可以看到目前 Docker 支持 Docker Platform、Docker Hub、Docker Cloud 和 Docker DataCenter。
? Docker Platform:支持在桌面系統(tǒng)或云平臺(tái)安裝 Docker;
? DockerHub:官方提供的云托管服務(wù),可以提供公有或私有的鏡像倉庫;
? DockerCloud:官方提供的容器云服務(wù),可以完成容器的部署與管理,可以完整地支持容器化項(xiàng)目,還有 CI、CD 功能;
? Docker DataCenter:提供企業(yè)級(jí)的簡(jiǎn)單安全彈性的容器集群編排和管理。
推薦盡量使用 Linux 操作系統(tǒng)來運(yùn)行 Docker,因?yàn)槟壳?Linux 操作系統(tǒng)對(duì) Docker的支持是原生的,使用體驗(yàn)最好。
2.2.1 在 Red Hat Enterprise Linux 上安裝 Docker
以下是支持 Docker 的 RHEL 版本:
Red Hat Enterprise Linux 7 (64-bit)
Red Hat Enterprise Linux 6.5 (64-bit) 或更高版本
如果你的 RHEL 運(yùn)行的是發(fā)行版內(nèi)核。那就僅支持通過 extras 渠道或者 EPEL 包來安裝Docker。如果我們打算在非發(fā)行版本的內(nèi)核上運(yùn)行 Docker ,內(nèi)核的改動(dòng)可能會(huì)導(dǎo)致出錯(cuò)
1.Red Hat Enterprise Linux 7 安裝 Docker
Red Hat Enterprise Linux 7 (64 位) 自帶 Docker。我們可以在發(fā)行日志中找到概述和指南。
Docker 包含在 extras 鏡像源中,使用下面的方法可以安裝 Docker:
啟用 extras 鏡像源:
$ sudo subscription-manager repos --enable=rhel-7-server-extras-rpms
安裝 Docker :
$ sudo yum install docker
2.Red Hat Enterprise Linux 6.5 安裝 Docker
需要在 64 位 的 RHEL 6.5 或更高的版本上來安裝 Docker,Docker 工作需要特定的內(nèi)核補(bǔ)丁, 因此 RHEL 的內(nèi)核版本應(yīng)為 2.6.32-431 或者更高。
Docker 已經(jīng)包含在 RHEL 的 EPEL 源中。該源是 Extra Packages for Enterprise Linux (EPEL) 的一個(gè)額外包,社區(qū)中正在努力創(chuàng)建和維護(hù)相關(guān)鏡像。
首先,你需要安裝 EPEL 鏡像源,在 EPEL 中已經(jīng)提供了 docker-io 包。
下一步,我們將要在我們的主機(jī)中安裝 Docker,也就是 docker-io 包:
$ sudo yum -y install docker-io
更新 docker-io 包:
$ sudo yum -y update docker-io
現(xiàn)在 Docker 已經(jīng)安裝好了,我們來啟動(dòng) docker 進(jìn)程:
$ sudo service docker start
設(shè)置開機(jī)啟動(dòng):
$ sudo chkconfig docker on
現(xiàn)在,讓我們確認(rèn) Docker 是否正常工作:
$ sudo docker run -i -t fedora /bin/bash
現(xiàn)在 Docker 已經(jīng)安裝好了,讓我們來啟動(dòng) Docker 進(jìn)程
$ sudo service docker start
如果我們想要開機(jī)啟動(dòng) Docker ,我們需要執(zhí)行如下的命令:
$ sudo chkconfig docker on
現(xiàn)在測(cè)試一下是否正常工作:
$ sudo docker run -i -t fedora /bin/bash
注意: 如果運(yùn)行的時(shí)候提示一個(gè) Cannot start container 的錯(cuò)誤,錯(cuò)誤中提到了SELINUX 或者 權(quán)限不足。我們需要更新 SELINUX 規(guī)則。可以使用 sudo yum upgrade selinux-policy 然后重啟。
2.2.2 在 Windows 上安裝 Docker
1. 安裝
1 ) 、下載最新版本的 Docker for Windows Installer
2 ) 、運(yùn)行安裝文件,它將會(huì)安裝 virtualbox、 MSYS-git boot2docker Linux 鏡像和 Boot2Docker的管理工具。

3)、從桌面上或者 Program Files 中找到 Boot2Docker for Windows,運(yùn)行 Boot2Docker Start 腳本。這個(gè)腳本會(huì)要求你輸入 ssh 密鑰密碼 - 可以簡(jiǎn)單點(diǎn)(但是起碼看起來比較安全) ,然后只需要按[Enter]按鈕即可。
4)、Boot2Docker Start 將啟動(dòng)一個(gè) Unix shell 來配置和管理運(yùn)行在虛擬主機(jī)中的 Docker,運(yùn)行 docker version 來查看它是否正常工作。

2. 運(yùn)行 Docker
注意:如果使用的是一個(gè)遠(yuǎn)程的 Docker 進(jìn)程,像 Boot2docker ,就不需要像前邊的文檔實(shí)例中那樣在輸入 Docker 命令之前輸入 sudo。
Boot2docker start 將會(huì)自動(dòng)啟動(dòng)一個(gè) shell 命令框并配置好環(huán)境變量,以便我們可以馬上使用 Docker :
讓我們嘗試運(yùn)行 hello-world 例子。運(yùn)行:
$ docker run hello-world
這將會(huì)下載一個(gè)非常小的 hello-world 鏡像,并且打印出 Hello from Docker 的信息。
3. 使用 Windows 的命令行( ( cmd.exe ) 來管理運(yùn)行 Docker
啟動(dòng)一個(gè) Windows 命令行(cmd.exe) ,運(yùn)行 Boot2docker 命令,這需要 Windows PATH 環(huán)境變量中包含了 ssh.exe。因此我們需要將安裝的 Git 的 bin 目錄 (其中包含了 ssh.exe)配置到我們的 %PATH% 環(huán)境變量中,運(yùn)行如下命令:
set PATH=%PATH%;"c:\Program Files (x86)\Git\bin"
現(xiàn)在,我們可以運(yùn)行 boot2docker start 命令來啟動(dòng) Boot2docker 虛擬機(jī)。(如果有虛擬主機(jī)不存在的錯(cuò)誤提示,需要運(yùn)行 boot2docker init 命令) 。復(fù)制上邊的指令到 cmd.exe 來設(shè)置 windows 控制臺(tái)的環(huán)境變量,然后就可以運(yùn)行 docker 命令了,譬如 docker ps :

4. PowerShell 中使用 Docker
啟動(dòng) PowerShell,需要將 ssh.exe 添加到 PATH 中。
$Env:Path = "${Env:Path};c:\Program Files (x86)\Git\bin"
之后,運(yùn)行 boot2docker start 命令行,它會(huì)打印出 PowerShell 命令,這些命令是用來設(shè)置環(huán)境變量來連接運(yùn)行在虛擬機(jī)中 Docker 的。運(yùn)行這些命令,然后就可以運(yùn)行 docker 命令了,譬如 docker ps :

提示:可以使用 boot2docker shellinit | Invoke-Expression 來設(shè)置環(huán)境變量來代替復(fù)制粘貼 Powershell 命令。
2.2.3 在 CentOS 環(huán)境下安裝 Docker
Docker 支持以下的 CentOS 版本:
CentOS 7 (64-bit)
CentOS 6.5 (64-bit)或更高的版本
前提條件
Docker 運(yùn)行在 CentOS 7 上,要求系統(tǒng)為 64 位、系統(tǒng)內(nèi)核版本為 3.10 以上。
Docker 運(yùn)行在 CentOS-6.5 或更高的版本的 CentOS 上,要求系統(tǒng)為 64 位、系統(tǒng)內(nèi)核版本為2.6.32-431 或者更高版本。
使用 yum 安裝(CentOS 7 下)
Docker 要求 CentOS 系統(tǒng)的內(nèi)核版本高于 3.10 ,查看本頁面的前提條件來驗(yàn)證你的 CentOS 版本是否支持 Docker 。
通過 uname - - r 命令查看你當(dāng)前的內(nèi)核版本
uname -r 3.10.0-327.el7.x86_64

安裝 Docker
Docker 軟件包和依賴包已經(jīng)包含在默認(rèn)的 CentOS-Extras 軟件源里,安裝命令如下:
yum -y install docker

安裝完成。

啟動(dòng) Docker 后臺(tái)服務(wù)
service docker start

測(cè) 試 運(yùn) 行 hello-world
docker run hello-world

由于本地沒有 hello-world 這個(gè)鏡像,所以會(huì)下載一個(gè) hello-world 的鏡像,并在容器內(nèi)運(yùn)行。
使用腳本安裝 Docker
1、使用 sudo 或 root 權(quán)限登錄 Centos。
2、確保 yum 包更新到最新。
$ sudo yum update
3、執(zhí)行 Docker 安裝腳本。
$ curl -fsSL https://get.docker.com/ | sh
執(zhí)行這個(gè)腳本會(huì)添加 docker.repo 源并安裝 Docker。
4、啟動(dòng) Docker 進(jìn)程。
$ sudo service docker start
5、驗(yàn)證 docker 是否安裝成功并在容器中執(zhí)行一個(gè)測(cè)試的鏡像。
$ sudo docker run hello-world
到此,docker 在 CentOS 系統(tǒng)的安裝完成。
第三部分 使用 Docker 鏡像
鏡像(image)是 Docker 三大核心概念中最為重要的,自 Docker 誕生之日起“鏡像”就是相關(guān)社區(qū)最為熱門的關(guān)鍵詞。
Docker 運(yùn)行容器前需要本地存在對(duì)應(yīng)的鏡像,如果鏡像沒保存在本地,Docker 會(huì)嘗試先從默認(rèn)鏡像倉庫下載(默認(rèn)使用:Docker Hub 公共注冊(cè)服務(wù)器中的倉庫),用戶也可以通過配置,使用自定義的鏡像倉庫。
本部分將介紹圍繞鏡像這一核心概念的具體操作,包括如何使用 pull 命令從 Docker Hub 倉庫中下載鏡像到本地,如何查看本地已有的鏡像信息和管理鏡像標(biāo)簽,如何在遠(yuǎn)端倉庫使用 search 命令進(jìn)行搜索和過濾,如何刪除鏡像標(biāo)簽和鏡像文件,如何創(chuàng)建用戶定制的鏡像并且保存為外部文件。最后,還介紹如何往 Docker Hub 倉庫中推送自己的鏡像。
3.1 獲取鏡像
鏡像是運(yùn)行容器的前提,官方的 Docker Hub 網(wǎng)站已經(jīng)提供了數(shù)十萬個(gè)鏡像供大家開放下載。
可以使用 docker pull 命令直接從 Docker Hub 鏡像源來下載鏡像。該命令的格式為docker pull NAME[:TAG]。其中,NAME 是鏡像倉庫的名稱(用來區(qū)分鏡像),TAG 是鏡像的標(biāo)簽(往往用來表示版本信息)。通常情況下,描述一個(gè)鏡像需要包括‘名稱+標(biāo)簽’信息。
例如,獲取一個(gè) Ubuntu 14.04 系統(tǒng)的基礎(chǔ)鏡像可以使用如下的命令:

對(duì)于 Docker 鏡像來說,如果不顯式指定 TAG,則默認(rèn)會(huì)選擇 latest 標(biāo)簽,這會(huì)下載倉庫中最新版本的鏡像。
下面的例子將從 Docker Hub 的 Ubuntu 倉庫下載一個(gè)最新的 Ubuntu 操作系統(tǒng)的鏡像。

該命令實(shí)際上下載的就是 ubuntu: latest 鏡像。
下載過程中可以看出,鏡像文件一般由若干層(layer)組成,6c953ac5d795 這樣的串是層的唯一 id(實(shí)際上完整的 id 包括 256 比特,由 64 個(gè)十六進(jìn)制字符組成)。使用 docker pull 命令下載時(shí)會(huì)獲取并輸出鏡像的各層信息。當(dāng)不同的鏡像包括相同的層時(shí),本地僅存儲(chǔ)層的一份內(nèi)容,減小了需要的存儲(chǔ)空問。
我們可能會(huì)想到,在使用不同的鏡像倉庫服務(wù)器的情況下,可能會(huì)出現(xiàn)按鏡像重名的情況。
嚴(yán)格地講,鏡像的倉庫名稱中還應(yīng)該添加倉庫地址(即 registry,注冊(cè)服務(wù)器)作為前綴,只是我們默認(rèn)使用的是 Docker Hub 服務(wù),該前綴可以忽略。
例如,docker pull Ubuntu:14.04 命令相當(dāng)于 docker pull registry.hub.docker.com/Ubuntu:14.04 命令,即從默認(rèn)的注冊(cè)服務(wù)器 Docker Hub Registry 中的 ubuntu 倉庫來下載標(biāo)記為 14.04 的鏡像。
如果從非官方的倉庫下載,則需要在倉庫名稱前指定完整的倉庫地址。例如從網(wǎng)易蜂巢的鏡像源來下載 ubuntu:14.04 鏡像,可以使用如下命令,此時(shí)下載的鏡像名稱為
hub.c.163.com/public/Ubuntu:14.04:
$ docker pull hub.c.163.com/public/Ubuntu:14.04
pull 子命令支持的選項(xiàng)主要包括:
-a,--all- tags=true| false:是否獲取倉庫中的所有鏡像,默認(rèn)為否。
下載鏡像到本地后,即可隨時(shí)使用該鏡像了,例如利用該鏡像創(chuàng)建一個(gè)容器,在其中運(yùn)行 bash 應(yīng)用,執(zhí)行 ping localhost 命令:


3.2 查看鏡像信息
1. 使用 images 命令列出鏡像
使用 docker images 命令可以列出本地主機(jī)上已有鏡像的基本信息。例
如,下面的命令列出了上一小節(jié)中下載的鏡像信息:

在列出的信息中,可以看到以下幾個(gè)字段信息。
? 來自于哪個(gè)倉庫,比如 ubuntu 倉庫用來保存 ubuntu 系列的基礎(chǔ)鏡像;
? 鏡像的標(biāo)簽信息,比如 14.04、latest 用來標(biāo)注不同的版本信息。標(biāo)簽只是標(biāo)記,并不能標(biāo)識(shí)鏡像內(nèi)容;
? 鏡像的 ID(唯一標(biāo)識(shí)鏡像),如 ubuntu:latest 和 ubuntu:16.04 鏡像的 ID 都是 2fa927b5cdd3,說明它們目前實(shí)際上指向同一個(gè)鏡像;
? 創(chuàng)建時(shí)間,說明鏡像最后的更新時(shí)間;
? 鏡像大小,優(yōu)秀的鏡像往往體積都較小。
其中鏡像的 ID 信息十分重要,它唯一標(biāo)識(shí)了鏡像。在使用鏡像 ID 的時(shí)候,一般可以使用該 ID 的前若干個(gè)字符組成的可區(qū)分串來替代完整的 ID。
TAG 信息用來標(biāo)記來自同一個(gè)倉庫的不同鏡像。例如 ubunm 倉庫中有多個(gè)鏡像,通過TAG 信息來區(qū)分發(fā)行版本,包括 10.04、12.04、12.10、13.04、14.04、16.04 等標(biāo)簽:
鏡像大小信息只是表示該鏡像的邏輯體積大小,實(shí)際上由于相同的鏡像層本地只會(huì)存儲(chǔ)一份,物理上占用的存儲(chǔ)空間會(huì)小于各鏡像的邏輯體積之和。
images 子命令主要支持如下選項(xiàng),用戶可以自行進(jìn)行嘗試。
? -a,--all=true | false:列出所有的鏡像文件(包括臨時(shí)文件),默認(rèn)為否;
? --digests=true I false:列出鏡像的數(shù)字摘要值,默認(rèn)為否;
? -f,---filter=[ ]:過濾列出的鏡像,如 dangling=true 只顯示沒有被使用的鏡像;
也可指定帶有特定標(biāo)注的鏡像等;
? --format="TEMPLATE":控制輸出格式,如.ID 代表 ID 信息,Repository 代表倉庫信息等;
? --no-trunc=true l false:對(duì)輸出結(jié)果中太長(zhǎng)的部分是否進(jìn)行截?cái)啵珑R像的 ID信息,默認(rèn)為是;
? -q,--quiet=true l false:僅輸出 ID 信息,默認(rèn)為否。
其中,對(duì)輸出結(jié)果進(jìn)行控制的選項(xiàng)如-f,--filter=[ ]、--no-trunc=true | false、-q,--quiet=true I false 等,大部分子命令都支持。
更多子命令選項(xiàng)還可以通過 man docker-images 來查看。
2 .使用 tag 命令添加鏡像標(biāo)簽
為了方便在后續(xù)工作中使用特定鏡像,還可以使用 docker tag 命令來為本地鏡像任意添加新的標(biāo)簽。例如添加一個(gè)新的 myubuntu:latest 鏡像標(biāo)簽:
$ docker tag ubuntu:latest myubuntu:latest
再次使用 docker images 列出本地主機(jī)上鏡像信息,可以看到多了一個(gè)擁有 myubuntu:latest 標(biāo)簽的鏡像。之后,用戶就可以直接使用 myubuntu:latest 來表示這個(gè)鏡像了。
我們可能注意到,這些 myubuntu:latest 鏡像的 ID 跟 ubuntu:latest 完全一致。它們實(shí)際上指向同一個(gè)鏡像文件,只是別名不同而已。docker tag 命令添加的標(biāo)簽實(shí)際上起到了類似鏈接的作用。
3. 使用 inspect 命令查看詳細(xì)信息
使用 docker inspect 命令可以獲取該鏡像的詳細(xì)信息,包括制作者、適應(yīng)架構(gòu)、各層的數(shù)字摘要等,可輸入以下命令:
$docker inspect ubuntu:14.04
返回的是一個(gè) JSON 格式的消息,如果我們只要其中一項(xiàng)內(nèi)容時(shí),可以使用參數(shù)-f 來指定,例如,獲取鏡像的 Architecture:
$docker inspect -f {{".Architecture"}}
amd64
4. 使用 history 命令查看鏡像歷史
既然鏡像文件由多個(gè)層組成,那么怎么知道各個(gè)層的內(nèi)容具體是什么呢?這時(shí)候可以使用 history 子命令,該命令將列出各層的創(chuàng)建信息。
例如,查看 ubuntu:14.04 鏡像的創(chuàng)建過程,可以使用如下命令:
$docker history ubuntu:14.04
3.3 搜尋鏡像
使用 docker search 命令可以搜索遠(yuǎn)端倉庫中共享的鏡像,默認(rèn)搜索官方倉庫中的鏡像。用法為 docker search TERM,支持的參數(shù)主要包括:
? --automated=true I false:僅顯示自動(dòng)創(chuàng)建的鏡像,默認(rèn)為否;
? --no-trunc=true | false:輸出信息不截?cái)囡@示,默認(rèn)為否;
? -s,--stars=X:指定僅顯示評(píng)價(jià)為指定星級(jí)以上的鏡像,默認(rèn)為 0,即輸出所有鏡像。
例如,搜索所有自動(dòng)創(chuàng)建的評(píng)價(jià)為 3+的帶 nginx 關(guān)鍵字的鏡像,如下所示:
$ docker search----automated -s 3 nginx
可以看到返回了很多包含關(guān)鍵字的鏡像,其中包括鏡像名字、描述、星級(jí)(表示該鏡像的受歡迎程度)、是否官方創(chuàng)建、是否自動(dòng)創(chuàng)建等。
默認(rèn)的輸出結(jié)果將按照星級(jí)評(píng)價(jià)進(jìn)行排序。
3.4 刪除鏡像
1. 使用標(biāo)簽刪除鏡像
使用 docker rmi 命令可以刪除鏡像,命令格式為 docker rmi IMAGE [IMAGE…],其中IMAGE 可以為標(biāo)簽或 ID。
例如,要?jiǎng)h除掉 myubuntu:latest 鏡像,可以使用如下命令:
$ docker rmi myubuntu:latest
Untagged:myubuntu:latest
我們可能會(huì)擔(dān)心,本地的 ubuntu:latest 鏡像是否會(huì)受此命令的影響。無需擔(dān)心,當(dāng)同一個(gè)鏡像擁有多個(gè)標(biāo)簽的時(shí)候,docker rmi 命令只是刪除該鏡像多個(gè)標(biāo)簽中的指定標(biāo)簽而已,并不影響鏡像文件。因此上述操作相當(dāng)于只是刪除了鏡像 2fa927b5cdd3 的一個(gè)標(biāo)簽而已。
為保險(xiǎn)起見,再次查看本地的鏡像,發(fā)現(xiàn) ubuntu:latest 鏡像(準(zhǔn)確地說是2fa927b5cdd3 鏡像)仍然存在。但當(dāng)鏡像只剩下一個(gè)標(biāo)簽的時(shí)候就要小心了,此時(shí)再使用 docker rmi 命令會(huì)徹底刪除鏡像。
例如刪除標(biāo)簽為 ubuntu:14.04 的鏡像,由于該鏡像沒有額外的標(biāo)簽指向它,執(zhí)行 docker rmi 命令,它會(huì)刪除這個(gè)鏡像文件的所有層:
$ docker rmi ubuntu:14.04
2. 使用鏡像 ID 刪除鏡像
當(dāng)使用 docker rmi 命令,并且后面跟上鏡像的 ID(也可以是能進(jìn)行區(qū)分的部分 ID 串前綴)時(shí),會(huì)先嘗試刪除所有指向該鏡像的標(biāo)簽,然后刪除該鏡像文件本身。
注意,當(dāng)有該鏡像創(chuàng)建的容器存在時(shí),鏡像文件默認(rèn)是無法被刪除的,例如,先利用 ubuntu:14.04 鏡像創(chuàng)建一個(gè)簡(jiǎn)單的容器來輸出一段話:
$ docker run Ubuntu:14.04 echo 'hello! I am here!'
hello!I am here!
使用 docker ps -a 命令可以看到本機(jī)上存在的所有容器:
$ docker ps -a
可以看到,后臺(tái)存在一個(gè)退出狀態(tài)的容器,是剛基于 ubuntu:14.04 鏡像創(chuàng)建的。
試圖刪除該鏡像,Docker 會(huì)提示有容器正在運(yùn)行,無法刪除:
$ docker rmi Ubuntu:14.04
Error response from daemon:conflict:unable to remove repository reference
"Ubuntu: 14.04" (must force)一 container a21c0840213e is using it's referenced
image 8f1bd21bd25c
如果要想強(qiáng)行刪除鏡像,可以使用 -f 參數(shù)。
$ docker rmi -f ubuntu:14.04
注意,通常并不推薦使用-f 參數(shù)來強(qiáng)制刪除一個(gè)存在容器依賴的鏡像。正確的做法是,先刪除依賴該鏡像的所有容器,再來刪除鏡像。首先刪除容器 a21c0840213e:
$docker rm a21c0840213e
再使用 ID 來刪除鏡像,此時(shí)會(huì)正常打印出刪除的各層信息:
$docker rmi 8f1bd21bd25c
3.5 創(chuàng)建鏡像
創(chuàng)建鏡像的方法主要有三種:基于已有鏡像的容器創(chuàng)建、基于本地模板導(dǎo)入、基于Dockerfile 創(chuàng)建。
1 .基于已有鏡像的容器創(chuàng)建
該方法主要是使用 docker commit 命令。命令格式為 docker commit [OPTIONS]
CONTAINER [REPOSITORY[:TAG]],主要選項(xiàng)包括:
? -a,--author="":作者信息;
? -c,--change=[ ]:提交的時(shí)候執(zhí)行 Dockerfile 指令,包括 CMD | ENTRYPOINT |
ENV l EXPOSE | LABEL | ONBUILD | USER | VOLUME | WORKDIR 等;
? -m,--message="":提交消息;-
? -p,--pause=true:提交時(shí)暫停容器運(yùn)行。
下面將演示如何使用該命令創(chuàng)建一個(gè)新鏡像。首先,啟動(dòng)一個(gè)鏡像,并在其中進(jìn)行修改操作,例如創(chuàng)建一個(gè) test 文件,之后退出:
$ docker run -it Ubuntu:14.04/bin/bash
root@a925cb40b3f0:/# touch test
root@a925Cb40b3f0:/# exit
記住容器的 ID 為 a925cb40b3f0。
此時(shí)該容器跟原 ubuntu:14.04 鏡像相比,已經(jīng)發(fā)生了改變,可以使用 docker commit 命令來提交為一個(gè)新的鏡像。提交時(shí)可以使用 ID 或名稱來指定容器:
$ docker commit -m "Added a new file" -a "Docker Newbee" a925cb40b3f0 test:0.1
9e9C814023bcffc3e67e892a235afe61b02f66a947d2747f724bd317dda02f27
順利的話,會(huì)返回新創(chuàng)建的鏡像的 ID 信息,例如
9e9C814023bcffc3e67e892a235afe61b02f66a947d2747f724bd317dda02f27。此時(shí)查看本地鏡像列表,會(huì)發(fā)現(xiàn)新創(chuàng)建的鏡像已經(jīng)存在了。
$docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
test 0.1 9e9c814023bc 4 seconds ago 188 MB
2 .基于本地模板導(dǎo)入
用戶也可以直接從一個(gè)操作系統(tǒng)模板文件導(dǎo)入一個(gè)鏡像,主要使用 docker import 命令。命令格式為 docker import [OPTIONS] file |URL|-[REPOSITORY [:TAG]]。
要直接導(dǎo)入一個(gè)鏡像,可以使用 OpenVZ 提供的模板來創(chuàng)建,或者用其他已導(dǎo)出的鏡像模板來創(chuàng)建。OPENVZ 模板的下載地址為 http:
//openvz.org/Download/templates/precreated。
例如,下載了 ubuntu -14.04 的模板壓縮包,之后使用以下命令導(dǎo)入:
$cat Ubuntu -14.04 -x86_64 -minimal.tar.gz | docker import -ubuntu:14.04
然后查看新導(dǎo)入的鏡像,會(huì)發(fā)現(xiàn)它已經(jīng)在本地存在了:
$docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
ubuntu 14.04 05ac7cob9383 17 seconds ago 215.5 MB
3.6 存出和載入鏡像
用戶可以使用 docker save 和 docker load 命令來存出和載入鏡像。
1 .存出鏡像
如果要導(dǎo)出鏡像到本地文件,可以使用 docker save 命令。例如,導(dǎo)出本地的ubuntu:14.04 鏡像為文件 ubuntu_14.04.tar,如下所示:

之后,用戶就可以通過復(fù)制 ubuntu_14.04.tar 文件將該鏡像分享給他人。
2 .載入鏡像
可以使用 docker load 將導(dǎo)出的 tar 文件再導(dǎo)入到本地鏡像庫,例如從文件ubuntu_14.04.tar 導(dǎo)入鏡像到本地鏡像列表,如下所示:
$docker load --input ubuntu_14.04.tar
或:
$docker load < ubuntu_14.04.tar
這將導(dǎo)入鏡像及其相關(guān)的元數(shù)據(jù)信息(包括標(biāo)簽等)。導(dǎo)入成功后,可以使用 dockerimages 命令進(jìn)行查看。
3.7 上傳鏡像
可以使用 docker push 命令上傳鏡像到倉庫,默認(rèn)上傳到 Docker Hub 官方倉庫(需要登錄)。命令格式為:
docker push NAME [:TAG] l [REGISTRY_HOST [:REGISTRY_PORT]/ ] NAME [:TAG]
用戶在 Docker Hub 網(wǎng)站注冊(cè)后可以上傳自制的鏡像。例如用戶 user 上傳本地的 test:
latest 鏡像.可以先添加新的標(biāo)簽 user/test:latest,然后用 docker push 命令上傳鏡像:
$docker tag test:latest user/test:latest
$docker push user/test:latest
第一次上傳時(shí),會(huì)提示輸入登錄信息或進(jìn)行注冊(cè)。
第四部分 操作 Docker 容器
容器是 Docker 的另一個(gè)核心概念。簡(jiǎn)單來說,容器是鏡像的一個(gè)運(yùn)行實(shí)例。所不同的是,鏡像是靜態(tài)的只讀文件,而容器帶有運(yùn)行時(shí)需要的可寫文件層。如果認(rèn)為虛擬機(jī)是模擬運(yùn)行的一整套操作系統(tǒng)(包括內(nèi)核、應(yīng)用運(yùn)行態(tài)環(huán)境和其他系統(tǒng)環(huán)境)和跑在上面的應(yīng)用, 那么Docker 容器就是獨(dú)立運(yùn)行的一個(gè)(或一組)應(yīng)用,以及它們必需的運(yùn)行環(huán)境。容器是直接提供應(yīng)用服務(wù)的組件,也是 Docker 實(shí)現(xiàn)快速啟停和高效服務(wù)性能的基礎(chǔ)。
在生產(chǎn)環(huán)境中,因?yàn)槿萜髯陨淼妮p量級(jí)特性,我們推薦使用容器時(shí)在一組容器前引入HA(High Availability,高可靠性)機(jī)制。例如使用 HAProxy 工具來代理容器訪問,這樣在容器出現(xiàn)故障時(shí),可以快速切換到功能正常的容器。此外,建議通過指定合適的容器重啟策略,來自動(dòng)重啟退出的容器。
本部分具體介紹圍繞容器的重要操作,包括創(chuàng)建一個(gè)容器、啟動(dòng)容器、終止一個(gè)容器、進(jìn)入容器內(nèi)執(zhí)行操作、刪除容器和通過導(dǎo)入導(dǎo)出容器來實(shí)現(xiàn)容器遷移等。
4.1 創(chuàng)建容器
從現(xiàn)在開始,可以忘掉虛擬機(jī)。對(duì)容器進(jìn)行操作就跟直接操作應(yīng)用一樣簡(jiǎn)單、快速。
Docker 容器實(shí)在太輕量級(jí)了,用戶可以隨時(shí)創(chuàng)建或刪除容器。
1. 新建容器
可以使用 docker create 命令新建一個(gè)容器,例如:

使用 docker create 命令新建的容器處于停止?fàn)顟B(tài),可以使用 docker start 命令來啟動(dòng)它。
create 命令和后續(xù)的 run 命令支持的選項(xiàng)都十分復(fù)雜,與容器運(yùn)行模式相關(guān)、與容器和環(huán)境配置相關(guān)、與容器資源限制和安全保護(hù)相關(guān)。
2. 啟動(dòng)容器
使用 docker start 命令來啟動(dòng)一個(gè)已經(jīng)創(chuàng)建的容器,例如啟動(dòng)剛創(chuàng)建的 ubuntu 容器:
$ docker start af
af
此時(shí),通過 docker ps 命令可以查看一個(gè)運(yùn)行中的容器:
$docker ps

3. 新建并啟動(dòng)容器
除了創(chuàng)建容器后通過 start 命令來啟動(dòng),也可以直接新建并啟動(dòng)容器。所需要的命令主要為 docker run,等價(jià)于先執(zhí)行 docker create 命令,再執(zhí)行 docker start 命令。
例如,下面的命令輸出一個(gè) "Hello World",之后容器自動(dòng)終止:
$ docker run ubuntu /bin/echo 'Hello world'
Hello world
這跟在本地直接執(zhí)行/bin/echo 'Hello world' 幾乎感覺不出任何區(qū)別。當(dāng)利用 docker run 來創(chuàng)建并啟動(dòng)容器時(shí),Docker 在后臺(tái)運(yùn)行的標(biāo)準(zhǔn)操作包括:
? 檢查本地是否存在指定的鏡像,不存在就從公有倉庫下載;
? 利用鏡像創(chuàng)建一個(gè)容器,并啟動(dòng)該容器;
? 分配一個(gè)文件系統(tǒng)給容器,并在只讀的鏡像層外面掛載一層可讀寫層;
? 從宿主主機(jī)配置的網(wǎng)橋接口中橋接一個(gè)虛擬接口到容器中;
? 從網(wǎng)橋的地址池配置一個(gè) IP 地址給容器;
? 執(zhí)行用戶指定的應(yīng)用程序;
? 執(zhí)行完畢后容器被自動(dòng)終止。
下面的命令啟動(dòng)一個(gè) bash 終端,允許用戶進(jìn)行交互:
$ docker run -it Ubuntu:14.04/bin/bash
root@af8bae53bdd3:/#
其中,-t 選項(xiàng)讓 Docker 分配一個(gè)偽終端(pseudo-tty)并綁定到容器的標(biāo)準(zhǔn)輸入上,-i則讓容器的標(biāo)準(zhǔn)輸入保持打開。更多的命令選項(xiàng)可以通過 man docker -run 命令來查看。
在交互模式下,用戶可以通過所創(chuàng)建的終端來輸入命令,例如:

在容器內(nèi)用 ps 命令查看進(jìn)程,可以看到,只運(yùn)行了 bash 應(yīng)用,并沒有運(yùn)行其他無關(guān)的進(jìn)程。用戶可以按 Ctrl+d 或輸入 exit 命令來退出容器:
root@af8bae53bdd3:/# exit
exit
對(duì)于所創(chuàng)建的 bash 容器,當(dāng)使用 exit 命令退出之后,容器就自動(dòng)處于退出(Exited)狀態(tài)了。這是因?yàn)閷?duì) Docker 容器來說,當(dāng)運(yùn)行的應(yīng)用退出后,容器也就沒有繼續(xù)運(yùn)行的必要了。
某些時(shí)候,執(zhí)行 docker run 會(huì)出錯(cuò),因?yàn)槊顭o法正常執(zhí)行容器會(huì)直接退出,此時(shí)可以查看退出的錯(cuò)誤代碼。
默認(rèn)情況下,常見錯(cuò)誤代碼包括:
? 125:Dockerdaemon 執(zhí)行出錯(cuò),例如指定了不支持的 Docker 命令參數(shù);
? 126:所指定命令無法執(zhí)行,例如權(quán)限出錯(cuò);
? 127:容器內(nèi)命令無法找到。
命令執(zhí)行后出錯(cuò),會(huì)默認(rèn)返回錯(cuò)誤碼。
4. 守護(hù)態(tài)運(yùn)行
更多的時(shí)候,需要讓 Docker 容器在后臺(tái)以守護(hù)態(tài)(Daemonized)形式運(yùn)行。此時(shí),可以通過添加 -d 參數(shù)來實(shí)現(xiàn)。
例如下面的命令會(huì)在后臺(tái)運(yùn)行容器:

容器啟動(dòng)后會(huì)返回一個(gè)唯一的 id,也可以通過 docker ps 命令來查看容器信息:

此時(shí),要獲取容器的輸出信息,可以如下使用 docker logs 命令:
$docker logs ce5
helio world
helio world
hello world
4.2 終止容器
可以使用 docker stop 來終止一個(gè)運(yùn)行中的容器。該命令的格式為 docker stop [-t|--time[=10]] [CONTAINER…]。
首先向容器發(fā)送 SIGTERM 信號(hào),等待一段超時(shí)時(shí)間(默認(rèn)為 10 秒)后,再發(fā)送 SIGKILL 信號(hào)來終止容器:
$docker stop ce5
ce5
此外,當(dāng) Docker 容器中指定的應(yīng)用終結(jié)時(shí),容器也會(huì)自動(dòng)終止。例如對(duì)于上一節(jié)中只啟動(dòng)了一個(gè)終端的容器,用戶通過 exit 命令或 Ctrl+d 來退出終端時(shí),所創(chuàng)建的容器立刻終止,處于 stopped 狀態(tài)。可以用 docker ps -qa 命令看到所有容器的 ID。例如:
$docker ps -qa
ce554267d7a4
d58050081fe3
e812 617b41f6
處于終止?fàn)顟B(tài)的容器,可以通過 docker start 命令來重新啟動(dòng):
$ docker start ce5
此外,docker restart 命令會(huì)將一個(gè)運(yùn)行態(tài)的容器先終止,然后再重新啟動(dòng)它:
$docker restart ce5
4.3 進(jìn)入容器
Docker 從 1.3.0 版本起提供了一個(gè)方便的 exec 命令,可以在容器內(nèi)直接執(zhí)行任意命令。該命令的基本格式為:
docker exec [-d|--detach] [--detach-keys[=[ ]]] [-i|--interactive] [--privileged] [-t |--tty] [-u |--user[=USER]] CONTAINER COMMAND [ARG…] 。
比較重要的參數(shù)有:
? -i,--interactive=true | false:打開標(biāo)準(zhǔn)輸入接受用戶輸入命令,默認(rèn)為
false;
? --privileged=true | false:是否給執(zhí)行命令以高權(quán)限,默認(rèn)為 false;
? -t,--tty= true | false:分配偽終端,默認(rèn)為 false;
? -u,--user=" ":執(zhí)行命令的用戶名或 ID。
例如進(jìn)入到剛創(chuàng)建的容器中,并啟動(dòng)一個(gè) bash:
$docker exec -it 243c32535da7 /bin/bash
root@243c32535da7:/#
可以看到,一個(gè) bash 終端打開了,在不影響容器內(nèi)其他應(yīng)用的前提下,用戶可以很容易與容器進(jìn)行交互。
4.4 刪除容器
可以使用 docker rm 命令來刪除處于終止或退出狀態(tài)的容器,命令格式為 docker rm [-f |--force] [-l |--link] [-v |--volumes] CONTAINER [CONTAINER…] 。
主要支持的選項(xiàng)包括:
? -f,--force=false:是否強(qiáng)行終止并刪除一個(gè)運(yùn)行中的容器;
? -l,--link=false:刪除容器的連接,但保留容器;
? -v,--volumes=false:刪除容器掛載的數(shù)據(jù)卷。
例如,查看處于終止?fàn)顟B(tài)的容器,并刪除:
$docker rm ce554267d7a4
Ce554267d7a4
默認(rèn)情況下,docker rm 命令只能刪除處于終止或退出狀態(tài)的容器,并不能刪除還處于運(yùn)行狀態(tài)的容器。
如果要直接刪除一個(gè)運(yùn)行中的容器,可以添加 -f 參數(shù)。Docker 會(huì)先發(fā)送 SIGKILL 信號(hào)給容器,終止其中的應(yīng)用,之后強(qiáng)行刪除,如下所示:
$ docker rm -f 2ae
2ae
4.5 導(dǎo)入和導(dǎo)出容器
某些時(shí)候,需要將容器從一個(gè)系統(tǒng)遷移到另外一個(gè)系統(tǒng),此時(shí)可以使用 Docker 的導(dǎo)入和導(dǎo)出功能。這也是 Docker 自身提供的一個(gè)重要特性。
1 .導(dǎo)出容器
導(dǎo)出容器是指導(dǎo)出一個(gè)已經(jīng)創(chuàng)建的容器到一個(gè)文件,不管此時(shí)這個(gè)容器是否處于運(yùn)行狀態(tài),可以使用 docker export 命令,該命令的格式為 docker export [-o] --output[=" "]]
CONTAINER。其中,可以通過-o 選項(xiàng)來指定導(dǎo)出的 tar 文件名,也可以直接通過重定向來實(shí)現(xiàn)。
示例:分別導(dǎo)出 ce554267d7a4 容器和 e812617b41f6 容器到文件 test_for_run.tar
文件和 test_for_stop.tar 文件:
$ docker export -o test_for_run.tar ce5
$ls
test_for_run.tar
$ docker export e81 > test_for_stop.tar
$ls
test_for_run.tar test_for_stop.tar
之后,可將導(dǎo)出的 tar 文件傳輸?shù)狡渌麢C(jī)器上,然后再通過導(dǎo)人命令導(dǎo)人到系統(tǒng)中,從而實(shí)現(xiàn)容器的遷移。
2 .導(dǎo)入容器
導(dǎo)出的文件又可以使用 docker import 命令導(dǎo)入變成鏡像,該命令格式為:
docker import [-c I --change[=[ ]]] [-m|--message [=MESSAGE]] file | URL | -[REPOSITORY [:TAG]]
用戶可以通過-c,--change=[ ]選項(xiàng)在導(dǎo)入的同時(shí)執(zhí)行對(duì)容器進(jìn)行修改的 Dockerfile 指令。
下面將導(dǎo)出的 test_for_run.tar 文件導(dǎo)入到系統(tǒng)中:
$ docker import test_for_run.tar - test/Ubuntu:v1.0
之前鏡像章節(jié)中我們?cè)榻B過使用 docker load 命令來導(dǎo)入一個(gè)鏡像文件,與 dockerimport 命令十分類似。
實(shí)際上,既可以使用 docker load 命令來導(dǎo)入鏡像存儲(chǔ)文件到本地鏡像庫,也可以使用docker import 命令來導(dǎo)人一個(gè)容器快照到本地鏡像庫。
這兩者的區(qū)別在于容器快照文件將丟棄所有的歷史記錄和元數(shù)據(jù)信息(即僅保存容器當(dāng)時(shí)的快照狀態(tài)),而鏡像存儲(chǔ)文件將保存完整記錄,體積也更大。此外,從容器快照文件導(dǎo)入時(shí)可以重新指定標(biāo)簽等元數(shù)據(jù)信息。
4.6 實(shí)現(xiàn)容器的網(wǎng)絡(luò)端口映射
下面我們來實(shí)現(xiàn) Docker 容器的網(wǎng)絡(luò)端口映射。我們先創(chuàng)建了一個(gè) python 應(yīng)用的容器。
$ docker run -d -P training/webapp python app.py
fce072cc88cee71b1cdceb57c2821d054a4a59f67da6b416fceb5593f059fc6d
另外,我們可以指定容器綁定的網(wǎng)絡(luò)地址,比如綁定 127.0.0.1。
我們使用 -P 參數(shù)創(chuàng)建一個(gè)容器,使用 docker ps 來看到端口 5000 綁定主機(jī)端口 32768。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTSNAMES
fce072cc88ce training/webapp "python app.py" 4 minutes ago Up 4 minutes 0.0.0.0:32768-
>5000/tcp grave_hopper
我們也可以使用 -p 標(biāo)識(shí)來指定容器端口綁定到主機(jī)端口。
兩種方式的區(qū)別是:
-P :是容器內(nèi)部端口隨機(jī)映射到主機(jī)的高端口。
-p : 是容器內(nèi)部端口綁定到指定的主機(jī)端口。

另外,我們可以指定容器綁定的網(wǎng)絡(luò)地址,比如綁定 127.0.0.1。

這樣我們就可以通過訪問 127.0.0.1:5001 來訪問容器的 5002 端口。
上面的例子中,默認(rèn)都是綁定 tcp 端口,如果要綁定 UPD 端口,可以在端口后面加上/udp。

docker port 命令可以讓我們快捷地查看端口的綁定情況。
$ docker port adoring_stonebraker 5002
127.0.0.1:5001
第五部分 Docker 容器實(shí)現(xiàn) Web 服務(wù)與應(yīng)用
5.1 Docker 容器實(shí)現(xiàn) Apache 服務(wù)
方法一、通過 Dockerfile 構(gòu)建
創(chuàng)建 Dockerfile
首先,創(chuàng)建目錄 apache,用于存放后面的相關(guān)東西。
$ mkdir -p ~/apache/www ~/apache/logs ~/apache/conf
www 目錄將映射為 apache 容器配置的應(yīng)用程序目錄,logs 目錄將映射為 apache 容器的日志目錄,conf 目錄里的配置文件將映射為 apache 容器的配置文件,進(jìn)入創(chuàng)建的 apache 目錄,創(chuàng)建 Dockerfile,內(nèi)容如下:







Dockerfile 文件中 COPY httpd-foreground /usr/local/bin/ 是將當(dāng)前目錄下的 httpd-foreground 拷貝到鏡像里,作為 httpd 服務(wù)的啟動(dòng)腳本,所以我們要在本地創(chuàng)建一個(gè)腳本文件 httpd-foreground
#!/bin/bash
set -e
# Apache gets grumpy about PID files pre-existing
rm -f /usr/local/apache2/logs/httpd.pid
exec httpd -DFOREGROUND
賦予 httpd-foreground 文件可執(zhí)行權(quán)限
$ chmod +x httpd-foreground
通過 Dockerfile 創(chuàng)建一個(gè)鏡像,替換成你自己的名字
$ docker build -t httpd .
創(chuàng)建完成后,我們可以在本地的鏡像列表里查找到剛剛創(chuàng)建的鏡像
$ docker images httpd
REPOSITORY TAG IMAGE ID CREATED SIZE
httpd latest da1536b4ef14 23 seconds ago .... 195.1 MB
方法二、 docker pull httpd
查找 Docker Hub 上的 httpd 鏡像

這里我們拉取官方的鏡像
$ docker pull httpd
等待下載完成后,我們就可以在本地鏡像列表里查到 REPOSITORY 為 httpd 的鏡像。
使用 apache 鏡像
運(yùn)行容器

命令說明:
-p 80:80 :將容器的 80 端口映射到主機(jī)的 80 端口
-v $PWD/www/:/usr/local/apache2/htdocs/ :將主機(jī)中當(dāng)前目錄下的 www 目錄掛載到容器的 /usr/local/apache2/htdocs/
-v $PWD/conf/httpd.conf:/usr/local/apache2/conf/httpd.conf :將主機(jī)中當(dāng)前目錄下的 conf/httpd.conf 文件掛載到容器的/usr/local/apache2/conf/httpd.conf
-v $PWD/logs/:/usr/local/apache2/logs/ :將主機(jī)中當(dāng)前目錄下的 logs 目錄掛載到容器的 /usr/local/apache2/logs/
查看容器啟動(dòng)情況
$ docker ps
CONTAINER ID IMAGE COMMAND ............... PORTS NAMES
79a97f2aac37 httpd "httpd-foreground" ... 0.0.0.0:80->80/tcp sharp_swanson
通過瀏覽器訪問驗(yàn)證 Docker 中的 Apache 服務(wù)是否可訪問。
5.2 Docker 容器實(shí)現(xiàn) Nginx 服務(wù)
方法一、通過 Dockerfile 構(gòu)建
創(chuàng)建 Dockerfile
首先,創(chuàng)建目錄 nginx,用于存放后面的相關(guān)東西。
$ mkdir p ~/nginx/www ~/nginx/logs ~/nginx/conf
www 目錄將映射為 nginx 容器配置的虛擬目錄,logs 目錄將映射為 nginx 容器的日志目錄,conf 目錄里的配置文件將映射為 nginx 容器的配置文件,進(jìn)入創(chuàng)建的 nginx 目錄,創(chuàng)建Dockerfile。



通過 Dockerfile 創(chuàng)建一個(gè)鏡像,替換成你自己的名字。
docker build -t nginx .
創(chuàng)建完成后,我們可以在本地的鏡像列表里查找到剛剛創(chuàng)建的鏡像

方法二、 docker pull nginx
查找 Docker Hub 上的 nginx 鏡像。



這里我們拉取官方的鏡像
$ docker pull nginx
等待下載完成后,我們就可以在本地鏡像列表里查到 REPOSITORY 為 nginx 的鏡像。
使用 nginx 鏡像,運(yùn)行容器

命令說明:
-p 80:80:將容器的 80 端口映射到主機(jī)的 80 端口
--name mynginx:將容器命名為 mynginx
-v $PWD/www:/www:將主機(jī)中當(dāng)前目錄下的 www 掛載到容器的/www
-v $PWD/conf/nginx.conf:/etc/nginx/nginx.conf:將主機(jī)中當(dāng)前目錄下的
nginx.conf 掛載到容器的/etc/nginx/nginx.conf
-v $PWD/logs:/wwwlogs:將主機(jī)中當(dāng)前目錄下的 logs 掛載到容器的/wwwlogs
查看容器啟動(dòng)情況

通過瀏覽器訪問

5.3 Docker 容器實(shí)現(xiàn) Python 應(yīng)用
方法一、通過 Dockerfile 構(gòu)建
創(chuàng)建 Dockerfile
首先,創(chuàng)建目錄 python,用于存放后面的相關(guān)東西。
$ mdkir -p ~/python ~/python/myapp
myapp 目錄將映射為 python 容器配置的應(yīng)用目錄,進(jìn)入創(chuàng)建的 python 目錄,創(chuàng)建 Dockerfile。





通過 Dockerfile 創(chuàng)建一個(gè)鏡像,替換成你自己的名字
$ docker build -t python:3.5 .
創(chuàng)建完成后,我們可以在本地的鏡像列表里查找到剛剛創(chuàng)建的鏡像

方法二、 docker pull python
查找 Docker Hub 上的 python 鏡像



這里我們拉取官方的鏡像,標(biāo)簽為 3.5
$ docker pull python:3.5
等待下載完成后,我們就可以在本地鏡像列表里查到 REPOSITORY 為 python,標(biāo)簽為 3.5 的鏡像。
在~/python/myapp 目錄下創(chuàng)建一個(gè) helloworld.py 文件,代碼如下:
#!/usr/bin/python
print("Hello, World!");
運(yùn)行容器
$ docker run -v $PWD/myapp:/usr/src/myapp -w /usr/src/myapp python:3.5 python
helloworld.py
命令說明:
-v $PWD/myapp:/usr/src/myapp :將主機(jī)中當(dāng)前目錄下的 myapp 掛載到容器的/usr/src/myapp
-w /usr/src/myapp :指定容器的/usr/src/myapp 目錄為工作目錄
python helloworld.py :使用容器的 python 命令來執(zhí)行工作目錄中的 helloworld.py 文件
輸出結(jié)果:
Hello, World!
5.4 Docker 容器實(shí)現(xiàn) MySQL 服務(wù)
方法一、通過 Dockerfile 構(gòu)建
創(chuàng)建 Dockerfile
首先,創(chuàng)建目錄 mysql,用于存放后面的相關(guān)東西。
$ mkdir -p ~/mysql/data ~/mysql/logs ~/mysql/conf
data 目錄將映射為 mysql 容器配置的數(shù)據(jù)文件存放路徑,logs 目錄將映射為 mysql 容器的日志目錄,conf 目錄里的配置文件將映射為 mysql 容器的配置文件。
進(jìn)入創(chuàng)建的 mysql 目錄,創(chuàng)建 Dockerfile
FROM debian:jessie







通過 Dockerfile 創(chuàng)建一個(gè)鏡像,替換成你自己的名字。
$ docker build -t mysql .
創(chuàng)建完成后,我們可以在本地的鏡像列表里查找到剛剛創(chuàng)建的鏡像
$ docker images |grep mysql
mysql .............. 5.6 2c0964ec182a 3 weeks ago 329 MB
方法二、 docker pull mysql
查找 Docker Hub 上的 mysql 鏡像。



這里我們拉取官方的鏡像,標(biāo)簽為 5.6。
$ docker pull mysql:5.6
等待下載完成后,我們就可以在本地鏡像列表里查到 REPOSITORY 為 mysql,標(biāo)簽為 5.6 的鏡像。
運(yùn)行容器:

命令說明:
-p 3306:3306:將容器的 3306 端口映射到主機(jī)的 3306 端口
-v $PWD/conf/my.cnf:/etc/mysql/my.cnf:將主機(jī)當(dāng)前目錄下的 conf/my.cnf 掛載到容
器的/etc/mysql/my.cnf
-v $PWD/logs:/logs:將主機(jī)當(dāng)前目錄下的 logs 目錄掛載到容器的/logs
-v $PWD/data:/mysql_data:將主機(jī)當(dāng)前目錄下的 data 目錄掛載到容器的/mysql_data
-e MYSQL_ROOT_PASSWORD=123456:初始化 root 用戶的密碼
查看容器啟動(dòng)情況:

第六部分 Docker 的運(yùn)行監(jiān)控
在運(yùn)維體系中, 監(jiān)控是非常重要的組成部分。通過監(jiān)控可以實(shí)時(shí)掌握系統(tǒng)運(yùn)行的狀態(tài),對(duì)故障的提前預(yù)警,歷史狀態(tài)的回放等,還可以通過監(jiān)控?cái)?shù)據(jù)為系統(tǒng)的容量規(guī)劃提供輔助決策,為系統(tǒng)性能優(yōu)化提供真實(shí)的用戶行為和體驗(yàn)。
6.1 容器的監(jiān)控方案
傳統(tǒng)的監(jiān)控系統(tǒng)大多是針對(duì)物理機(jī)或虛擬機(jī)設(shè)計(jì)的,物理機(jī)和虛擬機(jī)的特點(diǎn)是靜態(tài)的,生命周期長(zhǎng),一個(gè)環(huán)境安裝配置好后可能幾年都不會(huì)去變動(dòng),那么對(duì)監(jiān)控系統(tǒng)來說,監(jiān)控對(duì)像是靜態(tài)的,對(duì)監(jiān)控對(duì)象做的監(jiān)控配置也是靜態(tài)的,系統(tǒng)上線部署好監(jiān)控后基本就不再需要管理。
雖然物理機(jī)、虛擬機(jī)、容器對(duì)于應(yīng)用進(jìn)程來說都是 host 環(huán)境,容器也是一個(gè)輕量級(jí)的虛擬機(jī), 但容器是動(dòng)態(tài)的, 生命周期短,特別是在微服務(wù)的分布式架構(gòu)下,容器的個(gè)數(shù),IP 地址隨時(shí)可能變化。如果還采用原來傳統(tǒng)監(jiān)控的方案,則會(huì)增加監(jiān)控的復(fù)雜度。比如對(duì)于一個(gè)物理機(jī)或虛擬機(jī),我們只要安裝一個(gè)監(jiān)控工具的 agent 就可以了,但如果在一個(gè)物理機(jī)上運(yùn)行了
無數(shù)個(gè)容器,也采用安裝 agent 的方式,就會(huì)增加 agent 對(duì)資源的占用,但因?yàn)槿萜魇桥c宿主機(jī)是共享資源,所以在容器內(nèi)采集的性能數(shù)據(jù)會(huì)是宿主機(jī)的數(shù)據(jù),那就失去在容器內(nèi)采集數(shù)據(jù)的意義。
而且往往容器的數(shù)量比較多,采集到的數(shù)量也會(huì)非常多,容器可能啟動(dòng)幾分鐘就停止了,那么原來采集的數(shù)據(jù)就沒有價(jià)值了,則會(huì)產(chǎn)生大量這樣沒有價(jià)值的監(jiān)控?cái)?shù)據(jù),維護(hù)起來也會(huì)非常的復(fù)雜。那么應(yīng)該如何對(duì)容器進(jìn)行監(jiān)控呢?答案是在容器外,宿主機(jī)上進(jìn)行監(jiān)控。這樣不僅可以監(jiān)控到每個(gè)容器的資源使用情況,還可以監(jiān)控到容器的狀態(tài),數(shù)量等數(shù)據(jù)。
6.2 單臺(tái)主機(jī)上容器的監(jiān)控
單臺(tái)主機(jī)上容器的監(jiān)控實(shí)現(xiàn)最簡(jiǎn)單的方法就是使用命令 Docker stats,就可以顯示所有容器的資源使用情況,如下輸出:

雖然可以很直觀地看到每個(gè)容器的資源使用情況,但是顯示的只是一個(gè)當(dāng)前值,并不能看到變化趨勢(shì)。而谷歌提供的圖形化工具不僅可以看到每個(gè)容器的資源使用情況,還可以看到主機(jī)的資源使用情況,并且可以設(shè)置顯示一段時(shí)間內(nèi)的趨勢(shì)。以下是 cAdvisor 的面板:


而且 cAdivsor 的安裝非常簡(jiǎn)單,下載一個(gè) cAdvisor 的容器啟動(dòng)后,就可以使用主機(jī) IP 加默認(rèn)端口 8080 進(jìn)行訪問了。
6.3 跨多臺(tái)主機(jī)上容器的監(jiān)控
cAdivsor 雖然能采集到監(jiān)控?cái)?shù)據(jù),也有很好的界面展示,但是并不能顯示跨主機(jī)的監(jiān)控?cái)?shù)據(jù),當(dāng)主機(jī)多的情況,需要有一種集中式的管理方法將數(shù)據(jù)進(jìn)行匯總展示,最經(jīng)典的方案就是cAdvisor+ Influxdb+grafana,可以在每臺(tái)主機(jī)上運(yùn)行一個(gè) cAdvisor 容器負(fù)責(zé)數(shù)據(jù)采集,再將采集后的數(shù)據(jù)都存到時(shí)序型數(shù)據(jù)庫 influxdb 中,再通過圖形展示工具 grafana 定制展示面板。結(jié)構(gòu)如下:

這三個(gè)工具的安裝也非常簡(jiǎn)單,可以直接啟動(dòng)三個(gè)容器快速安裝。如下所示:

在上面的安裝步驟中,先是啟動(dòng) influxdb 容器,然后進(jìn)行到容器內(nèi)部配置一個(gè)數(shù)據(jù)庫給cadvisor 專用,然后再啟動(dòng) cadvisor 容器,容器啟動(dòng)的時(shí)候指定把數(shù)據(jù)存儲(chǔ)到 influxdb 中,最后啟動(dòng) grafana 容器,在展示頁面里配置 grafana 的數(shù)據(jù)源為 influxdb,再定制要展示的數(shù)據(jù),一個(gè)簡(jiǎn)單的跨多主機(jī)的監(jiān)控系統(tǒng)就構(gòu)建成功了。下圖為 Grafana 的界面:

6.4 Kubernetes 上容器的監(jiān)控
在 Kubernetes 的新版本中已經(jīng)集成了 cAdvisor,所以在 Kubernetes 架構(gòu)下,不需要單獨(dú)再去安裝 cAdvisor,可以直接使用節(jié)點(diǎn)的 IP 加默認(rèn)端口 4194 就可以直接訪問 cAdvisor 的監(jiān)控面板。而 Kubernetes 還提供一個(gè)叫 heapster 的組件用于聚合每個(gè) node 上 cAdvisor 采集的數(shù)據(jù),再通過 Kubedash 進(jìn)行展示,結(jié)構(gòu)如下:

在 Kubernetes 的框架里,master 復(fù)雜調(diào)度后有的 node,所以在 heapster 啟動(dòng)時(shí),當(dāng)heapster 配合 k8s 運(yùn)行時(shí),需要指定 kubernetes_master 的地址,heapster 通過 k8s 得到所有 node 節(jié)點(diǎn)地址,然后通過訪問對(duì)應(yīng)的 node ip 和端口號(hào)(10250)來調(diào)用目標(biāo)節(jié)點(diǎn) Kubelet的 HTTP 接口,再由 Kubelet 調(diào)用 cAdvisor 服務(wù)獲取該節(jié)點(diǎn)上所有容器的性能數(shù)據(jù),并依次返回到 heapster 進(jìn)行數(shù)據(jù)聚合。再通過 kubedash 進(jìn)行展示,界面如下:

6.5 Mesos 的監(jiān)控方案
而 Mesos 提供一個(gè) mesos-exporter 工具,用于導(dǎo)出 mesos 集群的監(jiān)控?cái)?shù)據(jù) prometheus,而prometheus 是個(gè)集 db、graph、statistic、alert 于一體的監(jiān)控工具,安裝也非常簡(jiǎn)單,下載包后做些參數(shù)的配置,比如監(jiān)控的對(duì)象就可以運(yùn)行了,默認(rèn)通過 9090 端口訪問。而mesos-exporter 工具只需要在每個(gè) slave 節(jié)點(diǎn)上啟動(dòng)一個(gè)進(jìn)程,再 mesos-exporter 監(jiān)控配置到 prometheus server 的監(jiān)控目標(biāo)中就可以獲取到相關(guān)的數(shù)據(jù)。架構(gòu)如下:

在 Prometheus 的面板上我們可以看到 Prometheus 的監(jiān)控對(duì)象可以為 mesos-export,也可以為 cAdvisor。

下面為 Prometheus 的展示界面:

6.6 性能采集工具的對(duì)比
cAdvisor 可以采集本機(jī)以及容器的資源監(jiān)控?cái)?shù)據(jù),如 CPU、 memory、filesystem and network usage statistics) 。還可以展示 Docker 的信息及主機(jī)上已下載的鏡像情況。因?yàn)閏Advisor 默認(rèn)是將數(shù)據(jù)緩存在內(nèi)存中,在顯示界面上只能顯示 1 分鐘左右的趨勢(shì),所以歷史的數(shù)據(jù)還是不能看到,但它也提供不同的持久化存儲(chǔ)后端,比如 influxdb 等。
Heapster 的前提是使用 cAdvisor 采集每個(gè) node 上主機(jī)和容器資源的使用情況,再將所有 node 上的數(shù)據(jù)進(jìn)行聚合,這樣不僅可以看到整個(gè) Kubernetes 集群的資源情況,還可以分別查看每個(gè) node/namespace 及每個(gè) node/namespace 下 pod 的資源情況。這樣就可以從cluster,node,pod 的各個(gè)層面提供詳細(xì)的資源使用情況。默認(rèn)也是存儲(chǔ)在內(nèi)存中,也提供不同的持久化存儲(chǔ)后端,比如 influxdb 等。
mesos-exporter 的特點(diǎn)是可以采集 task 的監(jiān)控?cái)?shù)據(jù)。mesos 在資源調(diào)度時(shí)是在每個(gè)slave 上啟動(dòng) task executor,這些 task executor 可以是容器,也可以不是容器。而mesos-exporter 則可以從 task 的角度來了解資源的使用情況,而不是一個(gè)一個(gè)沒有關(guān)聯(lián)關(guān)系的容器。
以上從幾個(gè)典型的架構(gòu)上介紹了一些 Docker 的運(yùn)行監(jiān)控,需要根據(jù)生產(chǎn)環(huán)境的特點(diǎn)結(jié)合每個(gè)監(jiān)控產(chǎn)品的優(yōu)勢(shì)來達(dá)到監(jiān)控的目的。比如 Grafana 的圖表展示能力強(qiáng),但是沒有告警的功能,那么可以結(jié)合 Prometheus 在數(shù)據(jù)處理能力改善數(shù)據(jù)分析的展示。
猜您喜歡:
等你著陸!【GAN生成對(duì)抗網(wǎng)絡(luò)】知識(shí)星球!
附下載 | 經(jīng)典《Think Python》中文版
附下載 | 《Pytorch模型訓(xùn)練實(shí)用教程》
附下載 | 最新2020李沐《動(dòng)手學(xué)深度學(xué)習(xí)》
附下載 | 《可解釋的機(jī)器學(xué)習(xí)》中文版
附下載 |《TensorFlow 2.0 深度學(xué)習(xí)算法實(shí)戰(zhàn)》
