1. 程式人生 > >Docker命令全解析

Docker命令全解析

操作映象

獲取映象並啟動一個容器

$ docker run -d -p 80:80 --name webserver nginx

檢視當前執行的容器

$ docker ps

獲取映象

$ docker pull --help
$ docker pull [OPTIONS] NAME[:TAG|@DIGEST]
$ docker pull ubuntu:14.04

NAME:為映象倉庫名稱

TAG:為映象的標籤

檢視映象資訊

$ docker images

使用映象建立容器,執行應用

$ docker run -it ubuntu:14.04 bash

檢視當前執行的容器

$ docker ps

給映象打標籤

$ docker tag

檢視映象詳細資訊

$ docker inspect

例如

$ docker inspect 677
$ docker inspect 677 -f {{".Architecture"}} #獲取部分資訊

檢視映象歷史

$ docker history 677
$ docker history 677 --no-trunc #顯示完整的命令

搜尋映象

$ docker search --automated -s 3 nginx #自動建立且3星以上的nginx映象

刪除映象

通過標籤名刪除映象,則刪除的是標籤,不刪除原始映象。

通過映象ID刪除映象,先嚐試刪除所有標籤,然後刪除映象本身。

如果映象有容器存在,則無法刪除。可以強制刪除,但是不建議這樣做。

$ docker rmi TAG
$ docker rmi IMAGE ID
$ docker rmi -f IMAGE ID

建立映象
1. 基於已有映象的容器建立


$ docker tag ubuntu:14.04 myubuntu:01
$ docker run -it myubuntu:01 /bin/bash
# touch test
# exit
$ docker ps -a
$ docker commit -a "liux" -m "create file" -p c466799b264e test:01
$ docker images


- 基於本地模板建立

  • 基於Dockerfile建立

匯出和匯入映象

$ docker save  -o ~/Downloads/ubuntu_14.04.tar ubuntu:14.04
$ docker load  < ~/Downloads/ubuntu_14.04.tar

上傳映象

$ docker tag ubuntu:14.04 test/myubuntu:01
$ docker push test/myubuntu:01

操作容器

容器是映象的一個例項,映象是靜態只讀檔案,而容器帶有執行時所需的可寫層。

可以認為虛擬機器是一套作業系統,可以在上面執行應用。

而容器只是一個可以獨立執行的應用,攜帶了他必需的執行環境。

create命令與容器執行模式相關的選項

選項 說明
-a , –attach=[ ] 是否繫結到標準輸入,輸出和錯誤
-d , –detach=true|false 是否在後臺執行容器,預設false
–detach-keys=”“ 從attach模式退出時的快捷鍵
–entrypoint=”“ 映象存在入口命令時,覆蓋為新的命令
–expose=[ ] 指定容器會暴露出來的埠或埠範圍
–group-add=[ ] 執行容器的使用者組
-i, –interactive=true|false 保持標準輸入開啟,預設為false
–ipc=”“ 容器IPC名稱空間,可以為其他容器或主機
–isolation=”default” 容器使用的隔離機制
–log-driver=”json-file” 指定容器的日誌驅動型別:json-file,syslog,journald,gelf,fluentd,awslogs,splunk,etwlogs或none
–log-opt=[ ] 傳遞給日誌驅動的選項
–net=”bridge” 指定容器網路模式,bridge,none,其他容器內網路,host的網路或某個現有網路
–net-alias=[ ] 容器在網路中的別名
-P, –publish-all=true|false 通過NAT機制將容器標記暴露的埠自動對映到本地本機的臨時埠
-p, –publish=[ ] 指定如何對映到本地主機埠,例如:-p 11234-12234:123-12234
–pid=host 容器的PID名稱空間
–userns=”“ 啟動userns-remap時配置使用者名稱空間的模式
–uts=host 容器的UTS名稱空間
–restart=no 容器的重啟策略,包括no,no-failure[:max-retry],always,unless-stopped
–rm=true|false 容器退出後是否自動刪除,不能跟-d同時使用
-t, –tty=true|false 是否分配一個偽終端,預設為false
–tmpfs=[ ] 掛載臨時檔案系統到容器
-v | –volume[=[[HOST-DIR:]CONTAINER-DIR[:OPTIONS]]] 掛載主機上的檔案捲到容器內
–volume-driver=”“ 掛載檔案卷的驅動型別
–volumes-from=[ ] 從其他容器掛載卷
-w, –workdir=”“ 容器內預設的工作目錄

