我有机会在当前工作中建立一个完整的基于docker的新微服务体系结构,所以既然每个人都在分享他们的docker技巧和窍门,我想我会做同样的事情。 因此,这里列出了一些技巧,窍门或任何您可能会称之为的技巧,它们可能会在日常处理Docker中发现有用。
1.同一主机上有多个泊坞窗。
如果需要,可以在同一主机上运行多个docker容器。 如果要为特定容器设置不同的TLS设置,网络设置,日志设置或存储驱动程序,此功能特别有用。 例如,我们当前运行两个docker守护程序的标准设置。 一个运行Consul提供DNS解析,并充当另一个Docker容器的群集存储。
例如:
# start a docker daemon and bind to a specific port
docker daemon -H tcp://$IP:5000 --storage-opt dm.fs=xfs \
-p "/var/run/docker1.pid" \
-g "/var/lib/docker1" \
--exec-root="/var/run/docker1
# and start another daemon
docker daemon -H tcp://$IP:5001 --storage-opt dm.fs=xfs \
-s devicemapper \
--storage-opt dm.thinpooldev=/dev/mapper/docker--vg-docker--pool \
-p "/var/run/docker2.pid" \
-g "/var/lib/docker2" --exec-root="/var/run/docker2"
--cluster-store=consul://$IP:8500 \
--cluster-advertise=$IP:2376
2.当然是Docker exec
这可能是每个人都提到的提示之一。 当您不仅将docker用于您的登台,生产或测试环境,而且还在本地计算机上使用docker运行数据库,服务器,密钥库等时,能够在正在运行的容器上下文中直接运行命令非常方便。
我们对cassandra做了很多工作,并检查表是否包含正确的数据,或者您是否只想执行快速的CQL查询docker exec,效果很好:
$ docker ps --format "table {{.ID}}\t {{.Names}}\t {{.Status}}"
CONTAINER ID NAMES STATUS
682f47f97fce cassandra Up 2 minutes
4c45aea49180 consul Up 2 minutes
$ docker exec -ti 682f47f97fce cqlsh --color
Connected to Test Cluster at 127.0.0.1:9042.
[cqlsh 5.0.1 | Cassandra 2.2.3 | CQL spec 3.3.1 | Native protocol v4]
Use HELP for help.
cqlsh>
或者只是访问nodetool或映像中可用的任何其他工具:
$ docker exec -ti 682f47f97fce nodetool status
Datacenter: datacenter1
=======================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
-- Address Load Tokens Owns Host ID Rack
UN 192.168.99.100 443.34 KB 256 ? 8f9f4a9c-5c4d-4453-b64b-7e01676361ff rack1
Note: Non-system keyspaces don't have the same replication settings, effective ownership information is meaningless
当然,这可以应用于与图像捆绑在一起的任何(客户端)工具。 我个人觉得这比在本地安装所有客户端库和保持版本最新要容易得多。
3.码头检查和jq
这不是docker技巧,而是jq技巧。 如果您还没有听说过jq,那么它是从命令行解析JSON的好工具。 这也使它成为查看容器中正在发生的事情的好工具,而不必使用–我不记得该怎么使用的–format说明符:
# Get network information:
$ docker inspect 4c45aea49180 | jq '.[].NetworkSettings.Networks'
{
"bridge": {
"EndpointID": "ba1b6efba16de99f260e0fa8892fd4685dbe2f79cba37ac0114195e9fad66075",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02"
}
}
# Get the arguments with which the container was started
$ docker inspect 4c45aea49180 | jq '.[].Args'
[
"-server",
"-advertise",
"192.168.99.100",
"-bootstrap-expect",
"1"
]
# Get all the mounted volumes
11:22 $ docker inspect 4c45aea49180 | jq '.[].Mounts'
[
{
"Name": "a8125ffdf6c4be1db4464345ba36b0417a18aaa3a025267596e292249ca4391f",
"Source": "/mnt/sda1/var/lib/docker/volumes/a8125ffdf6c4be1db4464345ba36b0417a18aaa3a025267596e292249ca4391f/_data",
"Destination": "/data",
"Driver": "local",
"Mode": "",
"RW": true
}
]
当然,它对于查询生成JSON的其他类型(docker风格)的API(例如Marathon,Mesos,Consul等)也非常有用。 JQ提供了非常广泛的API,用于访问和处理JSON。 可以在这里找到更多信息: https : //stedolan.github.io/jq/
4.扩展现有容器并将其推送到本地注册表。
在中央docker hub上,有大量可用的图像可用于许多不同的用例。 但是,我们注意到的是,通常我们必须对图像进行一些非常小的更改。 例如,从领事那里进行更好的运行状况检查,在我们的群集设置中表现更好或添加其他配置(通过系统变量或命令行参数不容易完成)。 如果遇到这种情况,我们通常要做的只是创建自己的docker映像并将其推送到我们的本地注册表。
例如,我们希望在领事形象上提供JQ,以使我们的服务更容易进行健康检查:
FROM progrium/consul
USER root
ADD bin/jq /bin/jq
ADD scripts/health-check.sh /bin/health-check.sh
使用我们的健康检查脚本和JQ,我们从自己的领事形象中进行健康检查。 我们还运行着一个本地注册表,因此在创建映像之后,我们只需标记生成的映像并将其推送到我们的本地注册表即可:
$ docker build .
...
$ docker tag a3157e9edc18 <local-registry>/consul-local:some-tag
$ docker push <local-registry>/consul-local:some-tag
现在,它对我们的开发人员可用,也可以在我们的不同测试环境中使用(出于生产目的,我们使用单独的注册表)。
5.访问远程主机上的泊坞窗
docker CLI是一个非常酷的工具。 很棒的功能之一是,即使它们在不同的主机上,您也可以使用它轻松地访问多个docker守护程序。 您所要做的只是将DOCKER_HOST环境变量设置为指向docker守护进程的侦听地址,并且,如果该端口当然可以访问,则可以直接在远程主机上控制docker。 这与运行docker守护程序并通过docker-machine env设置环境时docker-machine所使用的原理几乎相同:
$ docker-machine env demo
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="/Users/jos/.docker/machine/machines/demo"
export DOCKER_MACHINE_NAME="demo"
但是您不必只局限于通过docker-machine启动的docker守护进程,如果您有运行着受控且安全良好的网络的守护程序,则可以从一台机器上轻松地控制所有(或垫脚石)。
6.轻松安装主机目录
使用容器时,有时需要在容器内获取一些数据(例如,共享配置)。 您可以将其复制到或ssh中,但是通常最简单的方法是将主机目录添加到安装在容器内的容器中。 您可以通过以下方式轻松地执行此操作:
$ mkdir /Users/jos/temp/samplevolume/
$ ls /Users/jos/temp/samplevolume/
$ docker run -v /Users/jos/temp/samplevolume/:/samplevolume -it --rm busybox
$ docker run -v /Users/jos/temp/samplevolume/:/samplevolume -it --rm busybox
/ # ls samplevolume/
/ # touch samplevolume/hello
/ # ls samplevolume/
hello
/ # exit
$ ls /Users/jos/temp/samplevolume/
hello
如您所见,我们指定的目录已安装在容器内,并且放置在该目录中的所有文件在主机和容器内均可见。 我们还可以使用inspect来查看安装在什么位置:
$ docker inspect 76465cee5d49 | jq '.[].Mounts'
[
{
"Source": "/Users/jos/temp/samplevolume",
"Destination": "/samplevolume",
"Mode": "",
"RW": true
}
]
在Docker站点上有很多其他功能很好地解释了: https : //docs.docker.com/engine/userguide/dockervolumes/
7.将DNS解析添加到您的容器中
我已经提到过,我们在容器中使用领事。 Consul是一个分布式KV存储,还提供服务发现和运行状况检查。 为了进行服务发现,Consul提供了REST API或普通的旧DNS。 最重要的是,您可以在运行特定映像时为容器指定DNS服务器。 因此,当您运行Consul(或任何其他DNS服务器)时,可以将其添加到docker守护进程中,如下所示:
docker run -d --dns $IP_CONSUL --dns-search service.consul <rest of confguration>
现在,我们可以按名称解析在Consul注册的任何容器的ip地址。 例如,在我们的环境中,我们有一个卡桑德拉群集。 每个cassandra实例都以名称“ cassandra”注册到我们的Consul集群。 很酷的事情是,我们现在可以根据主机名解析cassandra的地址(而不必使用docker链接)。
$ docker exec -ti 00c22e9e7c4e bash
daemon@00c22e9e7c4e:/opt/docker$ ping cassandra
PING cassandra.service.consul (192.168.99.100): 56 data bytes
64 bytes from 192.168.99.100: icmp_seq=0 ttl=64 time=0.053 ms
64 bytes from 192.168.99.100: icmp_seq=1 ttl=64 time=0.077 ms
^C--- cassandra.service.consul ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.053/0.065/0.077/0.000 ms
daemon@00c22e9e7c4e:/opt/docker$
8. Docker-ui是查看和深入了解容器的好方法
使用Docker CLI管理Docker并不难,并且可以为正在发生的事情提供丰富的内部信息。 通常,尽管您不需要Docker CLI的全部功能,而只是想快速了解正在运行的容器并查看正在发生的情况。 为此,一个很棒的项目是Docker ui( https://github.com/crosbymichael/dockerui ):
使用此工具,您可以查看特定docker守护程序的容器和映像的最重要方面。
覆盖入口点,然后从bash运行它
有时容器只是不执行您想要的操作。 您已经重新创建了Docker映像几次,但是以某种方式在启动时运行的应用程序无法按预期运行,并且日志记录没有任何用处。 调试此问题的最简单方法是仅覆盖容器的入口点,然后查看容器内部发生了什么。 文件权限是否正确?您是否将正确的文件复制到了映像中,或者是否有其他1000处可能出错的问题。
幸运的是,码头工人对此有一个简单的解决方案。 您可以使用选择的入口点启动容器:
$ docker run -ti --entrypoint=bash cassandra
root@896757f0bfd4:/# ls
bin dev etc lib media opt root sbin sys usr
boot docker-entrypoint.sh home lib64 mnt proc run srv tmp var
root@896757f0bfd4:/#
10.监听容器中的事件
当您编写自己的脚本或只想了解正在运行的映像发生了什么时,可以使用docker event命令。 为此编写脚本非常容易。
到此为止,我们还没有涉及到Docker的组成和组成,也没有涉及Docker 1.9网络覆盖功能! Docker是一个了不起的工具,周围还有很多其他工具。 将来,我将展示到目前为止我们在Docker方面所做的更多工作。
翻译自: https://www.javacodegeeks.com/2015/12/10-practical-docker-tips-day-day-docker-usage.html