> 原文:http://www.infoq.com/cn/articles/docker-command-line-quest
## 1\. Docker命令行
Docker官方為了讓用戶快速了解Docker,提供了一個[交互式教程](https://www.docker.com/tryit/#0),旨在幫助用戶掌握Docker命令行的使用方法。但是由于Docker技術的快速發展,此交互式教程已經無法滿足Docker用戶的實際使用需求,所以讓我們一起開始一次真正的命令行學習之旅。首先,Docker的命令清單可以通過運行docker?,或者?docker help?命令得到:
~~~
$ sudo docker
~~~

在Docker容器技術不斷演化的過程中,Docker的子命令已經達到34個之多,其中核心子命令(例如:run)還會有復雜的參數配置。筆者通過結合功能和應用場景方面的考慮,把命令行劃分為4個部分,方便我們快速概覽Docker命令行的組成結構:
| 功能劃分 | 命令 |
|---|---|
| 環境信息相關 | 1. info<br/>2. version |
| 系統運維相關 | 1. attach<br/>2. build<br/>3. commit<br/>4. cp<br/>5. diff<br/>6. export<br/>7. images<br/>8. import / save / load<br/>9. inspect<br/>10. kill<br/>11. port<br/>12. pause / unpause<br/>13. ps<br/>14. rm<br/>15. rmi<br/>16. run<br/>17. start / stop / restart<br/>18. tag<br/>19. top<br/>20. wait |
| 日志信息相關 | 1. events<br/>2. history<br/>3. logs |
| Docker Hub服務相關 | 1. login<br/>2. pull / push<br/>3. search|
### 1.1 參數約定
單個字符的參數可以放在一起組合配置,例如
~~~
docker run -t -i --name test busybox sh
~~~
可以用這樣的方式等同:
~~~
docker run -ti --name test busybox sh
~~~
### 1.2 Boolean
Boolean參數形式如: -d=false。注意,當你聲明這個Boolean參數時,比如 docker run -d=true,它將直接把啟動的Container掛起放在后臺運行。
### 1.3 字符串和數字
參數如 --name=“” 定義一個字符串,它僅能被定義一次。同類型的如-c=0 定義一個數字,它也只能被定義一次。
### 1.4 后臺進程
Docker后臺進程是一個常駐后臺的系統進程,值得注意的是Docker使用同一個文件來支持客戶端和后臺進程,其中角色切換通過-d來實現。這個后臺進程是用來管理容器的,使用Docker --help可以得到更詳細的功能參數配置, 如下圖:

Docker后臺進程參數清單如下表:
| 參數 | 解釋 |
|---|---|
| --api-enable-cors=false | 開放遠程API調用的?[CORS 頭信息](https://en.wikipedia.org/wiki/Cross-Origin_Resource_Sharing)。這個接口開關對想進行二次開發的上層應用提供了支持。 |
| -b, --bridge="" | 掛載已經存在的網橋設備到 Docker 容器里。注意,使用?none?可以停用容器里的網絡。 |
| --bip="" | 使用?[CIDR](https://en.wikipedia.org/wiki/CIDR_notation)?地址來設定網絡橋的 IP。注意,此參數和 -b 不能一起使用。 |
| -D, --debug=false | 開啟Debug模式。例如:docker -d -D |
| -d, --daemon=false | 開啟Daemon模式。 |
| --dns=[] | 強制容器使用DNS服務器。例如: docker -d --dns 8.8.8.8 |
| --dns-search=[] | 強制容器使用指定的DNS搜索域名。例如: docker -d --dns-search example.com |
| -e, --exec-driver="native" | 強制容器使用指定的運行時驅動。例如:docker -d -e lxc |
| -G, --group="docker" | 在后臺運行模式下,賦予指定的Group到相應的unix socket上。注意,當此參數 --group 賦予空字符串時,將去除組信息。 |
| -g, --graph="/var/lib/docker" | 配置Docker運行時根目錄 |
| -H, --host=[] | 在后臺模式下指定socket綁定,可以綁定一個或多個 tcp://host:port, unix:///path/to/socket, fd://* 或 fd://socketfd。例如:<br/>$ docker -H tcp://0.0.0.0:2375 ps 或者<br/>$ export DOCKER_HOST="tcp://0.0.0.0:2375"<br/>$ docker ps |
| --icc=true | 啟用內聯容器的通信。 |
| --ip="0.0.0.0" | 容器綁定IP時使用的默認IP地址 |
| --ip-forward=true | 啟動容器的 net.ipv4.ip_forward |
| --iptables=true | 啟動Docker容器自定義的iptable規則 |
| --mtu=0 | 設置容器網絡的MTU值,如果沒有這個參數,選用默認 route MTU,如果沒有默認route,就設置成常量值 1500。 |
| -p, --pidfile="/var/run/docker.pid" | 后臺進程PID文件路徑。 |
| -r, --restart=true | 重啟之前運行中的容器 |
| -s, --storage-driver="" | 強制容器運行時使用指定的存儲驅動,例如,指定使用devicemapper, 可以這樣:<br/>docker -d -s devicemapper |
| --selinux-enabled=false | 啟用selinux支持 |
| --storage-opt=[] | 配置存儲驅動的參數 |
| --tls=false | 啟動TLS認證開關 |
| --tlscacert="/Users/dxiao/.docker/ca.pem" | 通過CA認證過的的certificate文件路徑 |
| --tlscert="/Users/dxiao/.docker/cert.pem" | TLS的certificate文件路徑 |
| --tlskey="/Users/dxiao/.docker/key.pem" | TLS的key文件路徑 |
| --tlsverify=false | 使用TLS并做后臺進程與客戶端通訊的驗證 |
| -v, --version=false | 顯示版本信息 |
注意,其中帶有[] 的啟動參數可以指定多次,例如
~~~
$ docker run -a stdin -a stdout -a stderr -i -t ubuntu /bin/bash
~~~
## 2\. Docker命令行探秘
### 2.1 環境信息相關
info
使用方法: docker info
例子:
~~~
[fedora@docker-devel-cli docker]$ sudo docker -D info
Containers: 0
Images: 32
Storage Driver: devicemapper
Pool Name: docker-252:1-130159-pool
Data file: /var/lib/docker/devicemapper/devicemapper/data
Metadata file: /var/lib/docker/devicemapper/devicemapper/metadata
Data Space Used: 1616.9 Mb
Data Space Total: 102400.0 Mb
Metadata Space Used: 2.4 Mb
Metadata Space Total: 2048.0 Mb
Execution Driver: native-0.2
Kernel Version: 3.11.10-301.fc20.x86_64
Debug mode (server): false
Debug mode (client): true
Fds: 11
Goroutines: 14
EventsListeners: 0
Init SHA1: 2c5adb59737b8a01fa3fb968519a43fe140bc9c9
Init Path: /usr/libexec/docker/dockerinit
Sockets: [fd://]
~~~
使用說明:
這個命令在開發者報告Bug時會非常有用,結合docker vesion一起,可以隨時使用這個命令把本地的配置信息提供出來,方便Docker的開發者快速定位問題。
version
使用方法: docker version
使用說明:
顯示Docker的版本號,API版本號,Git commit, Docker客戶端和后臺進程的Go版本號。
### 2.2 系統運維相關
attach
使用方法: docker attach [OPTIONS] CONTAINER
例子:
~~~
$ ID=$(sudo docker run -d ubuntu /usr/bin/top -b)
$ sudo docker attach $ID
top - 17:21:49 up 5:53, 0 users, load average: 0.63, 1.15, 0.78
Tasks: 1 total, 1 running, 0 sleeping, 0 stopped, 0 zombie
%Cpu(s): 1.0 us, 0.7 sy, 0.0 ni, 97.7 id, 0.7 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem: 2051644 total, 723700 used, 1327944 free, 33032 buffers
KiB Swap: 0 total, 0 used, 0 free. 565836 cached Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 19748 1280 1008 R 0.0 0.1 0:00.04 top
$ sudo docker stop $ID
~~~
使用說明:
使用這個命令可以掛載正在后臺運行的容器,在開發應用的過程中運用這個命令可以隨時觀察容器內進程的運行狀況。開發者在開發應用的場景中,這個命令是一個非常有用的命令。
build
使用方法:docker build [OPTIONS] PATH | URL | -
例子:
~~~
$ docker build .
Uploading context 18.829 MB
Uploading context
Step 0 : FROM busybox
---> 769b9341d937
Step 1 : CMD echo Hello world
---> Using cache
---> 99cc1ad10469
Successfully built 99cc1ad10469
~~~
使用說明:
這個命令是從源碼構建新Image的命令。因為Image是分層的,最關鍵的Base Image是如何構建的是用戶比較關心的,Docker官方文檔給出了構建方法,請參考[這里](http://docs.docker.com/articles/baseimages/)。
commit
使用方法:docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
例子:
~~~
$ sudo docker ps
ID IMAGE COMMAND CREATED STATUS PORTS
c3f279d17e0a ubuntu:12.04 /bin/bash 7 days ago Up 25 hours
197387f1b436 ubuntu:12.04 /bin/bash 7 days ago Up 25 hours
$ docker commit c3f279d17e0a SvenDowideit/testimage:version3
f5283438590d
$ docker images | head
REPOSITORY TAG ID CREATED VIRTUAL SIZE
SvenDowideit/testimage version3 f5283438590d 16 seconds ago 335.7 MB
~~~
使用說明:
這個命令的用處在于把有修改的container提交成新的Image,然后導出此Imange分發給其他場景中調試使用。Docker官方的建議是,當你在調試完Image的問題后,應該寫一個新的Dockerfile文件來維護此Image。commit命令僅是一個臨時創建Imange的輔助命令。
cp
使用方法: cp CONTAINER:PATH HOSTPATH
使用說明:
使用cp可以把容器內的文件復制到Host主機上。這個命令在開發者開發應用的場景下,會需要把運行程序產生的結果復制出來的需求,在這個情況下就可以使用這個cp命令。
diff
使用方法:docker diff CONTAINER
例子:
~~~
$ sudo docker diff 7bb0e258aefe
C /dev
A /dev/kmsg
C /etc
A /etc/mtab
A /go
A /go/src
A /go/src/github.com
A /go/src/github.com/dotcloud
....
~~~
使用說明:
diff會列出3種容器內文件狀態變化(A - Add, D - Delete, C - Change )的列表清單。構建Image的過程中需要的調試指令。
export
使用方法:docker export CONTAINER
例子:
~~~
$ sudo docker export red_panda > latest.tar
~~~
使用說明:
把容器系統文件打包并導出來,方便分發給其他場景使用。
images
使用方法:docker images [OPTIONS] [NAME]
例子:
~~~
$ sudo docker images | head
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
<none> <none> 77af4d6b9913 19 hours ago 1.089 GB
committest latest b6fa739cedf5 19 hours ago 1.089 GB
<none> <none> 78a85c484f71 19 hours ago 1.089 GB
$ docker latest 30557a29d5ab 20 hours ago 1.089 GB
<none> <none> 0124422dd9f9 20 hours ago 1.089 GB
<none> <none> 18ad6fad3402 22 hours ago 1.082 GB
<none> <none> f9f1e26352f0 23 hours ago 1.089 GB
tryout latest 2629d1fa0b81 23 hours ago 131.5 MB
<none> <none> 5ed6274db6ce 24 hours ago 1.089 GB
~~~
使用說明:
Docker Image是多層結構的,默認只顯示最頂層的Image。不顯示的中間層默認是為了增加可復用性、減少磁盤使用空間,加快build構建的速度的功能,一般用戶不需要關心這個細節。
import / save / load
使用方法:
~~~
docker import URL|- [REPOSITORY[:TAG]]
docker save IMAGE
docker load
~~~
使用說明:
這一組命令是系統運維里非常關鍵的命令。加載(兩種方法: import, load),導出(一種方法: save)容器系統文件。
inspect
使用方法:
~~~
docker inspect CONTAINER|IMAGE [CONTAINER|IMAGE...]
~~~
例子:
~~~
$ sudo docker inspect --format='{{.NetworkSettings.IPAddress}}' $INSTANCE_ID
~~~
使用說明:
查看容器運行時詳細信息的命令。了解一個Image或者Container的完整構建信息就可以通過這個命令實現。
kill
使用方法:
~~~
docker kill [OPTIONS] CONTAINER [CONTAINER...]
~~~
使用說明:
殺掉容器的進程。
port
使用方法:
~~~
docker port CONTAINER PRIVATE_PORT
~~~
使用說明:
打印出Host主機端口與容器暴露出的端口的NAT映射關系
pause / unpause
使用方法:
~~~
docker pause CONTAINER
~~~
使用說明:
使用cgroup的freezer順序暫停、恢復容器里的所有進程。詳細freezer的特性,請參考[官方文檔](https://www.kernel.org/doc/Documentation/cgroups/freezer-subsystem.txt)。
ps
使用方法:
~~~
docker ps [OPTIONS]
~~~
例子:
~~~
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4c01db0b339c ubuntu:12.04 bash 17 seconds ago Up 16 seconds webapp
d7886598dbe2 crosbymichael/redis:latest /redis-server --dir 33 minutes ago Up 33 minutes 6379/tcp redis,webapp/db
~~~
使用說明:
docker ps打印出正在運行的容器,docker ps -a打印出所有運行過的容器。
rm
使用方法:
~~~
docker rm [OPTIONS] CONTAINER [CONTAINER...]
~~~
例子:
~~~
$ sudo docker rm /redis
/redis
~~~
使用說明:
刪除指定的容器。
rmi
使用方法:
~~~
docker rmi IMAGE [IMAGE...]
~~~
例子:
~~~
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test1 latest fd484f19954f 23 seconds ago 7 B (virtual 4.964 MB)
test latest fd484f19954f 23 seconds ago 7 B (virtual 4.964 MB)
test2 latest fd484f19954f 23 seconds ago 7 B (virtual 4.964 MB)
$ sudo docker rmi fd484f19954f
Error: Conflict, cannot delete image fd484f19954f because it is tagged in multiple repositories
2013/12/11 05:47:16 Error: failed to remove one or more images
$ sudo docker rmi test1
Untagged: fd484f19954f4920da7ff372b5067f5b7ddb2fd3830cecd17b96ea9e286ba5b8
$ sudo docker rmi test2
Untagged: fd484f19954f4920da7ff372b5067f5b7ddb2fd3830cecd17b96ea9e286ba5b8
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test latest fd484f19954f 23 seconds ago 7 B (virtual 4.964 MB)
$ sudo docker rmi test
Untagged: fd484f19954f4920da7ff372b5067f5b7ddb2fd3830cecd17b96ea9e286ba5b8
Deleted: fd484f19954f4920da7ff372b5067f5b7ddb2fd3830cecd17b96ea9e286ba5b8
~~~
使用說明:
指定刪除Image文件。
run
使用方法:
~~~
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
~~~
例子:
~~~
$ sudo docker run --cidfile /tmp/docker_test.cid ubuntu echo "test"
~~~
使用說明:
這個命令是核心命令,可以配置的參數多達28個參數。詳細的解釋可以通過docker run --help列出。官方文檔中提到的?[Issue 2702](https://github.com/dotcloud/docker/issues/2702):"lxc-start: Permission denied - failed to mount" could indicate a permissions problem with AppArmor. 在最新版本的Dcoker中已經解決。
start / stop / restart
使用方法:
~~~
docker start CONTAINER [CONTAINER...]
~~~
使用說明:
這組命令可以開啟(兩個:start, restart),停止(一個:stop)一個容器。
tag
使用方法:
~~~
docker tag [OPTIONS] IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]
~~~
使用說明:
組合使用用戶名,Image名字,標簽名來組織管理Image。
top
使用方法:
~~~
docker top CONTAINER [ps OPTIONS]
~~~
使用說明:
顯示容器內運行的進程。
wait
使用方法:
~~~
docker wait CONTAINER [CONTAINER...]
~~~
使用說明:
阻塞對指定容器的其他調用方法,直到容器停止后退出阻塞。
### 2.3 日志信息相關
events
使用方法:
~~~
docker events [OPTIONS]
~~~
使用說明:
打印容器實時的系統事件。
history
使用方法:
~~~
docker history [OPTIONS] IMAGE
~~~
例子:
~~~
$ docker history docker
IMAGE CREATED CREATED BY SIZE
3e23a5875458790b7a806f95f7ec0d0b2a5c1659bfc899c89f939f6d5b8f7094 8 days ago
/bin/sh -c #(nop) ENV LC_ALL=C.UTF-8 0 B
8578938dd17054dce7993d21de79e96a037400e8d28e15e7290fea4f65128a36 8 days ago
/bin/sh -c dpkg-reconfigure locales && locale-gen C.UTF-8 &&
/usr/sbin/update-locale LANG=C.UTF-8 1.245 MB
be51b77efb42f67a5e96437b3e102f81e0a1399038f77bf28cea0ed23a65cf60 8 days ago /bin/sh
-c apt-get update && apt-get install -y git libxml2-dev python build-essential
make gcc python-dev locales python-pip 338.3 MB
4b137612be55ca69776c7f30c2d2dd0aa2e7d72059820abf3e25b629f887a084 6 weeks ago
/bin/sh -c #(nop) ADD jessie.tar.xz in / 121 MB
750d58736b4b6cc0f9a9abe8f258cef269e3e9dceced1146503522be9f985ada 6 weeks ago
/bin/sh -c #(nop) MAINTAINER Tianon Gravi <admwiggin@gmail.com>
- mkimage-debootstrap.sh -t jessie.tar.xz jessie http://http.debian.net/debian 0 B
511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158 9 months ago 0 B
~~~
使用說明:
打印指定Image中每一層Image命令行的歷史記錄。
logs
使用方法:
~~~
docker logs CONTAINER
~~~
使用說明:
批量打印出容器中進程的運行日志。
### 2.4 Dcoker Hub服務相關
login
使用方法:
~~~
docker login [OPTIONS] [SERVER]
~~~
使用說明:
登錄Hub服務。
pull / push
使用方法:
~~~
docker push NAME[:TAG]
~~~
使用說明:
通過此命令分享Image到Hub服務或者自服務的Registry服務。
search
使用方法:
~~~
docker search TERM
~~~
使用說明:
通過關鍵字搜索分享的Image。
## 3\. 總結
通過以上Docker命令行的詳細解釋,可以強化對Docker命令的全面理解。考慮到Docker命令行的發展變化非常快,讀者可以參考官方的[命令行解釋](http://docs.docker.com/reference/commandline/cli/)文檔更新相應的命令行解釋。另外,通過以上Docker命令行的分析,可以知道Docker命令行架構設計的特點在于客戶端和服務端的運行文件是同一個文件,內部實現代碼應該是重用的設計。筆者希望開發者在開發類似的命令行應用時參考這樣的設計,減少前后臺容錯的復雜度。
## 參考文獻
[1]?[https://docs.docker.com/reference/commandline/cli/](https://docs.docker.com/reference/commandline/cli/)
[2]?[https://en.wikipedia.org/wiki/Cross-Origin_Resource_Sharing](https://en.wikipedia.org/wiki/Cross-Origin_Resource_Sharing)
[3]?[https://en.wikipedia.org/wiki/CIDR_notation#CIDR_notation](https://en.wikipedia.org/wiki/CIDR_notation#CIDR_notation)