create命令與容器環境和配置相關的選項

選項 說明
–add-host=[ ] 在容器內hosts檔案中新增主機名到ip的對映
–device=[ ] 對映物理機上的裝置到容器內
–dns-search=[ ] DNS搜尋域
–dns-opt=[ ] 自定義的DNS選項
–dns=[ ] 自定義的DNS伺服器
-e,–env=[ ] 指定容器內環境變數
–env-file=[ ] 從檔案中讀取環境變數到容器內
-h,–hostname=”“ 指定容器內的主機名
–ip=”“ ip
–ip6=”“ ip6
–link=[:alias] 連結到其他容器
–mac-address=”“ 指定mac地址
–name=”“ 指定容器別名

create命令與容器資源限制和安全保護相關的選項

選項 說明
–blkio-weight=10-1000 容器讀寫塊裝置的IO效能權重,預設為0
–blkio-weight-device=[DEVICE_NAME:WEIGHT] 指定各個裝置的IO效能權重
-c, –cpu-shares=0 允許容器使用的CPU資源的相對權重,預設一個容器能用滿一個核的CPU
–cap-add=[ ] 增加容器的linux指定安全能力
–cap-drop=[ ] 移除容器的liunux指定安全能力
–cgroup-parent=”“ 容器cgroups限制的建立路徑
–cidfile=”“ 指定容器程序id號寫到的檔案
–cpu-period=0 限制容器CFS排程下CPU佔用時間片
–cpuset-cpus=”“ 限制容器能使用哪些CPU
–cpuset-mems=”“ NUMA架構下使用哪些核心的記憶體
–cpu-quota=0 限制容器CFS排程下CPU配額
–device-read-bps=[ ] 掛載裝置讀吞吐率限制 bps
–device-write-bps=[ ] 掛載裝置寫吞吐量限制 bps
–device-read-iops=[ ] 掛載裝置讀速率 單位為每秒io次數
–device-write-iops=[ ] 掛載裝置寫速率 單位為每秒io次數
–kernel-memory=”“ 限制容器記憶體使用大小
-m, –memory=”“ 限制容器內應用記憶體使用大小
–memory-reservation=”“ 記憶體過低時,容器被限制記憶體的指定值
–memory-swap= 限制容器使用記憶體和交換空間的總大小
–oom-kill-disable=true|false OOM時是否kill容器
–oom-score-adj=0 Tune host’s OOM preferences (-1000 to 1000)
–pids-limit=”“ 限制容器pid個數
–privileged=true|false 是否給容器高許可權,容器內應用將不受許可權限制
–read-only=true|false 是否讓容器內檔案系統只讀
–security-opt=[ ] 指定一些安全引數,包括許可權,安全能力,apparmor等
–stop-signal=”SIGTERM” 指定停止容器的系統訊號
–shm-size=”“ /dev/shm的大小
–memory-swappiness=-1 調整容器的記憶體交換區引數
-u, –user=”“ 指定容器內執行命令的使用者資訊
–ulimit=[ ] 通過ulimit來限制最大檔案數,最大程序數

其他重要引數

選項 說明
-l, –label=[ ] 以鍵值對方式指定容器的標籤資訊
–label-file=[ ] 從檔案中讀取標籤資訊

新建容器

新建立的容器狀態為Created

$ docker create -it ubuntu:latest #-it 開啟標準輸入,並建立偽終端

啟動/關閉容器

$ docker start 5cb
$ docker stop 5cb

容器狀態

動作 狀態
create Created
start Up
stop Exited

使用docker run新建並啟動容器

docker run 等價於 先執行docker create 在執行 docker start

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

docker run後臺執行的操作:
- 檢查本地是否存在映象,不存在從倉庫下載
- 利用映象建立一個容器,並啟動容器
- 分配一個檔案系統給容器,並在只讀層外面掛載一層可讀寫層
- 從宿主機配置的網橋介面中橋接一個虛擬介面道容器中
- 從網橋的地址池中配置一個ip地址給容器
- 執行使用者指定的應用程式
- 執行完畢後容器自動終止

docker run常見的錯誤

錯誤碼 錯誤原因
125 Docker daemon執行出錯,例如指定了不支援的命令引數
126 所指定的命令無法執行,例如許可權問題
127 容器內命令無法找到

守護態執行容器

-d引數

$ docker run -d ubuntu:14.04 /bin/sh -c  "while true; do echo hello; sleep 1; done"

