Docker從零開始實操

Docker從零開始實操

來自專欄 Python中文社區5 人贊了文章

作者:Zarten

知乎ID: Zarten

簡介: 互聯網一線工作者,尊重原創並歡迎評論留言指出不足之處,也希望多些關注和點贊是給作者最好的鼓勵 !

概念

Docker是一種新興的虛擬化方式,很多人在開發過程中會有疑惑:「為什麼程序在我的電腦可以正常運行,而在你的電腦就不行了?」,Docker就是為了解決這類問題而生。Docker比傳統的虛擬化方式有更多的優勢,如下圖:

名詞解釋

這裡解釋幾個重要詞:鏡像、容器、倉庫

  • 鏡像(image)

Docker鏡像是一個特殊的文件系統,除了提供容器運行時所需的程序、庫、資源、配置等文件之外,還包含了一些為運行時準備的配置參數,如匿名卷、環境變數、用戶等,鏡像不包含任何的動態數據,其內容在構建鏡像後不會被改變了。

  • 容器(container)

容器在鏡像中運行,在這樣一個隔離的環境中運行好像在一個獨立的宿主系統下運行,容器實質是進程,因此有自己的root文件系統、網路配置、進程空間等。

每一個容器運行時是以鏡像為基礎層,創建一個當前容器的存儲層,稱為容器存儲層。這個容器存儲層的生命周期和容器(進程)相同,容器消亡時,它也隨之消亡,因此不要向容器存儲層內寫入任何數據,比如日誌信息等。應該使用數據卷或綁定宿主目錄,這樣數據就不會丟失,這些後面會講到。

  • 倉庫(Repository)

鏡像構建完成後,我們可以託管到一個集中的存儲、分發鏡像的服務上,跟github類似。公開服務是官方的Docker Hub,也是默認的服務,有大量的高質量的官方鏡像。

一個這樣服務中有多個倉庫,倉庫內包含有多個標籤(Tag),每個標籤對應一個鏡像,通常軟體的不同版本對應不同的標籤(如python2和python3),一個鏡像通過 倉庫名:標籤名 來唯一確認,如果沒有給出標籤名,則將以latest作為默認標籤。

Docker的安裝

docker分為CE(社區版,免費)和EE(企業版,收費),這裡我們講述CE版在windows 7和Ubuntu上的安裝。其他系統安裝請看官網的安裝說明,這裡不再贅述。

  • windows 7上安裝docker

官網Docker Toolbox安裝

安裝完成後在cmd窗口輸入 docker,出現以下信息則安裝成功

安裝成功後需要創建docker虛擬機,命令如下:

docker-machine create --driver virtualbox 虛擬機名稱

創建完成後如下命令查看虛擬機運行狀態:

docker-machine ls

在Oracle VM VirtualBox可看到此虛擬機

虛擬機與docker-machine關聯,如下命令:

docker-machine env 虛擬機名稱

接下來,還需執行最後一行,就可以使用了

  • Ubuntu上安裝docker

通過腳本自動安裝非常方便,只需依次執行以下2行:

curl -fsSL get.docker.com -o get-docker.sh

sudo sh get-docker.sh --mirror Aliyun

docker需要用root許可權,為了普通用戶更方便使用docker,執行如下命令:

sudo usermod -a -G docker $USER

執行完成後一定要退出後重新登錄就可以了

驗證docker是否安裝成功,只需執行:

docker run hello-world

鏡像加速器的配置方法

國內從官方的Docker Hub上拉取鏡像時會非常的慢,所以我們需要配置鏡像加速器,這裡我們使用官方的中國mirror加速器: https://registry.docker-cn.com 為例

  • win 7 上配置加速器

用git Bash執行如下命令(其中Zarten為虛擬機的名稱):

最後重啟虛擬機即可

  • Ubuntu上配置加速器

註:本人系統版本為ubuntu 17.10

用root許可權在/etc/docker/daemon.json 中寫入如下內容(如果文件不存在請新建該文件)

{

"registry-mirrors": [

"registry.docker-cn.com" ]

}

最後重啟docker即可

$ sudo systemctl daemon-reload

$ sudo systemctl restart docker

鏡像的使用

  • 獲取鏡像

官方的Docker Hub上有許多高質量的鏡像,我們可以從這裡獲取鏡像,命令格式如下:

docker pull [選項] [Docker Registry 地址[:埠號]/]倉庫名[:標籤]

一般Docker Registry 地址不指定,默認為官方的Docker Hub,標籤不指定,默認為latest

例如:docker pull ubuntu:16.04

配置鏡像加速器後非常快

使用下面命令可看到下載的鏡像:

docker image ls

  • 運行鏡像中的容器

我們以這個鏡像啟動並運行一個容器,執行如下命令可以啟動裡面的bash並進行交互操作

