跳到主要內容
黯羽輕揚每天積累一點點

Docker 簡介

免費2017-12-23#Tool#Docker入门#Docker教程#Docker node#Docker centos#Docker introduction

輕量級虛擬化方案

一。目標

Bring Portability, Security, And Efficiency To Your Traditional Applications Without Changing Application Code

不改變原始碼就能讓傳統應用程式獲得可移植性、安全性和高成本效益

二。特性

Docker 提供了在寬鬆隔離環境(稱之為容器)中打包和執行應用程式的能力,以及用來管理容器生命週期的工具和平台

P.S.Docker 是用 Go 編寫的

混合雲可移植性

把應用程式的原始碼及其依賴項一起打包到輕量級的獨立容器,容器解決了works on my machine的問題,如圖:

(圖片來自 Digging Into the "Works On My Machine" Problem

這樣應用程式就能正常地在新環境裡跑起來,而不用考慮環境之間的差異。打包好之後,用一條簡單的 Docker 命令就能輕易地把容器部署到任何環境。能夠快速啟用雲遷移,加快技術更新週期或突然遷移到(公有)雲

提升應用程式安全性

把現有的應用程式打包到 Docker 容器中,無需修改原始碼就能獲得 Docker 內建的安全特性。Docker 提供了容器隔離,通過限制性的配置,減少應用程式的攻擊面,並允許設定合適的資源配額,節省主機資源

另外,Docker 還對容器應用程式的創建、掃描、簽名、共享和部署提供了安全的供應鏈。比如安全掃描能夠提供所有依賴項的公開漏洞清單,在定期報告中會通知 Docker 管理員修復相關的已知公開漏洞。還能對容器做數位簽章,通過啟用 Docker 集群驗證來保證應用程式的安全傳輸

CapEx(資本性支出)和 OpEx(運營成本)效益

Docker 能夠簡化資源調配、部署和更新等操作,遷移到 Docker 容器後可以節省部署時間

在結構上,Docker 容器共享底層作業系統核心,資源消耗要比虛擬機少,相對輕量。通過容器隔離來防止應用程式衝突,這樣 IT 管理員就能提高現有基礎結構的負載密度,優化現有虛擬機和服務器的利用率

P.S. 不需要管理程式的額外負載,而是直接在主機的內核中運行,更節省資源,比虛擬機輕量,甚至可以在虛擬機環境運行 Docker

DevOps

DevOps (a clipped compound of "development" and "operations") is a software engineering culture and practice that aims at unifying software development (Dev) and software operation (Ops). The main characteristic of the DevOps movement is to strongly advocate automation and monitoring at all steps of software construction, from integration, testing, releasing to deployment and infrastructure management. DevOps aims at shorter development cycles, increased deployment frequency, more dependable releases, in close alignment with business objectives.

一種軟體工程文化和實踐,想要統一開發和操作(測試、運維),進一步縮短產品發布週期,提高效率,同時通過自動化和監控來保證可靠性

容器技術是 DevOps 中的重要一環,如下圖:

(圖片來自 Red Hat OpenShift V3 Overview and Deep Dive

正如前面提到的,把原始碼和依賴項打包到容器,能夠簡化資源調配、部署、更新等一系列運維操作,達到 You build it, you run it,減少從開發到發布之間的不確定環節

P.S. 關於 DevOps 的更多信息,請查看 DevOps 的前世今生

三。結構及概念

一種 C/S 架構,Client 發出指令,Server(守護進程)接收並執行相應操作,管理容器和映像。Server 可以與 Client 位於同一物理機器上,也可以位於另一個遠程機器,通過 REST API 通信(要麼通過 UNIX socket 進程間通信,要麼通過網絡遠程通信)

Docker 守護進程

守護進程(dockerd)監聽 Docker API 請求,並管理 Docker 對象,比如映像(image)、容器(container)、網絡和目錄(volume,文件系統中的概念,卷)。此外,守護進程還能與其它守護進程通信以管理 Docker 服務

Docker 客戶端

客戶端(docker)是 Docker 用戶與 Docker 交互的基本方式,比如使用 docker run 命令,客戶端把這些命令發送給 dockerd 來執行,一個 client 可以與多個守護進程通信

Docker 註冊中心

類似於 npm registry,Docker registry 用來存放公共 Docker 映像,預設在 Docker Hub 查找映像

執行 docker pulldocker run 命令時,會從配置好的 registry 取所需映像,docker push 用來發布本地映像到配置指向的 registry

另外,與 npm package 不同的是,公共映像仍然是映像級的(黑盒),而不像 npm package 原始碼都是公開的。所以 Docker 還發展出了付費生態Docker store,能夠直接買一個可靠的模組/應用程式包過來,並且能夠獲得升級維護(映像更新)等服務,很有意思

P.S. 比如 Foopipes 就是個收費的映像

Docker 對象

包括映像(image)、容器(container)、服務(service)、網絡、volume(目錄)、插件等等,經常打交道的是映像和容器

映像

映像是一份只讀的模版,帶有創建 Docker 容器的說明

具有 3 個特點:

  • 可移植:能發布到 registry,或保存成壓縮文件

  • 分層的:生成映像的步驟就是(往映像中)添加層,這樣除了最後幾步外,大多數映像都可以通過共享父級層來減少磁碟佔用

  • 靜態的(只讀的):內容不可變,除非創建一個新的映像

一般通過��另一個映像的基礎上,附加一些額外定制來創建新映像。比如可以基於 ubuntu 映像構建一個映像,裝上 Apache 和自己的應用程式,並指定需要的 Apache 配置項

創建自己的映像需要創建 Dockerfile,通過簡單的語法定義其創建及運行所需步驟。Dockerfile 中的每個指都会在映像中創建一個層(layer),在修改 Dockerfile 並重新構建映像時,只構建那些發生變化的層。相比其它虛擬化技術,更輕巧更快

容器

容器是映像的可運行實例

容器也有 3 個特點:

  • 運行時的概念:進程所處的環境

  • 可變的(可寫的):實質上是一種短暫存儲

  • 分層的:映像就是容器的「層」

可以通過 Docker API 或 CLI 創建、啟動、停止、移動和刪除容器,可以把容器連接到多個網絡,給他附加存儲,甚至可以基於容器的當前狀態創建新的映像

容器是由其映像以及創建和啟動時給定的配置項定義的,容器被刪除時,其所有未被持久存儲的狀態變化都會丟失

例如:

docker run -i -t ubuntu /bin/bash

執行這條命令時發生了 6 件事:

  1. 本地沒有 ubuntu 映像的話,從 registry 拉取(跟手動執行 docker pull ubuntu 一樣)

  2. 創建個新容器(跟手動執行 docker create 一樣)

  3. 給容器分配讀寫文件系統,作為最終層,允許運行的容器操作本地文件

  4. 創建網絡接口,並把容器連接到預設網絡(沒指定網絡選項的話)。這樣會給容器分配一個 IP 地址,預設容器能夠通過主機的網絡連接連接到外網

  5. 啟動容器並執行 /bin/bash。容器以可交互的方式運行(-i)並連接到終端(-t),之後可以通過鍵盤輸入並把輸出記錄到終端

  6. 輸入 exit 終止 /bin/bash 命令時,容器將會停止,但不會被刪除,可以重新啟動它或將其刪除

服務

服務允許跨多 Docker 守護進程做容器擴展,就像多個管理者和工人作為一個集群協同工作。集群中的每個成員都是 Docker 守護進程,所有守護進程都通過 Docker API 通信。服務允許定義所需的狀態,例如在給定時間內容必須提供的服務副本數量。預設情況下,服務在所有工作節點之間是負載均衡的。對使用者來說,Docker 服務看起來就像個單一應用程式

底層技術

Docker 實現上利用了一些 Linux 內核特性:

  • Namespaces 實現獨立工作空間(container)

  • Control groups 實現容器可用資源限制

  • Union file systems 實現層(layer)

  • Container format 實現容器管理(把上面 3 個特性綜合利用起來,抽象出的概念)

四。示例

環境

cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)

安裝並啟用

# 安裝
yum install docker
# 啟動
sudo service docker start
# 開機自啟
sudo chkconfig docker on

試玩

我們在 CentOS 映像基礎上建立新的映像:

# 獲取 CentOS 映像
docker pull centos
# 確認映像存在
docker images centos

正常的話,會得到如下輸出,表明本地存在最新 CentOS 映像:

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
docker.io/centos    latest              3fa822599e10        3 weeks ago         203.5 MB

運行 Docker 容器

docker run -i -t centos /bin/bash

在新創建的終端(處於 centos 容器環境)做想做的事情:

# 裝 nvm
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash
# 更新環境變量
source ~/.bashrc
# 裝 node v4.6.2
nvm install 4.6.2
# 裝全局 module
npm install -g ionic @1.7.16
npm install -g cordova @6.2.0
# ...一頓猛操作
# 退出可交互終端
exit

P.S. 為什麼這裡的 node 版本號和全局模組版本號都是固定的?因為有個 舊玩具,只能在這個環境才跑得起來。Docker 很適合這種場景,不然別人很難在其本地環境跑起來。所以對環境有特殊要求的開源項目,不如發布一份 Docker 映像,或者自帶一份 Dockerfile

最後從當前狀態創建映像:

# 查看剛才改動的容器 ID
docker ps -a -q -l
# 提交改動並創建新的映像
docker commit 887a377fa369 ayqy/rsshelper

這樣會在本地創建一個基於 centos 映像的 ayqy/rsshelper 自定義映像:

# 查看新生成的映像
docker images ayqy/rsshelper
# 一鍵進入 RSSHelper 運行所需環境
docker run -it ayqy/rsshelper /bin/bash
# 驗證一下環境
node -v
# v4.6.2 沒錯

最基本的可以這麼玩,實際應用中還是通過 Dockerfile 創建自定義映像比較合理

Dockerfile

首先創建一個:

mkdir -p ~/projs/docker/rsshelper/
vi ~/projs/docker/rsshelper/Dockerfile

編輯內容:

FROM centos:latest
MAINTAINER ayqy "nwujiajie @163.com"

ENV NODE_VERSION 4.6.2

RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash \
&& source ~/.bashrc \
&& nvm install "$NODE_VERSION" \
&& nvm alias default "$NODE_VERSION" \
&& nvm use default \
&& nvm install -g ionic @1.7.16 cordova @6.2.0

注意

  • 第一行 FROM 指令必不可少,用來指定源映像,而且指定的映像必須是本地存在的,FROM 相當於 docker run

  • RUN 指令預設用 /bin/bash,而且每條 RUN 都起一個新的 bash 進程,所以為了共享環境變量需要用 && 連接,而不用多條 RUN 指令

創建映像:

docker build -t="ayqy/rsshelper_image" ~/projs/docker/rsshelper/
# 創建完成後查看新的映像
docker images ayqy/rsshelper_image

注意,如果有任何一條命令返回值不為 0,映像就會構建失敗

P.S. 關於 Dockerfile 的更多信息,請查看 快速掌握 dockerfile

常用命令

# 從 registry 拉取指定映像
docker pull fedora
# 查看本地映像
docker images
# 從 Dockerfile 創建映像,要求當前目錄下有 Dockerfile
docker build -t myimage .
# 以可交互的方式運行容器
docker run -it myimage
# 查看正在運行的容器
docker ps -l
# 停止容器運行(id 從 docker ps 輸出裡找)
docker kill <id>
# 刪除容器
docker rm <id>

P.S. 通過 docker help 查看更多 Docker 客戶端命令

五。應用場景

容器技術消除了本地開發環境與真實生產環境的差異,有助於簡化保障 CI/CD 工作流:

  1. 用容器開發應用程式並管理依賴項

  2. 把容器作為發布和測試的基本單元

  3. 部署到生產環境,無論生產環境具體是什麼樣子的(本地數據中心、雲供應商還是二者混合的)

幾個示例應用場景:

  • Demo 共享

把開發 Demo 打包到容器分享出去,別人能在其本地環境立即跑起來

  • 自動化測試

把開發環境的應用程式部署到測試環境,進行人工測試/自動化測試,而不用考慮環境差異

  • 快速重新部署/發布

開發環境修復 bug 後,重新部署到測試環境進行測試驗證,測試通過後,把最新映像部署到生產環境

  • 優化資源利用率

通過限制各應用程式的資源配額,或者用 Docker 容器代替虛擬機來進一步提高資源利用率

參考資料

評論

暫無評論,快來發表你的看法吧

提交評論