Docker

虛擬機器的做法是藉由Hypervisor軟體層,將硬體運算資源抽象化,再提供給每一臺虛擬機器,

雖然每臺虛擬機器所分配到的運算資源,實際上只占硬體資源的一部分,

但透過Hypervisor的作用,虛擬機器會以為它擁有獨立的硬體資源。

docker-containers-vms.png

Linux Container技術則是如同貨櫃的概念,把應用程式打包成一個貨櫃,

包含執行該應用程式最基本的作業系統核心、程式碼、函式庫等,

讓應用程式可隔離、可移動,並且直接使用由作業系統來分割的硬體資源,

因此不需要透過Hypervisor軟體層來配置硬體資源。

 

基本概念

Docker 包括三個基本概念

  • 映像檔(Image)
  • 容器(Container)
  • 倉庫(Repository)

理解了這三個概念,就理解了 Docker 的整個生命週期。
 

映像檔

Docker 映像檔就是一個唯讀的模板。

例如:一個映像檔可以包含一個完整的 ubuntu 作業系統環境,裡面僅安裝了 Apache 或使用者需要的其它應用程式。

映像檔可以用來建立 Docker 容器。
Docker 提供了一個很簡單的機制來建立映像檔或者更新現有的映像檔,
使用者甚至可以直接從其他人那裡下載一個已經做好的映像檔來直接使用。
  • 取得映像檔
  • 列出
  • 建立
  • 存出和載入
  • 移除
  • 實作原理

容器

Docker 利用容器來執行應用。
容器是從映像檔建立的執行實例。
它可以被啟動、開始、停止、刪除。每個容器都是相互隔離的、保證安全的平台。
可以把容器看做是一個簡易版的 Linux 環境
(包括root使用者權限、程式空間、使用者空間和網路空間等)和在其中執行的應用程式。

*註:映像檔是唯讀的,容器在啟動的時候建立一層可寫層作為最上層。(利用Union FS)

  • 啟動
  • 守護態執行(Daemonized)
  • 終止
  • 進入容器
  • 匯出與匯入
  • 刪除

倉庫

倉庫是集中存放映像檔檔案的場所。有時候會把倉庫和倉庫註冊伺服器(Registry)混為一談,並不嚴格區分。
實際上,倉庫註冊伺服器上往往存放著多個倉庫,每個倉庫中又包含了多個映像檔,每個映像檔有不同的標籤(tag)。
倉庫分為公開倉庫(Public)和私有倉庫(Private)兩種形式。

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

  • Docker Hub
  • 私有倉庫
  • 設定檔案

 

Docker data management

如何在 Docker 內部以及容器之間管理資料,在容器中管理資料主要有兩種方式:

  • 資料卷(Data volumes)
  • 資料卷容器(Data volume containers)

Data volumes

volume 的使用,類似於 Linux 下對目錄或檔案進行 mount。
  • 建立一個資料卷
  • 掛載一個主機目錄作為資料卷
  • 掛載一個本地主機檔案作為資料卷(建議直接掛載整個目錄)

Data volume containers

如果你有一些持續更新的資料需要在容器之間共享,最好建立資料卷容器。
資料卷容器,其實就是一個正常的容器,專門用來提供資料卷供其它容器掛載的。
欲掛載的資料卷容器無須保持在執行狀態。
可以利用資料卷容器對其中的資料進行進行備份、恢復和遷移。
  • 建立一個命名的資料卷容器
  • 掛載容器中的資料卷(也就是掛載資料卷容器)

 

Docker network

Docker 允許透過外部存取容器或容器互聯的方式來提供網路服務。

  • 外部存取容器(port mapping)
  • 容器互聯(linking)

 

Docker advanced network

當 Docker 啟動時,會自動在主機上建立一個 docker0 虛擬橋接器,實際上是 Linux 的一個 bridge,
可以理解為一個軟體交換機。它會在掛載到它的網卡之間進行轉發。
network.png
同時,Docker 隨機分配一個本地未占用的私有網段(在 RFC1918 中定義)中的一個位址給 docker0 界面。
比如典型的 172.17.42.1,網路遮罩為 255.255.0.0。
此後啟動的容器內的網卡也會自動分配一個同一網段(172.17.0.0/16)的網址。

當建立一個 Docker 容器的時候,同時會建立了一對 veth pair 界面
(當資料包發送到一個界面時,另外一個界面也可以收到相同的資料包)。
這對界面一端在容器內,即 eth0;
另一端在本地並被掛載到 docker0 橋接器,名稱以 veth 開頭(例如 vethAQI2QT)。
透過這種方式,主機可以跟容器通信,容器之間也可以相互通信。
Docker 就建立了在主機和所有容器之間一個虛擬共享網路。
 

