<kbd id="5sdj3"></kbd>
<th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>

    Docker 容器技術使用指南

    共 30553字,需瀏覽 62分鐘

     ·

    2021-05-19 06:03

    點擊“程序員面試吧”,選擇“星標??”

    點擊文末“閱讀原文”解鎖資料!

    目錄

    第一部分 Docker 容器技術基礎及其應用場景介紹

    1.1 Docker 的基本概念
    1.2 為什么使用 Docker
    1.3 Docker 體系結構簡介
    1.4 Docker 容器技術的應用場景

    第二部分 核心概念與安裝配置

    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 進入容器
    4.4 刪除容器
    4.5 導入和導出容器
    4.6 實現(xiàn)容器的網(wǎng)絡端口映射

    第五部分 Docker 容器實現(xiàn) Web 服務與應用

    5.1 Docker 容器實現(xiàn) Apache 服務
    5.2 Docker 容器實現(xiàn) Nginx 服務
    5.3 Docker 容器實現(xiàn) Python 應用
    5.4 Docker 容器實現(xiàn) MySQL 服務

    第六部分 Docker 的運行監(jiān)控

    6.1 容器的監(jiān)控方案
    6.2 單臺主機上容器的監(jiān)控
    6.3 跨多臺主機上容器的監(jiān)控
    6.4 Kubernetes 上容器的監(jiān)控
    6.5 Mesos 的監(jiān)控方案
    6.6 性能采集工具的對比

    第一部分 Docker 容器技術基礎及其應用場景介紹

    1.1 Docker 的基本概念

    Docker 容器是資源分割和調(diào)度的基本單位,封裝整個服務的運行時環(huán)境,用于構建、發(fā)布和運行分布式應用的一個框架。它是一個跨平臺、可移植并且簡單易用的容器解決方案。Docker 的源代碼托管在 GitHub 上,基于 Go 語言開發(fā)并遵從 Apache 2.0 協(xié)議。

    Docker 容器可以快速自動化地部署應用,并通過操作系統(tǒng)內(nèi)核技術(namespaces、 cgroups等)為容器提供資源隔離與安全保障。Docker 作為輕量級的虛擬化方式,實現(xiàn)了 PaaS 平臺的高效部署、運行和維護。

    1.2 為什么使用 Docker

    • 持續(xù)部署與測試

    Docker 消除了線上線下的環(huán)境差異,保證了應用生命周期的環(huán)境一致性和標準化。開發(fā)人員使用鏡像實現(xiàn)標準開發(fā)環(huán)境的構建,開發(fā)完成后通過封裝著完整環(huán)境和應用的鏡像進行遷移,由此,測試和運維人員可以直接部署軟件鏡像來進行測試和發(fā)布,大大簡化了持續(xù)集成、測試和發(fā)布的過程。

    Docker 是革命性的,它重新定義了軟件開發(fā)、測試、交付和部署的流程。我們交付的東西不再只是代碼、配置文件、數(shù)據(jù)庫定義等,而是整個應用服務及其運行環(huán)境。

    • 優(yōu)異的跨平臺性

    Docker 在原有 Linux 容器的基礎上進行大膽革新,為容器設定了一 整套標準化的配置方法,將應用及其依賴的運行環(huán)境打包成鏡像。Docker 是可移植(或者說跨平臺)的,可以在各種主流操作系統(tǒng)上使用。Java 可以做到“一次編譯,到處運行”,而 Docker 可以 “構建一次,在各平臺上運行”(Build once,run anywhere)。越來越多的云平臺都支持 Docker,用戶再也無需擔心受到云平臺的捆綁,同時也讓應用多平臺混合部署成為可能。

    • 高資源利用率與隔離

    Docker 容器沒有管理程序的額外開銷,與底層共享操作系統(tǒng),性能更加優(yōu)良,系統(tǒng)負載更低,在同等條件下可以運行更多的應用實例,可以更充分地利 用系統(tǒng)資源。同時,Docker 擁有不錯的資源隔離與限制能力,可以精確地對應用分配 CPU、 內(nèi)存等資源,保證了應用間不會相互影響。Docker 是輕量級虛擬化技術。與傳統(tǒng)的 VM 相比,它更輕量,啟動速度更快,單臺硬件上可以同時跑成百上千個容器,所以非常適合在業(yè)務高峰期通過啟動大量容器進行橫向擴展。Docker 容器技術的直接虛擬化不僅在技術方面使 CPU 利用率得到顯著提升,還因 80:20 法則可在業(yè)務上更大程度發(fā)揮 CPU 利用率,真正體現(xiàn)了虛擬化精髓。

    • 環(huán)境標準化和版本控制

    可以使用 Git 等工具對 Docker 鏡像進行版本控制,相比基于代碼的版本控制來說,能夠?qū)φ麄€應用運行環(huán)境實現(xiàn)版本控制,一旦出現(xiàn)故障可以快速回滾。相比以前的虛擬機鏡像,Docker 壓縮和備份速度更快,鏡像啟動也像啟動一個普通進程一樣快速。

    • 應用鏡像倉庫

    Docker 官方構建了一個鏡像倉庫,組織和管理形式類似于 GitHub,其上 已累積了成千上萬的鏡像。因為 Docker 的跨平臺適配性,相當于為用戶提供了一個非常 有用的應用商店,所有人都可以自由地下載微服務組件,這為開發(fā)者提供了巨大便利。

    1.3 Docker 體系結構簡介

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

    1.4 Docker 容器技術的應用場景

    一般認為 Docker 技術有以下 8 個主要的應用場景,參見下圖:

    • 應用場景 1:簡化配置

    這是 Docker 公司宣傳的 Docker 的主要使用場景。Docker 能將運行環(huán)境和配置放在代碼中然后部署,同一個 Docker 的配置可以在不同的環(huán)境中使用,這樣就降低了硬件要求和應用環(huán)境之間耦合度。

    • 應用場景 2:代碼流水線(Code Pipeline)管理

    代碼從開發(fā)者的機器到最終在生產(chǎn)環(huán)境上的部署,需要經(jīng)過很多的中間環(huán)境。而每一個中間環(huán)境都有微小的差別,Docker 給應用提供了一個從開發(fā)到上線均一致的環(huán)境,讓代碼的流水線變得簡單不少。

    • 應用場景 3:提高開發(fā)效率

    Docker 能提升開發(fā)者的開發(fā)效率。不同的開發(fā)環(huán)境中,Docker 都可以把兩件事做好,一是可以在開發(fā)環(huán)境、生產(chǎn)環(huán)境之間直接遷移,二是可以讓我們快速搭建開發(fā)環(huán)境。開發(fā)環(huán)境的機器通常內(nèi)存比較小,之前使用虛擬的時候,我們經(jīng)常需要為開發(fā)環(huán)境的機器加內(nèi)存,而現(xiàn)在Docker 可以輕易的讓幾十個服務在 Docker 中跑起來。

    • 應用場景 4:隔離應用

    有很多種原因會讓我們選擇在一個機器上運行不同的應用,Docker 非常適合在較低的成本下實現(xiàn)多種應用的隔離。

    • 應用場景 5:整合服務器

    Docker 隔離應用的能力使得 Docker 可以整合多個服務器以降低成本。由于沒有操作系統(tǒng)的內(nèi)存占用,以及能在多個實例之間共享沒有使用的內(nèi)存,Docker 可以比虛擬機提供更好的服務器整合解決方案。通常數(shù)據(jù)中心的服務器資源利用率只有 30%,通過使用 Docker 并進行有效的資源分配可以大幅提高服務器資源的利用率。

    • 應用場景 6:調(diào)試能力

    Docker 提供了很多的工具,包括可以為容器設置檢查點、設置版本和查看兩個容器之間的差別,這些特性可以幫助調(diào)試 Bug。

    • 應用場景 7:多租戶環(huán)境

    另外一個 Docker 的使用場景是在多租戶的應用中,它可以避免關鍵應用的重寫。我們一個特別的關于這個場景的例子是為物聯(lián)網(wǎng)的應用開發(fā)一個快速、易用的多租戶環(huán)境。這種多租戶的基本代碼非常復雜,很難處理,重新規(guī)劃這樣一個應用不但消耗時間,也浪費金錢。

    使用 Docker,可以為每一個租戶的應用層的多個實例創(chuàng)建隔離的環(huán)境,這不僅簡單而且成本低廉,當然這一切得益于 Docker 環(huán)境的啟動速度和其高效的 diff 命令。

    • 應用場景 8:快速部署

    在虛擬機之前,購入部署新的硬件資源需要消耗幾天的時間。虛擬化技術(Virtualization)將這個時間縮短到了分鐘級別。而 Docker 通過為進程僅僅創(chuàng)建一個容器而無需啟動一個操作系統(tǒng),再次將這個過程縮短到了秒級。這正是 Google 和 Facebook 都看重的特性。我們可以創(chuàng) 建銷毀 Docker 容器而無需擔心重新啟動帶來的開銷。

    第二部分 核心概念與安裝配置

    本部分首先介紹 Docker 的三大核心概念。

    • 鏡像(Image)

    • 容器(Container)

    • 倉庫(Repository)

    只有理解了這三個核心概念,才能順利地理解 Docker 容器的整個生命周期。隨后將介紹如何在常見的操作系統(tǒng)平臺上安裝 Docker,包括 Redhat Linux、Windows、Centos 等主流操作系統(tǒng)平臺。

    2.1 核心概念

    Docker 的大部分操作都圍繞著它的三大核心概念——鏡像、容器和倉庫而展開。因此,準確把握這三大核心概念對于掌握 Docker 技術尤為重要。

    • Docker  鏡像

    Docker 鏡像類似于虛擬機鏡像,可以將它理解為一個只讀的模板。例如,一個鏡像可以包含一個基本的操作系統(tǒng)環(huán)境,里面僅安裝了 Apache 應用程序(或用戶需要的其他軟件)。可以把它稱為一個Apache 鏡像。

    鏡像是創(chuàng)建 Docker 容器的基礎。通過版本管理和增量的文件系統(tǒng),Docker 提供了一套十分簡單的機制來創(chuàng)建和更新現(xiàn)有的鏡像,用戶甚至可以從網(wǎng)上下載一個已經(jīng)做好的應用鏡像, 并直接使用 。

    • Docker 容器

    Docker 容器類似于一個輕量級的沙箱,Docker 利用容器來運行和隔離應用。容器是從鏡像創(chuàng)建的應用運行實例??梢詫⑵鋯印㈤_始、停止、刪除,而這些容器都是彼此相互隔離的、互不可見的。

    可以把容器看做是一個簡易版的 Linux 系統(tǒng)環(huán)境(包括 root 用戶權限、進程空間、用戶空間和網(wǎng)絡空間等)以及運行在其中的應用程序打包而成的盒子。

    • Docker  倉庫

    Docker 倉庫類似于代碼倉庫,它是 Docker 集中存放鏡像文件的場所。

    有時候會看到有資料將 Docker 倉庫和倉庫注冊服務器(Registry)混為一談,并不嚴格區(qū)分。實際上,倉庫注冊服務器是存放倉庫的地方,其上往往存放著多個倉庫。每個倉庫集中存放某一類鏡像,往往包括多個鏡像文件,通過不同的標簽(tag)來進行區(qū)分。例如存放 ubuntu操作系統(tǒng)鏡像的倉庫稱為 ubuntu 倉庫,其中可能包括 14.04、12.04 等不同版本的鏡像。

    根據(jù)所存儲的鏡像公開分享與否,Docker 倉庫可以分為公開倉庫(Public)和私有倉庫(Private)兩種形式。目前,最大的公開倉庫是官方提供的 Docker Hub,其中存放了數(shù)量龐大的鏡像供用戶下載。國內(nèi)不少云服務提供商(如時速云、阿里云等)也提供了倉庫的本地源,可以提供穩(wěn)定的國內(nèi)訪問。

    當然,用戶如果不希望公開分享自己的鏡像文件,Docker 也支持用戶在本地網(wǎng)絡內(nèi)創(chuàng)建一個只能自己訪問的私有倉庫。當用戶創(chuàng)建了自己的鏡像之后就可以使用 push 命令將它上傳到指定的公有或者私有倉庫。這樣用戶下次在另外一臺機器上使用該鏡像時,只需要將其從倉庫上 pull 下來就可以了。

    可以看出,Docker 利用倉庫管理鏡像的設計理念與 Git 非常相似,實際上在理念設計上借鑒了 Git 的很多優(yōu)秀思想。

    2.2 安裝Docker

    Docker 在主流的操作系統(tǒng)和云平臺上都可以使用,包括 Linux 操作系統(tǒng)(如 ubuntu、Debian、CentOS、Redhat 等)、MacOS 操作系統(tǒng)和 Windows 操作系統(tǒng),以及 AWS 等云平臺。

    用戶可以訪問 Docker 官網(wǎng)的 Get Docker(https://www.docker.com/products/overview)頁面,查看獲取 Docker 的方式,以及 Docker 支持的平臺類型,如圖 2-2 所示。

    在 Get Docker 頁面,我們可以看到目前 Docker 支持 Docker Platform、Docker Hub、Docker Cloud 和 Docker DataCenter。

    • Docker Platform:支持在桌面系統(tǒng)或云平臺安裝 Docker;

    • DockerHub:官方提供的云托管服務,可以提供公有或私有的鏡像倉庫;

    • DockerCloud:官方提供的容器云服務,可以完成容器的部署與管理,可以完整地支持容器化項目,還有 CI、CD 功能;

    • Docker DataCenter:提供企業(yè)級的簡單安全彈性的容器集群編排和管理。

    推薦盡量使用 Linux 操作系統(tǒng)來運行 Docker,因為目前 Linux 操作系統(tǒng)對 Docker的支持是原生的,使用體驗最好。

    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 運行的是發(fā)行版內(nèi)核。那就僅支持通過 extras 渠道或者 EPEL 包來安裝Docker。如果我們打算在非發(fā)行版本的內(nèi)核上運行 Docker ,內(nèi)核的改動可能會導致出錯

    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)核補丁, 因此 RHEL 的內(nèi)核版本應為 2.6.32-431 或者更高。

    Docker 已經(jīng)包含在 RHEL 的 EPEL 源中。該源是 Extra Packages for Enterprise Linux (EPEL) 的一個額外包,社區(qū)中正在努力創(chuàng)建和維護相關鏡像。

    首先,你需要安裝 EPEL 鏡像源,在 EPEL 中已經(jīng)提供了 docker-io 包。

    下一步,我們將要在我們的主機中安裝 Docker,也就是 docker-io 包:

    $ sudo yum -y install docker-io

    更新 docker-io 包:

    $ sudo yum -y update docker-io

    現(xiàn)在 Docker 已經(jīng)安裝好了,我們來啟動 docker 進程:

    $ sudo service docker start

    設置開機啟動:

    $ sudo chkconfig docker on

    現(xiàn)在,讓我們確認 Docker 是否正常工作:

    $ sudo docker run -i -t fedora /bin/bash

    現(xiàn)在 Docker 已經(jīng)安裝好了,讓我們來啟動 Docker 進程

    $ sudo service docker start

    如果我們想要開機啟動 Docker ,我們需要執(zhí)行如下的命令:

    $ sudo chkconfig docker on

    現(xiàn)在測試一下是否正常工作:

    $ sudo docker run -i -t fedora /bin/bash

    注意: 如果運行的時候提示一個 Cannot start container 的錯誤,錯誤中提到了SELINUX 或者 權限不足。我們需要更新 SELINUX 規(guī)則。可以使用 sudo yum upgrade selinux-policy 然后重啟。

    2.2.2  在 Windows  上安裝 Docker

    安裝

    • 下載最新版本的 Docker for Windows Installer

    • 運行安裝文件,它將會安裝 virtualbox、 MSYS-git boot2docker Linux 鏡像和 Boot2Docker的管理工具。

    • 從桌面上或者 Program Files 中找到 Boot2Docker for Windows,運行 Boot2Docker Start 腳本。這個腳本會要求你輸入 ssh 密鑰密碼 - 可以簡單點(但是起碼看起來比較安全) ,然后只需要按[Enter]按鈕即可。

    • Boot2Docker Start 將啟動一個 Unix shell 來配置和管理運行在虛擬主機中的 Docker,運行 docker version 來查看它是否正常工作。

    2.運行 Docker

    注意:如果使用的是一個遠程的 Docker 進程,像 Boot2docker ,就不需要像前邊的文檔實例中那樣在輸入 Docker 命令之前輸入 sudo。

    Boot2docker start 將會自動啟動一個 shell 命令框并配置好環(huán)境變量,以便我們可以馬上使用 Docker :

    讓我們嘗試運行 hello-world 例子。運行:

    $ docker run hello-world

    這將會下載一個非常小的 hello-world 鏡像,并且打印出 Hello from Docker 的信息。

    3.使用 Windows 的命令行( ( cmd.exe )  來管理運行 Docker

    啟動一個 Windows 命令行(cmd.exe) ,運行 Boot2docker 命令,這需要 Windows PATH 環(huán)境變量中包含了 ssh.exe。因此我們需要將安裝的 Git 的 bin 目錄 (其中包含了 ssh.exe)配置到我們的 %PATH% 環(huán)境變量中,運行如下命令:

    set PATH=%PATH%;"c:\Program Files (x86)\Git\bin"

    現(xiàn)在,我們可以運行 boot2docker start 命令來啟動 Boot2docker 虛擬機。(如果有虛擬主機不存在的錯誤提示,需要運行 boot2docker init 命令) 。復制上邊的指令到 cmd.exe 來設置 windows 控制臺的環(huán)境變量,然后就可以運行 docker 命令了,譬如 docker ps :

    4.PowerShell 中使用  Docker

    啟動 PowerShell,需要將 ssh.exe 添加到 PATH 中。

    $Env:Path = "${Env:Path};c:\Program Files (x86)\Git\bin"

    之后,運行 boot2docker start 命令行,它會打印出 PowerShell 命令,這些命令是用來設置環(huán)境變量來連接運行在虛擬機中 Docker 的。運行這些命令,然后就可以運行 docker 命令了,譬如 docker ps :

    提示:可以使用 boot2docker shellinit | Invoke-Expression 來設置環(huán)境變量來代替復制粘貼 Powershell 命令。

    2.2.3  在 CentOS  環(huán)境下安裝 Docker

    Docker 支持以下的 CentOS 版本:

    • CentOS 7 (64-bit)

    • CentOS 6.5 (64-bit)或更高的版本

    前提條件

    Docker 運行在 CentOS 7 上,要求系統(tǒng)為 64 位、系統(tǒng)內(nèi)核版本為 3.10 以上。

    Docker 運行在 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 ,查看本頁面的前提條件來驗證你的 CentOS 版本是否支持 Docker 。

    通過  uname - - r 命令查看你當前的內(nèi)核版本

    uname -r 3.10.0-327.el7.x86_64


    安裝 Docker

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

    yum -y install docker


    安裝完成。

    啟動 Docker 后臺服務

    service docker start


    測試運行 hello-world

    docker run hello-world


    由于本地沒有 hello-world 這個鏡像,所以會下載一個 hello-world 的鏡像,并在容器內(nèi)運行。

    使用腳本安裝 Docker

    1、使用  sudo  或  root  權限登錄 Centos。

    2、確保 yum 包更新到最新。

    $ sudo yum update

    3、執(zhí)行 Docker 安裝腳本。

    $ curl -fsSL https://get.docker.com/ | sh

    執(zhí)行這個腳本會添加  docker.repo  源并安裝 Docker。

    4、啟動 Docker 進程。

    $ sudo service docker start

    5、驗證  docker  是否安裝成功并在容器中執(zhí)行一個測試的鏡像。

    $ sudo docker run hello-world

    到此,docker 在 CentOS 系統(tǒng)的安裝完成。

    第三部分 使用 Docker 鏡像

    鏡像(image)是 Docker 三大核心概念中最為重要的,自 Docker 誕生之日起“鏡像”就是相關社區(qū)最為熱門的關鍵詞。

    Docker 運行容器前需要本地存在對應的鏡像,如果鏡像沒保存在本地,Docker 會嘗試先從默認鏡像倉庫下載(默認使用:Docker Hub 公共注冊服務器中的倉庫),用戶也可以通過配置,使用自定義的鏡像倉庫。

    本部分將介紹圍繞鏡像這一核心概念的具體操作,包括如何使用 pull 命令從 Docker Hub 倉庫中下載鏡像到本地,如何查看本地已有的鏡像信息和管理鏡像標簽,如何在遠端倉庫使用 search 命令進行搜索和過濾,如何刪除鏡像標簽和鏡像文件,如何創(chuàng)建用戶定制的鏡像并且保存為外部文件。最后,還介紹如何往 Docker Hub 倉庫中推送自己的鏡像。

    3.1 獲取鏡像

    鏡像是運行容器的前提,官方的 Docker Hub 網(wǎng)站已經(jīng)提供了數(shù)十萬個鏡像供大家開放下載。

    可以使用 docker pull 命令直接從 Docker Hub 鏡像源來下載鏡像。該命令的格式為docker pull NAME[:TAG]。其中,NAME 是鏡像倉庫的名稱(用來區(qū)分鏡像),TAG 是鏡像的標簽(往往用來表示版本信息)。通常情況下,描述一個鏡像需要包括‘名稱+標簽’信息。

    例如,獲取一個 Ubuntu 14.04 系統(tǒng)的基礎鏡像可以使用如下的命令:

    對于 Docker 鏡像來說,如果不顯式指定 TAG,則默認會選擇 latest 標簽,這會下載倉庫中最新版本的鏡像。

    下面的例子將從 Docker Hub 的 Ubuntu 倉庫下載一個最新的 Ubuntu 操作系統(tǒng)的鏡像。

    該命令實際上下載的就是 ubuntu: latest 鏡像。

    下載過程中可以看出,鏡像文件一般由若干層(layer)組成,6c953ac5d795 這樣的串是層的唯一 id(實際上完整的 id 包括 256 比特,由 64 個十六進制字符組成)。使用 docker pull 命令下載時會獲取并輸出鏡像的各層信息。當不同的鏡像包括相同的層時,本地僅存儲層的一份內(nèi)容,減小了需要的存儲空問。

    我們可能會想到,在使用不同的鏡像倉庫服務器的情況下,可能會出現(xiàn)按鏡像重名的情況。

    嚴格地講,鏡像的倉庫名稱中還應該添加倉庫地址(即 registry,注冊服務器)作為前綴,只是我們默認使用的是 Docker Hub 服務,該前綴可以忽略。

    例如,docker pull Ubuntu:14.04 命令相當于 docker pull registry.hub.docker.com/Ubuntu:14.04 命令,即從默認的注冊服務器 Docker Hub Registry 中的 ubuntu 倉庫來下載標記為 14.04 的鏡像。

    如果從非官方的倉庫下載,則需要在倉庫名稱前指定完整的倉庫地址。例如從網(wǎng)易蜂巢的鏡像源來下載 ubuntu:14.04 鏡像,可以使用如下命令,此時下載的鏡像名稱 hub.c.163.com/public/Ubuntu:14.04:

    $ docker pull hub.c.163.com/public/Ubuntu:14.04

    pull 子命令支持的選項主要包括:

    -a,--all- tags=true| false:是否獲取倉庫中的所有鏡像,默認為否。

    下載鏡像到本地后,即可隨時使用該鏡像了,例如利用該鏡像創(chuàng)建一個容器,在其中運行 bash 應用,執(zhí)行 ping localhost 命令:

    3.2 查看鏡像信息

    1. 使用 images 命令列出鏡像

    使用 docker images 命令可以列出本地主機上已有鏡像的基本信息。例

    如,下面的命令列出了上一小節(jié)中下載的鏡像信息:

    在列出的信息中,可以看到以下幾個字段信息。

    • 來自于哪個倉庫,比如 ubuntu 倉庫用來保存 ubuntu 系列的基礎鏡像;

    • 鏡像的標簽信息,比如 14.04、latest 用來標注不同的版本信息。標簽只是標記,并不能標識鏡像內(nèi)容;

    • 鏡像的 ID(唯一標識鏡像),如 ubuntu:latest 和 ubuntu:16.04 鏡像的 ID 都是 2fa927b5cdd3,說明它們目前實際上指向同一個鏡像;

    • 創(chuàng)建時間,說明鏡像最后的更新時間;

    • 鏡像大小,優(yōu)秀的鏡像往往體積都較小。

    其中鏡像的 ID 信息十分重要,它唯一標識了鏡像。在使用鏡像 ID 的時候,一般可以使用該 ID 的前若干個字符組成的可區(qū)分串來替代完整的 ID。

    TAG 信息用來標記來自同一個倉庫的不同鏡像。例如 ubunm 倉庫中有多個鏡像,通過TAG 信息來區(qū)分發(fā)行版本,包括 10.04、12.04、12.10、13.04、14.04、16.04 等標簽:

    鏡像大小信息只是表示該鏡像的邏輯體積大小,實際上由于相同的鏡像層本地只會存儲一份,物理上占用的存儲空間會小于各鏡像的邏輯體積之和。

    images 子命令主要支持如下選項,用戶可以自行進行嘗試。

    • -a,--all=true | false:列出所有的鏡像文件(包括臨時文件),默認為否;

    • --digests=true I false:列出鏡像的數(shù)字摘要值,默認為否;

    • -f,---filter=[ ]:過濾列出的鏡像,如 dangling=true 只顯示沒有被使用的鏡像;

    也可指定帶有特定標注的鏡像等;

    • --format="TEMPLATE":控制輸出格式,如.ID 代表 ID 信息,Repository 代表倉庫信息等;

    • --no-trunc=true l false:對輸出結果中太長的部分是否進行截斷,如鏡像的 ID信息,默認為是;

    • -q,--quiet=true l false:僅輸出 ID 信息,默認為否。

    其中,對輸出結果進行控制的選項如-f,--filter=[ ]、--no-trunc=true | false、-q,--quiet=true I false 等,大部分子命令都支持。

    更多子命令選項還可以通過 man docker-images 來查看。

    2.使用 tag  命令添加鏡像標簽

    為了方便在后續(xù)工作中使用特定鏡像,還可以使用 docker tag 命令來為本地鏡像任意添加新的標簽。例如添加一個新的 myubuntu:latest 鏡像標簽:

    $ docker tag ubuntu:latest myubuntu:latest

    再次使用 docker images 列出本地主機上鏡像信息,可以看到多了一個擁有 myubuntu:latest 標簽的鏡像。之后,用戶就可以直接使用 myubuntu:latest 來表示這個鏡像了。

    我們可能注意到,這些 myubuntu:latest 鏡像的 ID 跟 ubuntu:latest 完全一致。它們實際上指向同一個鏡像文件,只是別名不同而已。docker tag 命令添加的標簽實際上起到了類似鏈接的作用。

    3. 使用 inspect 命令查看詳細信息

    使用 docker inspect 命令可以獲取該鏡像的詳細信息,包括制作者、適應架構、各層的數(shù)字摘要等,可輸入以下命令:

    $docker inspect ubuntu:14.04

    返回的是一個 JSON 格式的消息,如果我們只要其中一項內(nèi)容時,可以使用參數(shù)-f 來指定,例如,獲取鏡像的 Architecture:

    $docker inspect -f {{".Architecture"}}
    amd64

    4. 使用 history 命令查看鏡像歷史

    既然鏡像文件由多個層組成,那么怎么知道各個層的內(nèi)容具體是什么呢?這時候可以使用 history 子命令,該命令將列出各層的創(chuàng)建信息。

    例如,查看 ubuntu:14.04 鏡像的創(chuàng)建過程,可以使用如下命令:

    $docker history ubuntu:14.04

    3.3 搜尋鏡像

    使用 docker search 命令可以搜索遠端倉庫中共享的鏡像,默認搜索官方倉庫中的鏡像。用法為 docker search TERM,支持的參數(shù)主要包括:

    • --automated=true I false:僅顯示自動創(chuàng)建的鏡像,默認為否;

    • --no-trunc=true | false:輸出信息不截斷顯示,默認為否;

    • -s,--stars=X:指定僅顯示評價為指定星級以上的鏡像,默認為 0,即輸出所有鏡像。

    例如,搜索所有自動創(chuàng)建的評價為 3+的帶 nginx 關鍵字的鏡像,如下所示:

    $ docker search----automated -s 3 nginx

    可以看到返回了很多包含關鍵字的鏡像,其中包括鏡像名字、描述、星級(表示該鏡像的受歡迎程度)、是否官方創(chuàng)建、是否自動創(chuàng)建等。

    默認的輸出結果將按照星級評價進行排序。

    3.4 刪除鏡像

    1. 使用標簽刪除鏡像

    使用 docker rmi 命令可以刪除鏡像,命令格式為 docker rmi IMAGE [IMAGE…],其中IMAGE 可以為標簽或 ID。

    例如,要刪除掉 myubuntu:latest 鏡像,可以使用如下命令:

    $ docker rmi myubuntu:latest

    Untagged:myubuntu:latest

    我們可能會擔心,本地的 ubuntu:latest 鏡像是否會受此命令的影響。無需擔心,當同一個鏡像擁有多個標簽的時候,docker rmi 命令只是刪除該鏡像多個標簽中的指定標簽而已,并不影響鏡像文件。因此上述操作相當于只是刪除了鏡像 2fa927b5cdd3 的一個標簽而已。

    為保險起見,再次查看本地的鏡像,發(fā)現(xiàn) ubuntu:latest 鏡像(準確地說是2fa927b5cdd3 鏡像)仍然存在。但當鏡像只剩下一個標簽的時候就要小心了,此時再使用 docker rmi 命令會徹底刪除鏡像。

    例如刪除標簽為 ubuntu:14.04 的鏡像,由于該鏡像沒有額外的標簽指向它,執(zhí)行 docker rmi 命令,它會刪除這個鏡像文件的所有層:

    $ docker rmi ubuntu:14.04

    2. 使用鏡像 ID 刪除鏡像

    當使用 docker rmi 命令,并且后面跟上鏡像的 ID(也可以是能進行區(qū)分的部分 ID 串前綴)時,會先嘗試刪除所有指向該鏡像的標簽,然后刪除該鏡像文件本身。

    注意,當有該鏡像創(chuàng)建的容器存在時,鏡像文件默認是無法被刪除的,例如,先利用 ubuntu:14.04 鏡像創(chuàng)建一個簡單的容器來輸出一段話:

    $ docker run Ubuntu:14.04 echo 'hello! I am here!'

    hello!I am here!

    使用 docker ps -a 命令可以看到本機上存在的所有容器:

    $ docker ps -a

    可以看到,后臺存在一個退出狀態(tài)的容器,是剛基于 ubuntu:14.04 鏡像創(chuàng)建的。

    試圖刪除該鏡像,Docker 會提示有容器正在運行,無法刪除:

    $ 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

    如果要想強行刪除鏡像,可以使用 -f 參數(shù)。

    $ docker rmi -f ubuntu:14.04

    注意,通常并不推薦使用-f 參數(shù)來強制刪除一個存在容器依賴的鏡像。正確的做法是,先刪除依賴該鏡像的所有容器,再來刪除鏡像。首先刪除容器 a21c0840213e:

    $docker rm a21c0840213e

    再使用 ID 來刪除鏡像,此時會正常打印出刪除的各層信息:

    $docker rmi 8f1bd21bd25c

    3.5 創(chuàng)建鏡像

    創(chuàng)建鏡像的方法主要有三種:基于已有鏡像的容器創(chuàng)建、基于本地模板導入、基于Dockerfile 創(chuàng)建。

    1.基于已有鏡像的容器創(chuàng)建

    該方法主要是使用 docker commit 命令。命令格式為 docker commit [OPTIONS]

    CONTAINER [REPOSITORY[:TAG]],主要選項包括:

    • -a,--author="":作者信息;

    • -c,--change=[ ]:提交的時候執(zhí)行 Dockerfile 指令,包括 CMD | ENTRYPOINT |
      ENV l EXPOSE | LABEL | ONBUILD | USER | VOLUME | WORKDIR 等;

    • -m,--message="":提交消息;-

    • -p,--pause=true:提交時暫停容器運行。

    下面將演示如何使用該命令創(chuàng)建一個新鏡像。首先,啟動一個鏡像,并在其中進行修改操作,例如創(chuàng)建一個 test 文件,之后退出:

    $ docker run -it Ubuntu:14.04/bin/bash

    root@a925cb40b3f0:/# touch test

    root@a925Cb40b3f0:/# exit

    記住容器的 ID 為 a925cb40b3f0。

    此時該容器跟原 ubuntu:14.04 鏡像相比,已經(jīng)發(fā)生了改變,可以使用 docker commit 命令來提交為一個新的鏡像。提交時可以使用 ID 或名稱來指定容器:

    $ docker commit -m "Added a new file" -a "Docker Newbee" a925cb40b3f0 test:0.1

    9e9C814023bcffc3e67e892a235afe61b02f66a947d2747f724bd317dda02f27

    順利的話,會返回新創(chuàng)建的鏡像的 ID 信息,例如9e9C814023bcffc3e67e892a235afe61b02f66a947d2747f724bd317dda02f27。此時查看本地鏡像列表,會發(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.基于本地模板導入

    用戶也可以直接從一個操作系統(tǒng)模板文件導入一個鏡像,主要使用 docker import 命令。命令格式為 docker import [OPTIONS] file |URL|-[REPOSITORY [:TAG]]。

    要直接導入一個鏡像,可以使用 OpenVZ 提供的模板來創(chuàng)建,或者用其他已導出的鏡像模板來創(chuàng)建。OPENVZ 模板的下載地址為 http://openvz.org/Download/templates/precreated。

    例如,下載了 ubuntu -14.04 的模板壓縮包,之后使用以下命令導入:

    $cat Ubuntu -14.04 -x86_64 -minimal.tar.gz | docker import -ubuntu:14.04

    然后查看新導入的鏡像,會發(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.存出鏡像

    如果要導出鏡像到本地文件,可以使用 docker save 命令。例如,導出本地的ubuntu:14.04 鏡像為文件 ubuntu_14.04.tar,如下所示:

    之后,用戶就可以通過復制 ubuntu_14.04.tar 文件將該鏡像分享給他人。

    2.載入鏡像

    可以使用 docker load 將導出的 tar 文件再導入到本地鏡像庫,例如從文件ubuntu_14.04.tar 導入鏡像到本地鏡像列表,如下所示:

    $docker load --input ubuntu_14.04.tar

    或:

    $docker load < ubuntu_14.04.tar

    這將導入鏡像及其相關的元數(shù)據(jù)信息(包括標簽等)。導入成功后,可以使用 dockerimages 命令進行查看。

    3.7 上傳鏡像

    可以使用 docker push 命令上傳鏡像到倉庫,默認上傳到 Docker Hub 官方倉庫(需要登錄)。命令格式為:

    docker push NAME [:TAG] l [REGISTRY_HOST [:REGISTRY_PORT]/ ] NAME [:TAG]

    用戶在 Docker Hub 網(wǎng)站注冊后可以上傳自制的鏡像。例如用戶 user 上傳本地的 test:

    latest 鏡像.可以先添加新的標簽 user/test:latest,然后用 docker push 命令上傳鏡像:

    $docker tag test:latest user/test:latest

    $docker push user/test:latest

    第一次上傳時,會提示輸入登錄信息或進行注冊。

    第四部分 操作 Docker 容器

    容器是 Docker 的另一個核心概念。簡單來說,容器是鏡像的一個運行實例。所不同的是,鏡像是靜態(tài)的只讀文件,而容器帶有運行時需要的可寫文件層。如果認為虛擬機是模擬運行的一整套操作系統(tǒng)(包括內(nèi)核、應用運行態(tài)環(huán)境和其他系統(tǒng)環(huán)境)和跑在上面的應用, 那么Docker 容器就是獨立運行的一個(或一組)應用,以及它們必需的運行環(huán)境。容器是直接提供應用服務的組件,也是 Docker 實現(xiàn)快速啟停和高效服務性能的基礎。

    在生產(chǎn)環(huán)境中,因為容器自身的輕量級特性,我們推薦使用容器時在一組容器前引入HA(High Availability,高可靠性)機制。例如使用 HAProxy 工具來代理容器訪問,這樣在容器出現(xiàn)故障時,可以快速切換到功能正常的容器。此外,建議通過指定合適的容器重啟策略,來自動重啟退出的容器。

    本部分具體介紹圍繞容器的重要操作,包括創(chuàng)建一個容器、啟動容器、終止一個容器、進入容器內(nèi)執(zhí)行操作、刪除容器和通過導入導出容器來實現(xiàn)容器遷移等。

    4.1 創(chuàng)建容器

    從現(xiàn)在開始,可以忘掉虛擬機。對容器進行操作就跟直接操作應用一樣簡單、快速。

    Docker 容器實在太輕量級了,用戶可以隨時創(chuàng)建或刪除容器。

    1.新建容器

    可以使用 docker create 命令新建一個容器,例如:

    使用 docker create 命令新建的容器處于停止狀態(tài),可以使用 docker start 命令來啟動它。

    create 命令和后續(xù)的 run 命令支持的選項都十分復雜,與容器運行模式相關、與容器和環(huán)境配置相關、與容器資源限制和安全保護相關。

    2. 啟動容器

    使用 docker start 命令來啟動一個已經(jīng)創(chuàng)建的容器,例如啟動剛創(chuàng)建的 ubuntu 容器:

    $ docker start af

    af

    此時,通過 docker ps 命令可以查看一個運行中的容器:

    $docker ps

    3. 新建并啟動容器

    除了創(chuàng)建容器后通過 start 命令來啟動,也可以直接新建并啟動容器。所需要的命令主要為 docker run,等價于先執(zhí)行 docker create 命令,再執(zhí)行 docker start 命令。

    例如,下面的命令輸出一個 "Hello World",之后容器自動終止:

    $ docker run ubuntu /bin/echo 'Hello world'

    Hello world

    這跟在本地直接執(zhí)行/bin/echo 'Hello world' 幾乎感覺不出任何區(qū)別。當利用 docker run 來創(chuàng)建并啟動容器時,Docker 在后臺運行的標準操作包括:

    • 檢查本地是否存在指定的鏡像,不存在就從公有倉庫下載;

    • 利用鏡像創(chuàng)建一個容器,并啟動該容器;

    • 分配一個文件系統(tǒng)給容器,并在只讀的鏡像層外面掛載一層可讀寫層;

    • 從宿主主機配置的網(wǎng)橋接口中橋接一個虛擬接口到容器中;

    • 從網(wǎng)橋的地址池配置一個 IP 地址給容器;

    • 執(zhí)行用戶指定的應用程序;

    • 執(zhí)行完畢后容器被自動終止。

    下面的命令啟動一個 bash 終端,允許用戶進行交互:

    $ docker run -it Ubuntu:14.04/bin/bash

    root@af8bae53bdd3:/#

    其中,-t 選項讓 Docker 分配一個偽終端(pseudo-tty)并綁定到容器的標準輸入上,-i則讓容器的標準輸入保持打開。更多的命令選項可以通過 man docker -run 命令來查看。

    在交互模式下,用戶可以通過所創(chuàng)建的終端來輸入命令,例如:

    在容器內(nèi)用 ps 命令查看進程,可以看到,只運行了 bash 應用,并沒有運行其他無關的進程。用戶可以按 Ctrl+d 或輸入 exit 命令來退出容器:

    root@af8bae53bdd3:/# exit

    exit

    對于所創(chuàng)建的 bash 容器,當使用 exit 命令退出之后,容器就自動處于退出(Exited)狀態(tài)了。這是因為對 Docker 容器來說,當運行的應用退出后,容器也就沒有繼續(xù)運行的必要了。

    某些時候,執(zhí)行 docker run 會出錯,因為命令無法正常執(zhí)行容器會直接退出,此時可以查看退出的錯誤代碼。

    默認情況下,常見錯誤代碼包括:

    • 125:Dockerdaemon 執(zhí)行出錯,例如指定了不支持的 Docker 命令參數(shù);

    • 126:所指定命令無法執(zhí)行,例如權限出錯;

    • 127:容器內(nèi)命令無法找到。

    命令執(zhí)行后出錯,會默認返回錯誤碼。

    4. 守護態(tài)運行

    更多的時候,需要讓 Docker 容器在后臺以守護態(tài)(Daemonized)形式運行。此時,可以通過添加 -d 參數(shù)來實現(xiàn)。

    例如下面的命令會在后臺運行容器:

    容器啟動后會返回一個唯一的 id,也可以通過 docker ps 命令來查看容器信息:

    此時,要獲取容器的輸出信息,可以如下使用 docker logs 命令:

    $docker logs ce5

    helio world

    helio world

    hello world

    4.2 終止容器

    可以使用 docker stop 來終止一個運行中的容器。該命令的格式為 docker stop [-t|--time[=10]] [CONTAINER…]。

    首先向容器發(fā)送 SIGTERM 信號,等待一段超時時間(默認為 10 秒)后,再發(fā)送 SIGKILL 信號來終止容器:

    $docker stop ce5

    ce5

    此外,當 Docker 容器中指定的應用終結時,容器也會自動終止。例如對于上一節(jié)中只啟動了一個終端的容器,用戶通過 exit 命令或 Ctrl+d 來退出終端時,所創(chuàng)建的容器立刻終止,處于 stopped 狀態(tài)??梢杂?docker ps -qa 命令看到所有容器的 ID。例如:

    $docker ps -qa

    ce554267d7a4

    d58050081fe3

    e812 617b41f6

    處于終止狀態(tài)的容器,可以通過 docker start 命令來重新啟動:

    $ docker start ce5

    此外,docker restart 命令會將一個運行態(tài)的容器先終止,然后再重新啟動它:

    $docker restart ce5

    4.3 進入容器

    Docker 從 1.3.0 版本起提供了一個方便的 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:打開標準輸入接受用戶輸入命令,默認為false;

    • --privileged=true | false:是否給執(zhí)行命令以高權限,默認為 false;

    • -t,--tty= true | false:分配偽終端,默認為 false;

    • -u,--user=" ":執(zhí)行命令的用戶名或 ID。

    例如進入到剛創(chuàng)建的容器中,并啟動一個 bash:

    $docker exec -it 243c32535da7 /bin/bash

    root@243c32535da7:/#

    可以看到,一個 bash 終端打開了,在不影響容器內(nèi)其他應用的前提下,用戶可以很容易與容器進行交互。

    4.4 刪除容器

    可以使用 docker rm 命令來刪除處于終止或退出狀態(tài)的容器,命令格式為 docker rm [-f |--force] [-l |--link] [-v |--volumes] CONTAINER [CONTAINER…] 。

    主要支持的選項包括:

    • -f,--force=false:是否強行終止并刪除一個運行中的容器;

    • -l,--link=false:刪除容器的連接,但保留容器;

    • -v,--volumes=false:刪除容器掛載的數(shù)據(jù)卷。

    例如,查看處于終止狀態(tài)的容器,并刪除:

    $docker rm ce554267d7a4

    Ce554267d7a4

    默認情況下,docker rm 命令只能刪除處于終止或退出狀態(tài)的容器,并不能刪除還處于運行狀態(tài)的容器。

    如果要直接刪除一個運行中的容器,可以添加 -f 參數(shù)。Docker 會先發(fā)送 SIGKILL 信號給容器,終止其中的應用,之后強行刪除,如下所示:

    $ docker rm -f 2ae

    2ae

    4.5 導入和導出容器

    某些時候,需要將容器從一個系統(tǒng)遷移到另外一個系統(tǒng),此時可以使用 Docker 的導入和導出功能。這也是 Docker 自身提供的一個重要特性。

    1.導出容器

    導出容器是指導出一個已經(jīng)創(chuàng)建的容器到一個文件,不管此時這個容器是否處于運行狀態(tài),可以使用 docker export 命令,該命令的格式為 docker export [-o] --output[=" "]]

    CONTAINER。其中,可以通過-o 選項來指定導出的 tar 文件名,也可以直接通過重定向來實現(xiàn)。

    示例:分別導出 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

    之后,可將導出的 tar 文件傳輸?shù)狡渌麢C器上,然后再通過導人命令導人到系統(tǒng)中,從而實現(xiàn)容器的遷移。

    2.導入容器

    導出的文件又可以使用 docker import 命令導入變成鏡像,該命令格式為:

    docker import [-c I --change[=[ ]]] [-m|--message [=MESSAGE]] file | URL | -[REPOSITORY [:TAG]]

    用戶可以通過-c,--change=[ ]選項在導入的同時執(zhí)行對容器進行修改的 Dockerfile 指令。

    下面將導出的 test_for_run.tar 文件導入到系統(tǒng)中:

    $ docker import test_for_run.tar - test/Ubuntu:v1.0

    之前鏡像章節(jié)中我們曾介紹過使用 docker load 命令來導入一個鏡像文件,與 dockerimport 命令十分類似。

    實際上,既可以使用 docker load 命令來導入鏡像存儲文件到本地鏡像庫,也可以使用docker import 命令來導人一個容器快照到本地鏡像庫。

    這兩者的區(qū)別在于容器快照文件將丟棄所有的歷史記錄和元數(shù)據(jù)信息(即僅保存容器當時的快照狀態(tài)),而鏡像存儲文件將保存完整記錄,體積也更大。此外,從容器快照文件導入時可以重新指定標簽等元數(shù)據(jù)信息。

    4.6 實現(xiàn)容器的網(wǎng)絡端口映射

    下面我們來實現(xiàn) Docker 容器的網(wǎng)絡端口映射。我們先創(chuàng)建了一個 python 應用的容器。

    $ docker run -d -P training/webapp python app.py

    fce072cc88cee71b1cdceb57c2821d054a4a59f67da6b416fceb5593f059fc6d

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

    我們使用 -P 參數(shù)創(chuàng)建一個容器,使用 docker ps 來看到端口 5000 綁定主機端口 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 標識來指定容器端口綁定到主機端口。

    兩種方式的區(qū)別是:

    -P :是容器內(nèi)部端口隨機映射到主機的高端口。

    -p : 是容器內(nèi)部端口綁定到指定的主機端口。

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

    這樣我們就可以通過訪問 127.0.0.1:5001 來訪問容器的 5002 端口。

    上面的例子中,默認都是綁定 tcp 端口,如果要綁定 UPD 端口,可以在端口后面加上/udp。

    docker port 命令可以讓我們快捷地查看端口的綁定情況。

    $ docker port adoring_stonebraker 5002

    127.0.0.1:5001

    第五部分 Docker 容器實現(xiàn) Web 服務與應用

    5.1 Docker 容器實現(xiàn) Apache 服務

    方法一、通過 Dockerfile  構建

    創(chuàng)建 Dockerfile

    首先,創(chuàng)建目錄 apache,用于存放后面的相關東西。

    $ mkdir -p ~/apache/www ~/apache/logs ~/apache/conf

    www 目錄將映射為 apache 容器配置的應用程序目錄,logs 目錄將映射為 apache 容器的日志目錄,conf 目錄里的配置文件將映射為 apache 容器的配置文件,進入創(chuàng)建的 apache 目錄,創(chuàng)建 Dockerfile,內(nèi)容如下:

    Dockerfile 文件中 COPY httpd-foreground /usr/local/bin/ 是將當前目錄下的 httpd-foreground 拷貝到鏡像里,作為 httpd 服務的啟動腳本,所以我們要在本地創(chuàng)建一個腳本文件 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í)行權限

    $ chmod +x httpd-foreground

    通過 Dockerfile 創(chuàng)建一個鏡像,替換成你自己的名字

    $ 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 鏡像

    運行容器

    命令說明:

    -p 80:80 :將容器的 80 端口映射到主機的 80 端口

    -v $PWD/www/:/usr/local/apache2/htdocs/ :將主機中當前目錄下的 www 目錄掛載到容器的 /usr/local/apache2/htdocs/

    -v $PWD/conf/httpd.conf:/usr/local/apache2/conf/httpd.conf :將主機中當前目錄下的 conf/httpd.conf 文件掛載到容器的/usr/local/apache2/conf/httpd.conf

    -v $PWD/logs/:/usr/local/apache2/logs/ :將主機中當前目錄下的 logs 目錄掛載到容器的 /usr/local/apache2/logs/

    查看容器啟動情況

    $ docker ps

    CONTAINER ID IMAGE COMMAND ............... PORTS NAMES

    79a97f2aac37 httpd "httpd-foreground" ... 0.0.0.0:80->80/tcp sharp_swanson

    通過瀏覽器訪問驗證 Docker 中的 Apache 服務是否可訪問。

    5.2 Docker 容器實現(xiàn) Nginx 服務

    方法一、通過 Dockerfile  構建

    創(chuàng)建 Dockerfile

    首先,創(chuàng)建目錄 nginx,用于存放后面的相關東西。

    $ mkdir p ~/nginx/www ~/nginx/logs ~/nginx/conf

    www 目錄將映射為 nginx 容器配置的虛擬目錄,logs 目錄將映射為 nginx 容器的日志目錄,conf 目錄里的配置文件將映射為 nginx 容器的配置文件,進入創(chuàng)建的 nginx 目錄,創(chuàng)建Dockerfile。

    通過 Dockerfile 創(chuàng)建一個鏡像,替換成你自己的名字。

    docker build -t nginx .

    創(chuàng)建完成后,我們可以在本地的鏡像列表里查找到剛剛創(chuàng)建的鏡像

    方法二、 docker pull nginx

    查找 Docker Hub 上的 nginx 鏡像。

    這里我們拉取官方的鏡像

    $ docker pull nginx

    等待下載完成后,我們就可以在本地鏡像列表里查到 REPOSITORY 為 nginx 的鏡像。

    使用 nginx 鏡像,運行容器

    命令說明:

    -p 80:80:將容器的 80 端口映射到主機的 80 端口

    --name mynginx:將容器命名為 mynginx

    -v $PWD/www:/www:將主機中當前目錄下的 www 掛載到容器的/www

    -v $PWD/conf/nginx.conf:/etc/nginx/nginx.conf:將主機中當前目錄下的

    nginx.conf 掛載到容器的/etc/nginx/nginx.conf

    -v $PWD/logs:/wwwlogs:將主機中當前目錄下的 logs 掛載到容器的/wwwlogs

    查看容器啟動情況


    通過瀏覽器訪問

    5.3 Docker 容器實現(xiàn) Python 應用

    方法一、通過 Dockerfile  構建

    創(chuàng)建 Dockerfile

    首先,創(chuàng)建目錄 python,用于存放后面的相關東西。

    $ mdkir -p ~/python ~/python/myapp

    myapp 目錄將映射為 python 容器配置的應用目錄,進入創(chuàng)建的 python 目錄,創(chuàng)建 Dockerfile。

    通過 Dockerfile 創(chuàng)建一個鏡像,替換成你自己的名字

    $ docker build -t python:3.5 .

    創(chuàng)建完成后,我們可以在本地的鏡像列表里查找到剛剛創(chuàng)建的鏡像

    方法二、 docker pull python

    查找 Docker Hub 上的 python 鏡像

    這里我們拉取官方的鏡像,標簽為 3.5

    $ docker pull python:3.5

    等待下載完成后,我們就可以在本地鏡像列表里查到 REPOSITORY 為 python,標簽為 3.5 的鏡像。

    在~/python/myapp 目錄下創(chuàng)建一個 helloworld.py 文件,代碼如下:

    #!/usr/bin/python

    print("Hello, World!");

    運行容器

    $ docker run -v $PWD/myapp:/usr/src/myapp -w /usr/src/myapp python:3.5 python

    helloworld.py

    命令說明:

    • -v $PWD/myapp:/usr/src/myapp :將主機中當前目錄下的 myapp 掛載到容器的/usr/src/myapp

    • -w /usr/src/myapp :指定容器的/usr/src/myapp 目錄為工作目錄

    python helloworld.py :使用容器的 python 命令來執(zhí)行工作目錄中的 helloworld.py 文件

    輸出結果:

    Hello, World!

    5.4 Docker 容器實現(xiàn) MySQL 服務

    方法一、通過 Dockerfile  構建

    創(chuàng)建 Dockerfile

    首先,創(chuàng)建目錄 mysql,用于存放后面的相關東西。

    $ mkdir -p ~/mysql/data ~/mysql/logs ~/mysql/conf

    data 目錄將映射為 mysql 容器配置的數(shù)據(jù)文件存放路徑,logs 目錄將映射為 mysql 容器的日志目錄,conf 目錄里的配置文件將映射為 mysql 容器的配置文件。

    進入創(chuàng)建的 mysql 目錄,創(chuàng)建 Dockerfile

    FROM debian:jessie

    通過 Dockerfile 創(chuàng)建一個鏡像,替換成你自己的名字。

    $ 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 鏡像。

    這里我們拉取官方的鏡像,標簽為 5.6。

    $ docker pull mysql:5.6

    等待下載完成后,我們就可以在本地鏡像列表里查到 REPOSITORY 為 mysql,標簽為 5.6 的鏡像。

    運行容器:

    命令說明:

    -p 3306:3306:將容器的 3306 端口映射到主機的 3306 端口

    -v $PWD/conf/my.cnf:/etc/mysql/my.cnf:將主機當前目錄下的 conf/my.cnf 掛載到容

    器的/etc/mysql/my.cnf

    -v $PWD/logs:/logs:將主機當前目錄下的 logs 目錄掛載到容器的/logs

    -v $PWD/data:/mysql_data:將主機當前目錄下的 data 目錄掛載到容器的/mysql_data

    -e MYSQL_ROOT_PASSWORD=123456:初始化 root 用戶的密碼

    查看容器啟動情況:

    第六部分 Docker 的運行監(jiān)控

    在運維體系中, 監(jiān)控是非常重要的組成部分。通過監(jiān)控可以實時掌握系統(tǒng)運行的狀態(tài),對故障的提前預警,歷史狀態(tài)的回放等,還可以通過監(jiān)控數(shù)據(jù)為系統(tǒng)的容量規(guī)劃提供輔助決策,為系統(tǒng)性能優(yōu)化提供真實的用戶行為和體驗。

    6.1 容器的監(jiān)控方案

    傳統(tǒng)的監(jiān)控系統(tǒng)大多是針對物理機或虛擬機設計的,物理機和虛擬機的特點是靜態(tài)的,生命周期長,一個環(huán)境安裝配置好后可能幾年都不會去變動,那么對監(jiān)控系統(tǒng)來說,監(jiān)控對像是靜態(tài)的,對監(jiān)控對象做的監(jiān)控配置也是靜態(tài)的,系統(tǒng)上線部署好監(jiān)控后基本就不再需要管理。

    雖然物理機、虛擬機、容器對于應用進程來說都是 host 環(huán)境,容器也是一個輕量級的虛擬機, 但容器是動態(tài)的, 生命周期短,特別是在微服務的分布式架構下,容器的個數(shù),IP 地址隨時可能變化。如果還采用原來傳統(tǒng)監(jiān)控的方案,則會增加監(jiān)控的復雜度。比如對于一個物理機或虛擬機,我們只要安裝一個監(jiān)控工具的 agent 就可以了,但如果在一個物理機上運行了

    無數(shù)個容器,也采用安裝 agent 的方式,就會增加 agent 對資源的占用,但因為容器是與宿主機是共享資源,所以在容器內(nèi)采集的性能數(shù)據(jù)會是宿主機的數(shù)據(jù),那就失去在容器內(nèi)采集數(shù)據(jù)的意義。

    而且往往容器的數(shù)量比較多,采集到的數(shù)量也會非常多,容器可能啟動幾分鐘就停止了,那么原來采集的數(shù)據(jù)就沒有價值了,則會產(chǎn)生大量這樣沒有價值的監(jiān)控數(shù)據(jù),維護起來也會非常的復雜。那么應該如何對容器進行監(jiān)控呢?答案是在容器外,宿主機上進行監(jiān)控。這樣不僅可以監(jiān)控到每個容器的資源使用情況,還可以監(jiān)控到容器的狀態(tài),數(shù)量等數(shù)據(jù)。

    6.2 單臺主機上容器的監(jiān)控

    單臺主機上容器的監(jiān)控實現(xiàn)最簡單的方法就是使用命令 Docker stats,就可以顯示所有容器的資源使用情況,如下輸出:

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


    而且 cAdivsor 的安裝非常簡單,下載一個 cAdvisor 的容器啟動后,就可以使用主機 IP 加默認端口 8080 進行訪問了。

    6.3 跨多臺主機上容器的監(jiān)控

    cAdivsor 雖然能采集到監(jiān)控數(shù)據(jù),也有很好的界面展示,但是并不能顯示跨主機的監(jiān)控數(shù)據(jù),當主機多的情況,需要有一種集中式的管理方法將數(shù)據(jù)進行匯總展示,最經(jīng)典的方案就是cAdvisor+ Influxdb+grafana,可以在每臺主機上運行一個 cAdvisor 容器負責數(shù)據(jù)采集,再將采集后的數(shù)據(jù)都存到時序型數(shù)據(jù)庫 influxdb 中,再通過圖形展示工具 grafana 定制展示面板。結構如下:

    這三個工具的安裝也非常簡單,可以直接啟動三個容器快速安裝。如下所示:

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

    6.4 Kubernetes 上容器的監(jiān)控

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

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

    6.5 Mesos 的監(jiān)控方案

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

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

    下面為 Prometheus 的展示界面:

    6.6 性能采集工具的對比

    cAdvisor 可以采集本機以及容器的資源監(jiān)控數(shù)據(jù),如 CPU、 memory、filesystem and network usage statistics) 。還可以展示 Docker 的信息及主機上已下載的鏡像情況。因為cAdvisor 默認是將數(shù)據(jù)緩存在內(nèi)存中,在顯示界面上只能顯示 1 分鐘左右的趨勢,所以歷史的數(shù)據(jù)還是不能看到,但它也提供不同的持久化存儲后端,比如 influxdb 等。

    Heapster 的前提是使用 cAdvisor 采集每個 node 上主機和容器資源的使用情況,再將所有 node 上的數(shù)據(jù)進行聚合,這樣不僅可以看到整個 Kubernetes 集群的資源情況,還可以分別查看每個 node/namespace 及每個 node/namespace 下 pod 的資源情況。這樣就可以從cluster,node,pod 的各個層面提供詳細的資源使用情況。默認也是存儲在內(nèi)存中,也提供不同的持久化存儲后端,比如 influxdb 等。

    mesos-exporter 的特點是可以采集 task 的監(jiān)控數(shù)據(jù)。mesos 在資源調(diào)度時是在每個slave 上啟動 task executor,這些 task executor 可以是容器,也可以不是容器。而mesos-exporter 則可以從 task 的角度來了解資源的使用情況,而不是一個一個沒有關聯(lián)關系的容器。

    以上從幾個典型的架構上介紹了一些 Docker 的運行監(jiān)控,需要根據(jù)生產(chǎn)環(huán)境的特點結合每個監(jiān)控產(chǎn)品的優(yōu)勢來達到監(jiān)控的目的。比如 Grafana 的圖表展示能力強,但是沒有告警的功能,那么可以結合 Prometheus 在數(shù)據(jù)處理能力改善數(shù)據(jù)分析的展示。

    轉(zhuǎn)自:杰哥的IT之旅(侵權刪)


    點擊左下角查看更多

    瀏覽 92
    點贊
    評論
    收藏
    分享

    手機掃一掃分享

    分享
    舉報
    評論
    圖片
    表情
    推薦
    點贊
    評論
    收藏
    分享

    手機掃一掃分享

    分享
    舉報

    <kbd id="5sdj3"></kbd>
    <th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>
    被错误羁押6千天男子申请国赔1911万 | 艹逼在线观看 | 69视频网在线观看 | 国产乱伦视频网站 | 爱爱午夜福利 |