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?
~*