Docker 筆記(1):介紹、鏡像、容器及其基本操做

Docker簡介

  • Docker 使用 Google 公司推出的 Go 語言 進行開發實現,基於 Linux 內核的 cgroup,namespace,以及 AUFS 類的 Union FS 等技術,對進程進行封裝隔離,屬於 操做系統層面的虛擬化技術。因爲隔離的進程獨立於宿主和其它的隔離的進程,所以也稱其爲容器。最初實現是基於 LXC,從 0.7 版本之後開始去除 LXC,轉而使用自行開發的 libcontainer,從 1.11 開始,則進一步演進爲使用 runC 和 containerd。
  • Docker 在容器的基礎上,進行了進一步的封裝,從文件系統、網絡互聯到進程隔離等等,極大的簡化了容器的建立和維護。使得 Docker 技術比虛擬機技術更爲輕便、快捷。
  • 下面的圖片比較了 Docker 和傳統虛擬化方式的不一樣之處。傳統虛擬機技術是虛擬出一套硬件後,在其上運行一個完整操做系統,在該系統上再運行所需應用進程;而容器內的應用進程直接運行於宿主的內核,容器內沒有本身的內核,並且也沒有進行硬件虛擬。所以容器要比傳統虛擬機更爲輕便。----Docker gitbook

傳統虛擬化


容器類虛擬化


Docker一般用於以下場景:html

  • web應用的自動化打包和發佈;
  • 自動化測試和持續集成、發佈;
  • 在服務型環境中部署和調整數據庫或其餘的後臺應用;
  • 從頭編譯或者擴展示有的OpenShift或Cloud Foundry平臺來搭建本身的PaaS環境。

關於容器、鏡像、倉庫等基本概念見Docker gitbook--基本概念mysql

鏡像

容器是鏡像的運行實例。Docker鏡像是一個特殊的文件系統,除了提供容器運行時所需的程序、庫、資源、配置等文件外,還包含了一些爲運行時準備的一些配置參數(如匿名卷、環境變量、用戶等)。 鏡像不包含任何動態數據,其內容在構建以後也不會被改變。---- http://dockone.io/article/6051git

鏡像的實現原理

Docker 鏡像是怎麼實現增量的修改和維護的?web

每一個鏡像都由不少層次構成,Docker 使用 Union FS 將這些不一樣的層結合到一個鏡像中去。sql

一般 Union FS 有兩個用途, 一方面能夠實現不借助 LVM、RAID 將多個 disk 掛到同一個目錄下,另外一個更經常使用的就是將一個只讀的分支和一個可寫的分支聯合在一塊兒,Live CD 正是基於此方法能夠容許在鏡像不變的基礎上容許用戶在其上進行一些寫操做。docker

Docker 在 AUFS 上構建的容器也是利用了相似的原理。關於聯合文件系統UFS可見http://www.dockerinfo.net/175...數據庫

Docker設計時,就充分利用Union FS的技術,將其設計爲分層存儲的架構。 鏡像實際是由多層文件系統聯合組成。ubuntu

鏡像構建時,會一層層構建,前一層是後一層的基礎。每一層構建完就不會再發生改變,後一層上的任何改變只發生在本身這一層。好比,刪除前一層文件的操做,實際不是真的刪除前一層的文件,而是僅在當前層標記爲該文件已刪除。在最終容器運行的時候,雖然不會看到這個文件,可是實際上該文件會一直跟隨鏡像。所以,在構建鏡像的時候,須要額外當心,每一層儘可能只包含該層須要添加的東西,任何額外的東西應該在該層構建結束前清理掉。segmentfault

相關命令

  • 搜索可用的鏡像
docker search mysql

  • 拉取鏡像
docker pull image_name:tag  // 如 docker pull mysql:5.7

  • 刪除鏡像
docker rmi image_name:tag
docker rmi image_id
  • 刪除空懸鏡像
docker image prune
// or : docker rmi $(docker images -aq -f dangling=true)
  • 導出、導出鏡像

有時候咱們須要將本身構造的鏡像分享給別人,但又不想放在倉庫上,那麼就能夠將鏡像導出爲文件,而後copy給別人,再由其導入便可分享給他人使用。安全

docker save image_name  -o  /home/xxx/tar_name.tar
docker load -i /home/xxx/tar_name.tar

容器

概念

  • 鏡像(Image)和容器(Container)的關係,就像是面向對象程序設計中的 類 和 實例 同樣,鏡像是靜態的定義,容器是鏡像運行時的實體。容器能夠被建立、啓動、中止、刪除、暫停等。
  • 容器的實質是進程,但與直接在宿主執行的進程不一樣,容器進程運行於屬於本身的獨立的 命名空間。所以容器能夠擁有本身的 root 文件系統、本身的網絡配置、本身的進程空間,甚至本身的用戶 ID 空間。容器內的進程是運行在一個隔離的環境裏,使用起來,就好像是在一個獨立於宿主的系統下操做同樣。這種特性使得容器封裝的應用比直接在宿主運行更加安全。也由於這種隔離的特性,不少人初學 Docker 時經常會混淆容器和虛擬機。
  • 容器存儲層的生存週期和容器同樣,容器消亡時,容器存儲層也隨之消亡。所以,任何保存於容器存儲層的信息都會隨容器刪除而丟失。按照 Docker 最佳實踐的要求,容器不該該向其存儲層內寫入任何數據,容器存儲層要保持無狀態化。全部的文件寫入操做,都應該使用 數據卷(Volume)、或者綁定宿主目錄,在這些位置的讀寫會跳過容器存儲層,直接對宿主(或網絡存儲)發生讀寫,其性能和穩定性更高。----《docker gitbook》

