Docker 調試技巧

『重用』容器名

但咱們在編寫/調試Dockerfile的時候咱們常常會重複以前的command,好比這種docker run --name jstorm-zookeeper zookeeper:3.4,而後就容器名就衝突了。java

$ docker run --name jstorm-zookeeper zookeeper:3.4
...
$ docker run --name jstorm-zookeeper zookeeper:3.4
docker: Error response from daemon: Conflict. The name "/jstorm-zookeeper" is already in use by container xxxxxxxxx

能夠在運行 docker run 時候加上--rm flag, 容器將在退出以後銷燬。無需手動docker rm CONTAINERlinux

$ docker run --name jstorm-zookeeper zookeeper:3.4 --rm

# reuse 
$ docker create --name jstorm-zookeeper zookeeper:3.4
$ docker start jstorm-zookeeper

# no error

<!-- more -->docker

debug Dockerfile

在寫 Dockerfile 的時候,一般並不會一鼓作氣。有的時候容器啓動就crash 直接退出,有的時候build image 就會失敗,或者想驗證Dockerfile是否符合預期,咱們常常要debug Dockerfile。shell

若是build 失敗能夠直接 查看stdout的錯誤信息,拆分指令,從新build。api

logs 查看 stdout

全部容器內寫到stdout的內容都會被捕獲到host中的一個history文件中, 能夠經過 docker logs CONTAINER 查看。bash

$ docker run -d --name jstorm-zookeeper zookeeper:3.4

$ docker logs jstorm-zookeeper
ZooKeeper JMX enabled by default
Using config: /conf/zoo.cfg
2016-12-18 05:55:27,717 [myid:] - INFO  [main:QuorumPeerConfig@124] - Reading configuration from: /conf/zoo.cfg
2016-12-18 05:55:27,725 [myid:] - INFO  [main:DatadirCleanupManager@78] - autopurge.snapRetainCount set to 3
2016-12-18 05:55:27,725 [myid:] - INFO  [main:DatadirCleanupManager@79] - autopurge.purgeInterval set to 0
2016-12-18 05:55:27,726 [myid:] - INFO  [main:DatadirCleanupManager@101] - Purge task is not scheduled.
2016-12-18 05:55:27,728 [myid:] - WARN  [main:QuorumPeerMain@113] - Either no config or no quorum defined in config, running  in standalone mode
2016-12-18 05:55:27,746 [myid:] - INFO  [main:QuorumPeerConfig@124] - Reading configuration from: /conf/zoo.cfg
2016-12-18 05:55:27,747 [myid:] - INFO  [main:ZooKeeperServerMain@96] - Starting server
2016-12-18 05:55:27,766 [myid:] - INFO  [main:Environment@100] - Server environment:zookeeper.version=3.4.9-1757313, built on 08/23/2016 06:50 GMT
2016-12-18 05:55:27,766 [myid:] - INFO  [main:Environment@100] - Server environment:host.name=dbc742dd5688
2016-12-18 05:55:27,767 [myid:] - INFO  [main:Environment@100] - Server environment:java.version=1.8.0_111-internal

即便是容器已經退出的也能夠看到,因此能夠經過這種方式來分析非預期的退出。這些文件一直保存着,直到經過docker rm把容器刪除。文件的具體路徑能夠經過docker inspect CONTAINER 得到。
(而後osx上你並找不到這些文件,由於其實osx的docker實際是運行在"VM"中,具體就不展開了,可是能夠經過 screen ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty touch上"VM"的tty)jvm

在使用docker logs 的時候加一些參數來過濾log,默認輸出全部log。ide

Options:
      --details        Show extra details provided to logs
  -f, --follow         Follow log output
      --help           Print usage
      --since string   Show logs since timestamp
      --tail string    Number of lines to show from the end of the logs (default "all")
  -t, --timestamps     Show timestamps

attach 實時查看stdout

若是你想實時查看容器的輸出你能夠用 docker attach CONTAINER 命令。ui

默認會綁定stdin,代理signals, 因此若是你 ctrl-c 容器一般會退出。不少時候你們並不想這樣,只是想分離開,能夠ctrl-p ctrl-qdebug

執行任意command

能夠經過docker exec CONTAINER COMMAND,來在容器內執行任意 command,好比 cat 一些東西來debug。

$ docker run -d --name jstorm-zookeeper zookeeper:3.4

$ docker exec jstorm-zookeeper java -version
openjdk version "1.8.0_111-internal"
OpenJDK Runtime Environment (build 1.8.0_111-internal-alpine-r0-b14)
OpenJDK 64-Bit Server VM (build 25.111-b14, mixed mode)