Notes

Dockerfile

.bashrc

將 .bashrc_docker 內容放進 .bashrc 中


這個檔案中定義了很多方便使用 Docker 的命令,
例如 docker-pid 可以取得某個容器的 PID;而 docker-enter 可以進入容器或直接在容器內執行命令。
$ echo $(docker-pid <container>)
$ docker-enter <container> ls

 

import

可以使用 docker import 從容器快照檔案中再匯入為映像檔

$ cat ubuntu.tar | sudo docker import - test/buntu:v1.0
$ sudo docker images
REPOSITORY          TAG                 IMAGE ID            CREATED              VIRTUAL SIZE
test/ubuntu         v1.0                9d37a6082e97        About a minute ago   171.3 MB

使用者既可以使用docker import 來匯入一個容器快照到本地映像檔庫,也可以 docker load 來匯入映像檔儲存檔案到本地映像檔庫。
$ sudo docker load --input ubuntu_14.04.tar
$ sudo docker load < ubuntu_14.04.tar

這兩者的區別在於容器快照檔案將丟棄所有的歷史記錄和原始資料訊息(即僅保存容器當時的快照狀態),
而映像檔儲存檔案將保存完整記錄,檔案體積也跟著變大。

此外,從容器快照檔案匯入時可以重新指定標籤等原始資料訊息。
 

TBD

TBD

TBD

 

附錄一 - Docker 命令查詢

基本語法

docker [OPTIONS] COMMAND [arg...]

一般來說,Docker 命令可以用來管理 daemon,或者透過 CLI 命令管理映像檔和容器。
可以透過 man docker 來查看這些命令。

option

command

Docker 的命令可以採用 docker-COMMAND 或者 docker COMMAND的方式執行。兩者一致。

docker attach(1)
    依附到一個正在執行的容器中。
docker build(1)
    從一個 Dockerfile 建立一個映像檔
docker commit(1)
    從一個容器的修改中建立一個新的映像檔
docker cp(1)
    從容器中複製檔案到宿主系統中
docker diff(1)
    檢查一個容器檔案系統的修改
docker events(1)
    從服務端取得實時的事件
docker export(1)
    匯出容器內容為一個 tar 包
docker history(1)
    顯示一個映像檔的歷史
docker images(1)
    列出存在的映像檔
docker import(1)
    匯入一個檔案(典型為 tar 包)路徑或目錄來建立一個映像檔
docker info(1)
    顯示一些相關的系統資訊
docker inspect(1)
    顯示一個容器的底層具體資訊。
docker kill(1)
    關閉一個執行中的容器 (包括程式和所有資源)
docker load(1)
    從一個 tar 包中載入一個映像檔
docker login(1)
    註冊或登錄到一個 Docker 的倉庫伺服器
docker logout(1)
    從 Docker 的倉庫伺服器登出
docker logs(1)
    取得容器的 log 資訊
docker pause(1)
    暫停一個容器中的所有程式
docker port(1)
    查找一個 nat 到一個私有網口的公共口
docker ps(1)
    列出容器
docker pull(1)
    從一個Docker的倉庫伺服器下拉一個映像檔或倉庫
docker push(1)
    將一個映像檔或者倉庫推送到一個 Docker 的註冊伺服器
docker restart(1)
    重新啟動一個執行中的容器
docker rm(1)
    刪除指定的數個容器
docker rmi(1)
    刪除指定的數個映像檔
docker run(1)
    建立一個新容器,並在其中執行指定命令
docker save(1)
    保存一個映像檔為 tar 包檔案
docker search(1)
    在 Docker index 中搜索一個映像檔
docker start(1)
    啟動一個容器
docker stop(1)
    終止一個執行中的容器
docker tag(1)
    為一個映像檔打標籤
docker top(1)
    查看一個容器中的正在執行的程式資訊
docker unpause(1)
    將一個容器內所有的程式從暫停狀態中恢復
docker version(1)
    輸出 Docker 的版本資訊
docker wait(1)
    阻塞直到一個容器終止,然後輸出它的退出符

一張圖總結 Docker 的命令

cmd_logic.png
 

附錄二 - 連結

  • 《 Docker —— 從入門到實踐》 Link
  • 《10 個讓 Docker 威力倍增的開放原始碼軟體》Link
  • 《Top 10 Open-Source Docker Developer Tools》Link

 

除非特別註明,本頁內容採用以下授權方式: Creative Commons Attribution-ShareAlike 3.0 License