15 个 Docker 技巧和提示

greenfrog 8年前
   <p>Docker 是个神奇的工具,我最喜欢它了。在软件开发界它是迄今为止最闪亮的神器,数十倍的简化了项目配置。</p>    <p>本文中,我会与你分享一些很酷的 Docker 技巧和提示。多数人可能熟悉这些命令,但我希望你或多或少能从本文获益。</p>    <h3>CLI(Command Line Interface,命令行)</h3>    <p>好的 docker ps 输出</p>    <p>将 docker ps 输出通过管道重定向到 less -S,避免折行:</p>    <pre>  docker ps -a | less -S</pre>    <p>跟随 logs</p>    <p>docker logs 默认情况下不会观察日志,除非你使用 -f 参数:</p>    <pre>  docker logs <containerid> -f</pre>    <p>docker inspect 输出漂亮的 JSON</p>    <p>docker inspect 默认输出大量的 JSON,可以通过 jq 提取需要的那些值:</p>    <pre>  # list IP addresses for all containers connected to 'bridge' network  docker network inspect bridge -f '{{json .Containers}}' | jq '.[] | {cont: .Name, ip: .IPv4Address}</pre>    <p>也可以像下面这样在 docker inspect 中使用内置的模板:</p>    <pre>  # is the last run container still running?  docker inspect --format '{{.State.Running}}' $(docker ps -lq)</pre>    <p>Docker 命令完成</p>    <p>Docker CLI 语法非常丰富,而且还在不断充实:添加新的命令和参数。要记住每个命令和参数几乎不可能,所以在终端上能自动完成这些命令很有必要。</p>    <p>命令完成是一个终端插件,通过 Tab 键,它会自动完成或建议你接下来要输入的内容。Docker 命令完成功能对命令和选项都能生效。Docker 团队为 Bash shell 和 Zsh shell 下的 docker、docker-machine 和 docker-compose 命令提供完成功能。</p>    <p>阅读 Docker 官方关于安装的文档: docker engine 、 docker-compose 和  docker-machine 。</p>    <p>使用一段时间 Docker 之后,没用的东西开始增长:不用的卷、网络、已退出的容器和不用的映像等。</p>    <p>prune:运行全部</p>    <p>prune 是个非常有用的命令(可在 vaume 和 network 子命令中使用),但它从 Docker 1.13 开始才有。如果你使用旧的 Docker 版本,下面的命令可用于代替 prune 命令。</p>    <pre>  docker system prune</pre>    <p>移除悬空卷</p>    <p>悬空卷是不被任何容器使用的卷。若要移除它们,需要结合两个命令:首先列出悬空卷的 ID 然后移除它们。</p>    <pre>  docker volume rm $(docker volume ls -q -f "dangling=true")</pre>    <p>删除已退出的容器</p>    <p>这个操作与上面的步骤相同。首先列出要删除(通过过滤)的容器(仅 ID)然后删除它们(参考 rm -f 强制删除)。</p>    <pre>  docker rm $(docker ps -q -f "status=exited")</pre>    <p>删除悬空映像</p>    <p>悬空映像是未标记的映像,它们是映像树的叶节点(不是中间层)。</p>    <pre>  docker rmi $(docker images -q -f "dangling=true")</pre>    <p>Docker 内部有一个保存 IP 地址的 IP 地址池。这些 IP 地址默认对外不可见,需要通过桥接进行访问。</p>    <p>查找端口映射</p>    <p>docker run 接收明确的端口映射参数,你也可以使用 -P 来自动映射所有端口。后者的优势在于可以防止冲突, 可以通过下面的命令查找已经分配的端口:</p>    <pre>  docker port <containerId> <portNumber>  # 或  docker inspect --format '{{.NetworkSettings.Ports}}' <containerId></pre>    <p>容器 IP</p>    <p>每个容器在私有子网中都有自己的 IP (默认是 172.17.0.0/16)。重启可以改变 IP,如果你需要,可以查询:</p>    <pre>  docker inspect --format '{{.NetworkSettings.IPAddress}}' <containerId></pre>    <p>docker 会检查冲突并会在必要的时候使用不同的子网。</p>    <p>接管主机的网络栈</p>    <p>docker run --net=host 允许使用主机的网络栈。不要干这种事情 :)</p>    <p>使用另一容器的网络栈</p>    <pre>  $ docker run --net=container:<name|id> ...</pre>    <p>新容器可以附加到另一个容器使用的网络接口。目标容器可以通过 ID 或名称指定。</p>    <p>可附加的覆盖网络</p>    <p>使用集群模式的 Docker 引擎可以在一人管理节点的覆盖网络上创建多个主机。创建集群服务的时候你可以将其附加到之前创建的覆盖网络。</p>    <p>有时候你需要将新的 Docker 容器(填充不同的网络工具)附加到已经存在的覆盖网络,以检查网络配置或调试问题。你可以使用 docker run 命令来完成,不需要创建全新的调试服务。</p>    <p>Docker 1.13 为 docker network create 命令添加了一个新选项:attachable。这个选项允许手工附加容器。</p>    <pre>  # create an attachable overlay network   docker network create --driver overlay --attachable mynet  # create net-tools container and attach it to mynet overlay network  docker run -it --rm --net=mynet net-tools sh</pre>    <h3>自动启动容器</h3>    <p>在 Docker 容器中运行的某个进程可能会有很多原因失败。某些情况下,可以通过重新运行失败的容器来修复。如果你在使用 Docker 业务流引擎,像 Swarm 或 Kubernetes,失败的服务会自动重启。</p>    <p>如果没有自动重启,那么你可能希望根据容器中主进程的退出代码来重启容器,或者直接重启容器(不管退出代码)。Docker 1.12 给 docker run 命令添加了 restart 参数来处理这种情况。</p>    <p>总是重启</p>    <p>配置重启策略为总是重启,这样一但容器退出,Docker 就会重启它。</p>    <pre>  docker run --restart=always my_image</pre>    <p>失败时重启容器</p>    <p>配置重启策略为失败时重启,最大重启尝试次数为 10。</p>    <pre>  docker run --restart=on-failure:10 my_image</pre>    <p>参考文献:</p>    <ul>     <li> <p><a href="/misc/goto?guid=4958986608595528202" rel="nofollow,noindex">https://docs.docker.com/</a></p> </li>     <li> <p><a href="/misc/goto?guid=4959737489828131992" rel="nofollow,noindex">https://codefresh.io/blog/everyday-hacks-docker/</a></p> </li>    </ul>    <p> </p>    <p>来自:https://www.oschina.net/translate/docker-hacks-tips</p>    <p> </p>