也能夠直接經過 exec 在容器內啓動一個 shell 更方便地調試容器,沒必要一條條執行docker exec

$ docker exec -it jstorm-zookeeper /bin/bash
bash-4.3# pwd
/zookeeper-3.4.9

docker exec 只能在正在運行的容器上使用,若是已經中止了退出了就不行了,就只好用 docker logs 了。

重寫entrypointcmd

每一個Docker鏡像都有 entrypointcmd , 能夠定義在 Dockerfile 中,也能夠在運行時指定。這兩個概念很容易混淆,並且它們的試用方式也不一樣。

entrypointcmd 更"高級",entrypoint 做爲容器中pid爲1的進程運行(docker不是虛擬機,只是隔離的進程。真正的linux中pid爲1的是init)。
cmd 只是 entrypoint的參數:

<ENTRYPOINT> "<CMD>"

當咱們沒有指定 entrypoint 時缺省爲 /bin/sh -c。因此其實 entrypoint 是真正表達這個docker應該幹什麼的,一般你們有一個shell 腳原本代理。
entrypointcmd 均可以在運行的時候更改,經過更改來看這樣設置entrypoint是否優雅合理。

$ docker run -it --name jstorm-zookeeper --entrypoint /bin/bash zookeeper:3.4
bash-4.3# top
Mem: 320212K used, 1725368K free, 89112K shrd, 35532K buff, 130532K cached
CPU:   0% usr   0% sys   0% nic 100% idle   0% io   0% irq   0% sirq
Load average: 0.20 0.06 0.02 5/195 7
  PID  PPID USER     STAT   VSZ %VSZ CPU %CPU COMMAND
    1     0 root     S     6220   0%   0   0% /bin/bash
    7     1 root     R     1516   0%   2   0% top

任何 docker run 命令中在image名後的內容都做爲cmd的內容傳給 entrypoint當參數。

暫停容器

使用 docker pause 能夠暫停容器中全部進程。這很是有用。

$ docker run -d --name jstorm-zookeeper zookeeper:3.4 && sleep 0.1 && docker pause jstorm-zookeeper && docker logs jstorm-zookeeper
a24405a53ddd9b7d94d9e77fe2b5a67639a251d681aa2f34fcb0cc96f347ba48
jstorm-zookeeper
ZooKeeper JMX enabled by default
Using config: /conf/zoo.cfg
2016-12-18 16:17:47,720 [myid:] - INFO  [main:QuorumPeerConfig@124] - Reading configuration from: /conf/zoo.cfg
2016-12-18 16:17:47,730 [myid:] - INFO  [main:DatadirCleanupManager@78] - autopurge.snapRetainCount set to 3
2016-12-18 16:17:47,730 [myid:] - INFO  [main:DatadirCleanupManager@79] - autopurge.purgeInterval set to 0
2016-12-18 16:17:47,730 [myid:] - INFO  [main:DatadirCleanupManager@101] - Purge task is not scheduled.
2016-12-18 16:17:47,731 [myid:] - WARN  [main:QuorumPeerMain@113] - Either no config or no quorum defined in config, running  in standalone mode
2016-12-18 16:17:47,757 [myid:] - INFO  [main:QuorumPeerConfig@124] - Reading configuration from: /conf/zoo.cfg
2016-12-18 16:17:47,757 [myid:] - INFO  [main:ZooKeeperServerMain@96] - Starting server