獲取容器的輸出資訊

$ docker logs CID #CID 容器id

終止容器

$ docker stop CID #CID 容器id
$ docker stop -t 10 CID #10s後終止容器
$ docker kill CID #強制終止

重啟容器

$ docker restart CID

restart會將一個執行態的容器先終止然後重新啟動

進入容器

當容器使用-d引數執行時,容器自動進入後臺。使用者無法看到容器中的資訊,也無法對容器進行操作。

  • attach命令

  • exec命令

    $ docker run -itd ubuntu:14.04
    $ docker exec -it CID /bin/bash
  • nsenter工具

刪除容器

$ docker rm [-f|--force][-l|--link][-v|columes] CID [CID...]

-f 強制刪除,預設只能刪除終止或退出狀態的容器,-f會先終止,再刪除

-l 刪除容器連結,保留容器

-v 刪除容器掛載的資料卷

容器匯入匯出

容器可以匯出,無論它是否正在執行。匯出的容器可以匯入變為映象。匯出的容器與匯出的映象相比丟棄了所有的歷史記錄與元資料資訊,體積較小,匯入時可以重新執行元資料資訊。而映象所有記錄比較完整,體積相對也較大。

#匯出
$ docker export -o ./c_export_test.tar ca3
$ docker export ca3 > ./c_export_test.tar
# 匯入
$ docker import ./c_export_test.tar  test/ubuntu:01

使用Docker倉庫

概念

private-docker.com/ubuntu

註冊伺服器:註冊伺服器是存放倉庫的具體伺服器,一個註冊伺服器上可以存在很多個倉庫。private-docker.com是註冊伺服器地址。

倉庫:倉庫是存放映象的地方,一個倉庫可以存放很多映象。ubuntu就是註冊伺服器下的一個倉庫。

$ docker login -u username -p password
$ docker search centos
$ docker pull centos
#將映象push到倉庫
$ docker tag centos:latest jefferliu/centos:01
$ docker pull jefferliu/centos:01

關於自動建立

自動建立的映象,當映象內軟體有新版本時,不需要手動更新映象。

建立自動建立的步驟:

  • 建立並登陸DockerHub,以及目標網站;因為要在DockerHub連線到目標網站。目前DockerHub支援的目標網站有Github和Bitbucket。
  • 在DockerHub上建立一個自動構建;Create > Create Automated Build
  • 選擇連線到Github或Bitbucket,一個Github或Bitbucket賬戶只能連結一個DockerHub賬戶
  • 選取一個目標網站中的專案(需要含有Dockerfile)和分支
  • 指定Dockerfile的位置,並提交建立

搭建本地私有倉庫

先不做

Docker資料管理

容器中管理資料的兩種方式:

  • 資料卷(Data Volumes):容器內資料直接對映到本地主機環境
  • 資料卷容器(Data Volumes Containers):使用特定容器維護資料卷

資料卷

將主機作業系統目錄對映到容器內,類似linux的mount。

資料卷的特性:

  • 卷可以在容器間共享和重用,容器間傳遞資料將變得高效方便。
  • 對卷內資料的修改立即生效,無論在容器內還是在主機上。
  • 對資料卷的更新不影響映象,解耦了應用和資料。
  • 卷會一直存在,直到沒有容器使用,可完全解除安裝。

在容器內建立卷

$ docker run -it -v /dbdata --name dbdata ubuntu

掛載主機目錄作為卷

掛載主機目錄時,不會影響目錄內原有檔案與資料

$ docker run -it --name dbdata -v /tmp/docker:/dbdata ubuntu

資料卷容器

可以專門使用一個掛載了卷的容器作為資料卷容器,

# 資料卷容器
$ docker run -it -v /dbdata --name dbdata ubuntu
# 使用資料卷容器的容器 db1 和 db2
$ docker run -it --volume-form dbdata --name db1 ubuntu
$ docker run -it --volume-form dbdata --name db2 ubuntu

刪除資料卷

刪除掛載資料卷的容器時不會刪除資料卷,如果要刪除一個數據卷,必須在刪除最後一個引用它的容器時指定 -v 引數

$ docker stop dbdata
$ docker rm -v dbdata

刪除本地掛載的資料卷後,不影響本地資料夾內的資料和檔案

利用資料卷容器遷移資料