docker run -it --rm ubuntu:16.04 bash

註:若不指定tag標籤,默認為latest標籤,若在本地沒有latest標籤的話,會自動從官網下載

-it: -i 互動式操作 -t 終端

--rm: 容器退出時做清理工作

bash: 互動式shell

從上圖可看到查看了系統的版本信息,最後 exit 命令可退出容器

  • 查看鏡像

查看所有本地鏡像(頂層鏡像)

docker image ls

從上圖從左到右依次列出欄位為: 倉庫名 標籤 鏡像id 鏡像創建時間 鏡像大小

有時新鏡像跟舊的鏡像同名,導致舊鏡像名稱被取消,從而出現了倉庫名和標籤均為<none>的鏡像,這種鏡像叫做虛懸鏡像,這類鏡像已經失去了其價值,可以隨意刪除掉

顯示所有虛懸鏡像命令:

docker image ls -f dangling=true

刪除所有虛懸鏡像命令:

docker image prune

查看中間層鏡像

docker image ls只會顯示頂層鏡像,若查看所有鏡像,用:

docker image ls -a

可以看到有很多<none>鏡像,這些鏡像不是虛懸鏡像,而是頂層鏡像所依賴的中間層鏡像,不應該也不能刪除

查看指定的鏡像

例如:只查看倉庫名為ubuntu的鏡像

docker image ls ubuntu

或 docker image ls ubuntu:16.04

列出鏡像id

docker image ls -q

有時我們需要進行批量操作,這個命令配合其他命令很有用,如:docker image rm

  • 刪除鏡像

docker image rm 鏡像1 鏡像2 ...

通常可用鏡像id(前3位就行),鏡像名,摘要刪除

批量刪除

docker image rm $(docker image ls -q ubuntu)

  • 定製鏡像

使用Dockerfile文件在某個已有的鏡像的基礎上來定製我們自己的鏡像,其內為一條條的指令,每一條指令構建一層,下面將介紹常用指令

FROM

FROM指定一個基礎鏡像,必須有這個指令,且是第一條指令,格式與pull命令的格式一樣,為:倉庫名:標籤名

若不需要以任何鏡像為基礎,可以將其設為 scratch ,如:

FROM scratch

...

RUN

這個指令用來執行命令行,用來安裝一些運行所需的環境,也是經常用到的指令,一個RUN指令就是構建一層,格式跟shell一樣。若有多個命令需要執行,用下面格式,只需一個RUN即可

RUN buildDeps=gcc libc6-dev make

&& apt-get update

&& apt-get install -y $buildDeps

COPY

這個指令將源路徑文件或目錄複製到容器內的目標路徑,目標路徑可以是絕對或相對,若沒有目錄,會自動創建目錄,其格式如下:

COPY 源 目

COPY package.json /usr/src/app/

另外還有一個更高級的指令ADD跟COPY差不多,若源路徑為URL或壓縮文件,ADD會自動解壓複製到目標路徑,不過不推薦使用ADD指令,用COPY指令就好,因為ADD指令會令鏡像構建緩存失效,可能會是鏡像構建變得很緩慢

CMD

這個指令為容器(進程)啟動的命令,格式為: CMD 命令,這個命令為默認命令,可以在運行容器時在命令最後添加自己的cmd命令,如 docker run -it ubuntu cat /etc/os-release,

cat /etc/os-release就替換了默認命令

ENV

這個指令為設置環境變數,格式為: ENV key value 或 ENV key1=value1 key2=value2

ENV VERSION=1.0 DEBUG=on

NAME="Happy Feet"

很多指令都可以支持環境變數展開

VOLUME

定義匿名卷,格式為: VOLUME 路徑

前面講到,容器運行時不應向容器存儲層發生寫操作,其數據應該保存在卷中,VOLUME指令可以事先指定匿名卷,當運行時用戶沒有指定掛載,不會向容器內寫入數據,如:

VOLUME /data

任何向/data中寫入的數據不會記錄到存儲層

EXPOSE

聲明運行時容器提供的服務埠,格式為: EXPOSE 埠1 埠2

這裡只是聲明容器暴露的埠,這樣方便後續執行命令知道所需的埠是什麼,真正埠映射是執行容器run 命令時 -p 宿主埠 容器埠 來映射的

WORKDIR

指定工作目錄,格式為: WORKDIR 路徑

  • 構建鏡像

Dockerfile文件製作好了之後,我們就可以構建自己的鏡像了,命令為:

docker build -t 鏡像名:標籤名 . (注意:最後有一個空格+點,標籤名不指定默認為latest)

容器的使用

鏡像創建好了之後就可以操作容器了,容器時鏡像運行時的實體,容器可以被創建,啟動,停止,刪除,暫停等

  • 啟動容器