$ docker unpause jstorm-zookeeper && docker logs jstorm-zookeeper
jstorm-zookeeper
ZooKeeper JMX enabled by default
Using config: /conf/zoo.cfg
2016-12-18 16:17:47,720 [myid:] - INFO  [main:QuorumPeerConfig@124] - Reading configuration from: /conf/zoo.cfg
2016-12-18 16:17:47,730 [myid:] - INFO  [main:DatadirCleanupManager@78] - autopurge.snapRetainCount set to 3
2016-12-18 16:17:47,730 [myid:] - INFO  [main:DatadirCleanupManager@79] - autopurge.purgeInterval set to 0
2016-12-18 16:17:47,730 [myid:] - INFO  [main:DatadirCleanupManager@101] - Purge task is not scheduled.
2016-12-18 16:17:47,731 [myid:] - WARN  [main:QuorumPeerMain@113] - Either no config or no quorum defined in config, running  in standalone mode
2016-12-18 16:17:47,757 [myid:] - INFO  [main:QuorumPeerConfig@124] - Reading configuration from: /conf/zoo.cfg
2016-12-18 16:17:47,757 [myid:] - INFO  [main:ZooKeeperServerMain@96] - Starting server
2016-12-18 16:18:09,039 [myid:] - INFO  [main:Environment@100] - Server environment:zookeeper.version=3.4.9-1757313, built on 08/23/2016 06:50 GMT
2016-12-18 16:18:09,040 [myid:] - INFO  [main:Environment@100] - Server environment:host.name=a24405a53ddd
2016-12-18 16:18:09,040 [myid:] - INFO  [main:Environment@100] - Server environment:java.version=1.8.0_111-internal
2016-12-18 16:18:09,040 [myid:] - INFO  [main:Environment@100] - Server environment:java.vendor=Oracle Corporation
2016-12-18 16:18:09,040 [myid:] - INFO  [main:Environment@100] - Server environment:java.home=/usr/lib/jvm/java-1.8-openjdk/jre
2016-12-18 16:18:09,040 [myid:] - INFO  [main:Environment@100] - Server environment:java.class.path=/zookeeper-3.4.9/bin/../build/classes:/zookeeper-3.4.9/bin/../build/lib/*.jar:/zookeeper-3.4.9/bin/../lib/slf4j-log4j12-1.6.1.jar:/zookeeper-3.4.9/bin/../lib/slf4j-api-1.6.1.jar:/zookeeper-3.4.9/bin/../lib/netty-3.10.5.Final.jar:/zookeeper-3.4.9/bin/../lib/log4j-1.2.16.jar:/zookeeper-3.4.9/bin/../lib/jline-0.9.94.jar:/zookeeper-3.4.9/bin/../zookeeper-3.4.9.jar:/zookeeper-3.4.9/bin/../src/java/lib/*.jar:/conf:
2016-12-18 16:18:09,040 [myid:] - INFO  [main:Environment@100] - Server environment:java.library.path=/usr/lib/jvm/java-1.8-openjdk/jre/lib/amd64/server:/usr/lib/jvm/java-1.8-openjdk/jre/lib/amd64:/usr/lib/jvm/java-1.8-openjdk/jre/../lib/amd64:/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
2016-12-18 16:18:09,041 [myid:] - INFO  [main:Environment@100] - Server environment:java.io.tmpdir=/tmp
2016-12-18 16:18:09,041 [myid:] - INFO  [main:Environment@100] - Server environment:java.compiler=<NA>
2016-12-18 16:18:09,043 [myid:] - INFO  [main:Environment@100] - Server environment:os.name=Linux
2016-12-18 16:18:09,043 [myid:] - INFO  [main:Environment@100] - Server environment:os.arch=amd64
2016-12-18 16:18:09,044 [myid:] - INFO  [main:Environment@100] - Server environment:os.version=4.4.27-moby
2016-12-18 16:18:09,044 [myid:] - INFO  [main:Environment@100] - Server environment:user.name=zookeeper
2016-12-18 16:18:09,044 [myid:] - INFO  [main:Environment@100] - Server environment:user.home=/home/zookeeper
2016-12-18 16:18:09,044 [myid:] - INFO  [main:Environment@100] - Server environment:user.dir=/zookeeper-3.4.9
2016-12-18 16:18:09,057 [myid:] - INFO  [main:ZooKeeperServer@815] - tickTime set to 2000
2016-12-18 16:18:09,057 [myid:] - INFO  [main:ZooKeeperServer@824] - minSessionTimeout set to -1
2016-12-18 16:18:09,058 [myid:] - INFO  [main:ZooKeeperServer@833] - maxSessionTimeout set to -1
2016-12-18 16:18:09,076 [myid:] - INFO  [main:NIOServerCnxnFactory@89] - binding to port 0.0.0.0/0.0.0.0:2181

topstats 得到容器中進程的狀態

docker top CONTAINER 和在容器裏執行 top 的效果相似。

$ docker top jstorm-zookeeper
PID    USER      TIME  COMMAND
24593  dockrema  0:01  /usr/lib/jvm/java-1.8-openjdk/jre/bin/java -Dzookeeper.log.dir=. .....

$ docker stats jstorm-zookeeper
CONTAINER           CPU %     MEM USAGE / LIMIT       MEM %   NET I/O        BLOCK I/O   PIDS
jstorm-zookeeper    0.00%     24.86 MiB / 1.951 GiB   1.24%   648 B / 648 B  0 B / 0 B   20

經過 inspect 查看容器的詳細信息

docker inspect CONTAINER 飯後鏡像和容器的詳細信息。好比:

  • State —— 容器的當先狀態

  • LogPath —— history(stdout) file 的路徑

  • Config.Env —— 環境變量

  • NetworkSettings.Ports —— 端口的映射關係

環境變量很是有用不少問題都是環境變量引發的。

history 查看 image layers

能夠看到各層建立的指令,大小和哈希。能夠用來檢查這個image是否符合你的預期。

相關文章
相關標籤/搜索