# 備份
$ docker run --volumes-from dbdata -v /tmp/docker:/backup --name worker ubuntu tar cxf /backup/backup.tar /dbdata
# 恢復
docker run -v /dbdata --name dbdata2 ubuntu
$ docker run --volumes-from dbdata2 -v /tmp/docker:/backup --name busybox ubuntu tar xvf /backup/backup.tar

埠對映與容器互聯

解決多個容器之間能夠互相訪問對方的服務。容器互聯有兩種方式,分別是:

  • 對映容器內服務埠到本機埠;
  • 容器互聯機制,通過容器名快速訪問;

埠對映

隨機介面

使用-P引數

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

-P引數會對映一個49000~49900的埠到容器內部開放的網路埠

指定埠

$ docker run -d -p 5000:5000 training/webapp python app.py
docker ps -l

如果指定了容器內沒有應用的服務埠,docker run命令不會失敗

容器啟動後用docker ps -l 檢視容器時PORTS顯示的資訊為:

0.0.0.0:5000->5000/tcp

對映到非服務埠,PORTS顯示的資訊為:

5000/tcp, 0.0.0.0:5000->5001/tcp

這能助於排除埠對映是否正確,容器在5000埠提供tcp連結,本地5000埠卻對映到5001埠上。

同時指定多個埠

$ docker run -d -p 5000:5000 -p 3000:80 training/webapp python app.py
docker ps -l

對映到指定地址的指定埠

這種情況當主機有多網絡卡時有用

# ip地址必須有效
$ docker run -d -p 192.168.1.100:5000:5000 -p 192.168.2.110:3000:80 training/webapp python app.py
docker ps -l

對映到指定地址任意埠

# ip地址必須有效
$ docker run -d -p 127.0.0.1::5000 training/webapp python app.py
docker ps -l

對映UDP埠

# ip地址必須有效
$ docker run -d -p 127.0.0.1::5000/udp training/webapp python app.py
docker ps -l

檢視埠對映

$ docker port CID

與docker ps -l 檢視容器時PORTS顯示的對映資訊相反

互聯機制

Container linking

會用 –link 引數可以讓容器之間安全地進行互動。Docker相當於在兩個互聯的容器間建立了一個虛擬通道,而且不用對映他們的埠到宿主機上。

Docker通過兩種方式為容器公開連結資訊:

  • 更新環境變數
  • 更新host檔案

例項

# 建立資料庫容器
$ docker run -d --name db training/postgres
$ docker run -d --name web --link db:db training/webapp python app.py
# 進入web容器,檢視env和host檔案
$ docker exec -it web /bin/bash

使用docker ps檢視容器names列中並不能體現互聯資訊,Version 17.09.1-ce-mac42

在網路環境複雜情況下,容器需要需要跨主機甚至跨資料中心的通訊,需要引入額外的機制,例如SDN或NFV。

使用Dockerfile建立映象

可以使用Dockerfile建立自定義映象。Dockerfile有其典型的結構,並且支援很多命令。

Dockerfile命令

命令 說明
FROM 指定所建立映象的基礎映象
MAINTAINER 維護者資訊
RUN 執行命令
CMD 指定啟動容器時執行的命令
LABEL 指定生成映象的元資料標籤資訊
EXPOSE 生命映象內服務所監聽的埠
ENV 指定環境變數
ADD 複製指定的src/url所指定的內容到dest路徑下。若是tar,自動解壓,不推薦
COPY 複製指定的src/url所指定的內容到dest路徑下。推薦使用
ENTRYPOINT 指定映象預設入口
VOLUME 建立資料卷掛載點
USER 指定執行容器時的使用者名稱或uid
WORKDIR 配置工作目錄
ARG 指定映象內使用的引數 (例如版本資訊)
ONBUILD 配置當所建立的映象作為其他映象的基礎映象時,所執行的建立操作命令
STOPSIGNAL 容器退出的訊號值
HEALTHCHECK 如何進行健康檢查
SHELL 指定使用shell時預設的shell型別

FROM

格式:

FROM <image>
FROM <image>:<tag>
FROM <image>@<digest>

要建立映象的基礎映象。若不存在,則去Dockerhub下載。任何Dockerfile第一行命令必須是From指令。

如果在一個Dockerfile中建立多個映象,可以使用多個FORM命令,每個映象一次

MAINTAINER

MAINTAINER docker_user docker_user@email.com

該資訊會寫入生成映象的Author屬性中。

RUN

RUN <command> #在shell終端執行
RUN ["executable" , "param1" , "param2"] #使用exec執行,不啟動shell環境