啟動容器的方式有2種:1.基於鏡像新建一個容器並啟動 2.將一個終止的容器重新啟動

1.基於鏡像新建一個容器並啟動

命令為: docker run [選項] 鏡像名

此命令會檢查本地是否有指定的鏡像名,若沒有則從公有倉庫下載

選項參數有很多,比較常見的為:

-d : 容器在後台運行,不會直接將命令輸出到當前的宿主,若要查看輸出信息,可以用命令:

docker container logs 容器id或容器名

-p : 埠映射 如: -p 宿主埠:容器埠

2.將一個終止的容器重新啟動

命令為: docker container start 容器名

  • 終止容器

當容器中程序終結時,容器會自動終止,我們也可以手動來終止一個運行的容器,命令為:

docker container stop 容器名或容器id

查看所有的容器,命令為:

docker container ls -a

可以看到STATUS為Exited 的為終止後的容器,我們可以使用docker container start 來啟動它。或看到Up狀態的為正在運行的容器,我們可以用 docker container restart 來重新啟動

  • 刪除容器

可以用下面命令刪除一個終止狀態的容器

命令為: docker container rm 容器

若要刪除一個運行中的容器,可以用 -f 參數來強制刪除掉

我們用 docker container ls -a 來查看所有容器,若發現太多的終止容器,一個個刪除太麻煩,可以用下面命令一次性刪除全部的終止狀態的容器,命令為:

docker container prune

  • 進入容器

當使用-d參數時,容器會進入後台運行,當用戶需要輸入時就不行了,此時就需要進入容器,有2個命令:attach 和 exec 來顯示容器輸入界面

推薦使用exec命令,因為attach命令使用exit後退出容器界面回到宿主界面時會導致容器終止

exec命令: docker exec 多個參數

一般 -i -t 參數一起使用時,是我們熟悉的Linux命令提示符,如:

docker exec -it 容器id 輸入

使用exec命令後,從stdin退出(exit)時不會導致容器終止

數據管理

前面講到容器內不應存數據,這裡將介紹數據如何管理,主要有2中管理數據方式:

數據卷(Volumes)和掛載主機目錄(Bind mount)

  • 數據卷(Volumes)

數據卷是可以給一個或多個容器使用的特殊目錄,它有如下的特性:

  1. 數據卷會一直存在,即使容器被刪除
  2. 可以在容器之間共享和重用
  3. 對數據卷的更新不會影響到鏡像
  4. 對數據卷的修改會立刻生效

使用如下命令可以創建一個數據卷

創建數據卷

docker volume create 數據卷名

查看所有的數據卷

docker volume ls

查看某個數據卷的具體信息

docker volume inspect 數據卷名

啟動一個容器並掛載數據卷

在用docker run 命令啟動容器時可以用 --mount 來掛載數據卷到容器中的某個或多個目錄(文件)

docker run [選項] --mount source=數據卷名,target=容器目錄或文件(可以多個,用空格分開)

也可以 -v 數據卷名:掛載目錄

刪除數據卷

數據卷生命周期獨立於容器,容器終止後其不會刪除。若需刪除,下面命令:

docker volume rm 數據卷名

若刪除容器的同時刪除數據卷,可用 -v 參數

docker rm -v 容器名

無主的數據卷可能會佔用很多空間,清理這些數據卷可用如下命令:

docker volume prune

  • 掛載主機目錄

使用 --mount 可以指定掛載一個本地主機的目錄到容器的目錄,如:

$ docker run -d -P

--name web

# -v /src/webapp:/opt/webapp

--mount type=bind,source=/src/webapp,target=/opt/webapp

training/webapp

python app.py

倉庫的使用

倉庫(Repository)是一個集中存放鏡像的地方,官方倉庫為 Docker Hub,可以在官網免費註冊一個賬號

註冊成功後,可以在命令行界面來登錄或退出操作

  • 登錄和退出操作

使用 docker login 和 docker logout

  • 查找鏡像

docker search 查找的鏡像名

  • 下載和推送鏡像

使用pull和push命令

例如: docker pull ubuntu:16.04

push操作必須登錄後才行

推送的步驟有2步:

1.將本地鏡像前面加上遠程倉庫名

docker tag 本地鏡像名:標籤 username/遠程倉庫名:標籤

2.推送

docker push username/鏡像

參考文章: 前言 · Docker -- 從入門到實踐

推薦閱讀:

最小許可權的容器編排
『中級篇』通過Docker-Machine阿里雲使用(11)
『中級篇』容器的技術概述(二)
Docker(六):Docker 三劍客之 Docker Swarm
開源項目中文鏡像服務上線

TAG:Docker | 虛擬機 | Python |