相關命令

  • run
docker run [options] image [command]

options:
-i: 讓容器的標準輸入保持打開
-t: 讓docker 分配一個僞終端pseudo-tty
-d: 後臺運行並返回一個惟一的id。要獲取容器的輸出信息,能夠經過 docker [container] logs [container ID or NAMES] 命令。

當利用 docker run 來建立容器時,Docker 在後臺運行的標準操做包括:

  • 檢查本地是否存在指定的鏡像,不存在就從公有倉庫下載
  • 利用鏡像建立並啓動一個容器
  • 分配一個文件系統,並在只讀的鏡像層外面掛載一層可讀寫層
  • 從宿主主機配置的網橋接口中橋接一個虛擬接口到容器中去
  • 從地址池配置一個 ip 地址給容器
  • 執行用戶指定的應用程序
  • 執行完畢後容器被終止

  • start

啓動已經終止的容器

docker start container

容器的核心爲所執行的應用程序,所須要的資源都是應用程序運行所必需的。除此以外,並無其它的資源。能夠在僞終端中利用 ps 或 top 來查看進程信息


  • stop
docke r [container] stop contain_id_or_name
// 中止全部的容器
// docker ps -a 的做用是列出全部的容器,-q 的做用是取出容器的id
docker stop $(docker ps -aq)

  • rm

刪除容器

docker [container] rm container_id

  • prune

刪除終止的容器

docker rm $(docker ps -aq)

在使用 -d 參數時,容器啓動後會進入後臺模式運行。

某些時候須要進入容器進行操做,包括使用 docker attach 命令或 docker exec 命令,推薦你們使用 docker exec 命令,緣由會在下面說明。

  • attach
docker attach container_id

注意: 若是從這個 stdin 中 exit,會致使容器的中止。

  • exec
docker exec [options] container_id command
options:
-i: 輸出
-t: 終端
如:
docker exec -it 69d1 bash

stdin 中 exit,不會致使容器的中止。這就是爲何推薦你們使用 docker exec 的緣由。

更多參數說明請使用 docker exec --help 查看。
圖片描述


有時候咱們會須要將本身機器的容器按期保存下來或者分享給其餘人,那麼就可使用導入/導出的功能

  • export
docker export container_id > your_container_file
example:
    docker export fe3 > ubuntu

這樣將導出容器快照到本地文件。

  • import
cat you_container_file > docker import - yourlibrary/your_image:tag

可使用 docker import 從容器快照文件中再導入爲鏡像。

此外,也能夠經過指定 URL 或者某個目錄來導入,例如

docker import http://example.com/exampleimage.tgz example/imagerepo

用戶既可使用 docker load 來導入鏡像存儲文件到本地鏡像庫,也可使用 docker import 來導入一個容器快照到本地鏡像庫。這二者的區別在於容器快照文件將丟棄全部的歷史記錄和元數據信息( 即僅保存容器當時的快照狀態) ,而鏡像存儲文件將保存完整記錄,體積也要大。此外,從容器快照文件導入時能夠從新指定標籤等元數據信息

數據卷

數據卷 是一個可供一個或多個容器使用的特殊目錄,它繞過 UFS,能夠提供不少有用的特性:

  • 數據卷 能夠在容器之間共享和重用
  • 對 數據卷 的修改會立馬生效
  • 對 數據卷 的更新,不會影響鏡像
  • 數據卷 默認會一直存在,即便容器被刪除

注意: 數據卷 的使用,相似於 Linux 下對目錄或文件進行 mount,鏡像中的被指定爲掛載點的目錄中的文件會隱藏掉,能顯示看的是掛載的 數據卷 。所以你的容器目錄dir有一個文件爲temp.data,若是你在dir掛載了一個數據卷,那麼你就不再能讀取temp.data,除非你移除該數據卷。

建立數據卷

docker volume create volume_name

查看數據卷

docker volume ls // 列出數據卷列表
docker volume inspect volume_name //查看指定的數據卷信息
--------------------------------------------------------------
輸出:

[
    {
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
        "Name": "my-vol",
        "Options": {},
        "Scope": "local"
    }
]

掛載數據卷

docker run [options] --name container_name
    --mount source=volume_name,targe=path_in_container
    image_name_or_id
    [command]

查看掛載信息,在輸出的信息的Mount字段包含了掛載信息

docker inspect container_name

result:
"Mounts": [
{
    "Type": "volume",
    "Name": "my-vol",
    "Source": "/var/lib/docker/volumes/my-vol/_data",
    "Destination": "/app",
    "Driver": "local",
    "Mode": "",
    "RW": true,
    "Propagation": ""
}
]

刪除數據卷

docker volume rm volume_name

刪除無主數據卷:即沒有被容器使用的數據卷

docker volume prune

掛載主機目錄做爲數據卷

docker run [option]
    [--name container_name]
    -- mount type=bind,source=host_path,target=container_path
    image_name
    [command]

上面的命令加載主機的 /src/webapp 目錄到容器的 /opt/webapp 目錄。這個功能在進行測試的時候十分方便,好比用戶能夠放置一些程序到本地目錄中,來查看容器是否正常工做。本地目錄的路徑必須是絕對路徑,之前使用 -v 參數時若是本地目錄不存在 Docker 會自動爲你建立一個文件夾,如今使用 --mount 參數時若是本地目錄不存在,Docker 會報錯。

也能夠爲docker數據卷指定讀寫權限

-- mount type=bind,source=host_path,target=container_path,readonly

這樣你就不能在容器中寫container_path的目錄了

也能夠掛載文件

-- mount type=bind,source=host_path,target=container_path

相關文章
相關標籤/搜索