每條run指令將在當前映象的基礎上執行指定命令,並提交為新的映象。當命令較長時可以使用 \ 換行

例如:

RUN apt-get update \
    && apt-get install -y libsnappy-dev zliblg-dev libbz2-dev \
    && rm -rf /var/cache/apt

CMD

每個Dockerfile中只能有一個CMD命令。若出現多個,前面的將被覆蓋。

如果啟動容器時手動指定了執行的命令,則會覆蓋CMD指定的命令。

# 推薦使用的方式
CMD ["executable" , "param1" , "param2"] #使用exec執行,不啟動shell環境
# 在、bin/sh中執行,提供給需要互動的應用
CMD command param1 param2
# 提供給ENTRYPOING的預設引數
CMD ["param1" , "param2"]

LABEL

用來指定生成映象的原資料標籤資訊

LABLE <key>=<value>

例如:

LABEL version="1.0"
LABEL description="this is a fun images"

EXPOSE

生命映象內服務所監聽的埠

EXPOSE port [port , port , ...]

只起到宣告作用,並不會自動完成埠對映
要完成埠對映,需要在啟動容器時使用-P或-p引數

ENV

指定環境變數,在Dockerfile中會被後續指令中使用,在映象啟動的容器中也會繼續存在。

ENV <KEY> <VALUE>
ENV <KEY>=<VALUE>

例如:

ENV JAVA_VARSION 1.7
RUN curl -SL http://downloadjava/${JAVA_VERSION}
ENV PATH /usr/local/java_${JAVA_VERSION}/bin:$PATH

已指定的環境變數在執行時可以使用run命令覆蓋,docker run –env =

ADD

複製指定路徑下的內容到容器總的目標路徑

ADD <src> <dest>

src是相對於dockerfile所在目錄的一個相對路徑或檔案,也可以是一個RUL或tar檔案(tar檔案上傳後會自動解壓)。
dest是映象內的絕對路徑或相對於工作目錄(WORKERDIR)的相對路徑。

例如:

ADD *.java /code/

COPY

與ADD命令功能作用相同。

目標路徑不存在時會自動建立。

當使用本地目錄為src時,推薦使用COPY。

ENTRYPOINT

指定映象的預設入口命令,該入口命令會在容器啟動時作為跟命令執行,所有傳入值作為該命令的引數。

ENTRYPOINT ["executable" , "param1" , "param2"] #使用exec執行
# 在、bin/sh中執行
ENTRYPOINT command param1 param2

當指定ENTRYPOINT後,CMD指令將作為根命令的引數。

Dockerfile中只能有一個ENTRYPOINT,多個時只有最後一個有效,使用docker run –entrypoint引數可以覆蓋。

VOLUME

建立一個數據卷掛載點,是點,沒有進行掛載

VOLUME ["/data"]

WORKDIR

為後續的RUN , CMD , ENTRYPOINT指令配置工作目錄

WORKDIR /path/to/dir

可以使用多個WORKDIR指令,若後續指令引數是相對路徑,則會基於指點的指令指定的路徑。

ARG

指定映象內使用的引數,這些引數在執行docker build命令時以–build-arg =形式傳入。

ARG <name>=[<default value>]

ONBUILD

配置當前映象作為其他映象的基礎映象時,所指定的建立操作指令。等價於在新映象的Dockerfile中增加的命令。

例如:

ONBUILD ADD . /app/src
ONBUILD RUN ....

HEALTHCHECK

配置所啟動容器如何新型健康檢查,有兩種格式:

  • HEALTHCHECK [OPTIONS] CMD command:根據所執行命令是否返回0來判斷;
  • HEALTHCHECK NONE:禁止健康檢查;

OPTION支援:

  • –interval=DURATION:檢查間隔,預設30s;
  • –timeout=DURATION;
  • –retries=N:重試幾次最終確認失敗;

SHELL

指定其他命令使用shell時預設的shell

SHELL ["executable" , "parameters"] #預設["/bin/sh", "-c"]

建立映象

$ docker build [option]

如果使用非內容路徑下的Dockerfile,可以通過-f引數指定其路徑。

要指定生成映象的標籤資訊,使用-t引數。

例如:

$ docker build -t jefferliu/ubuntu_test:01 /temp/docker

使用.dockerignore檔案

在檔案中每一行新增一條匹配模式,讓Docker忽略匹配模式路徑下的目錄檔案。例如:

# comment
  */temp*
  */*/temp*
  tmp?
  ~*