热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

[转]10个日常Docker使用技巧

我有机会建立一个以Docker为基础的微服务架构在我现在的工作中,很多人都会分享他们使用Docker的心得,我想我也不会例外。因此我总结了一些,可能你会在日常使用Docker的时候会用到。

1. 一台主机部署多个Docker实例

如果你想运行多个Docker 容器在一台主机上,如果要设置不同的TLS设置,网络设置,日志设置和存储驱动程序特定的容器,这是特别有用的。例如,我们目前正在运行一个标准设立两个Docker守护进程。一运行consul提供DNS解析,并作为群集存储为其他Docker 容器。

For example:

# 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
# start a docker daemon and bind to a specific port
dockerdaemon -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 Exec是一个很重要很多人都会用到的工具,也许你使用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>
$ dockerps --format "table {{.ID}}\t {{.Names}}\t {{.Status}}"
CONTAINERID        NAMES              STATUS
682f47f97fce        cassandra          Up 2 minutes
4c45aea49180        consul              Up 2 minutes
$ dockerexec -ti 682f47f97fce cqlsh --color
Connectedto TestClusterat 127.0.0.1:9042.
[cqlsh 5.0.1 | Cassandra 2.2.3 | CQLspec 3.3.1 | Native protocolv4]
Use HELPfor 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
$ dockerexec -ti 682f47f97fce nodetoolstatus
Datacenter: datacenter1
=======================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
--  Address        Load      Tokens      Owns    HostID                              Rack
UN  192.168.99.100  443.34 KB  256          ?      8f9f4a9c-5c4d-4453-b64b-7e01676361ff  rack1
Note: Non-systemkeyspacesdon't havethesamereplicationsettings, effectiveownershipinformation

这当然可以被应用到任何(Client)的工具捆绑在一起的镜像中。我个人觉得这样会比所有客户端和本地更新更简单。

3. Docker 的检查 和JQ

与其说这是一个Docker技巧,不如说是一个JQ技巧。如果你没有听过JQ,它是一个在命令行解析JSON的伟大工具。因为我们可以不需要使用format specifier而能够查看容器里面发生的一切。

# 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
  }
]
# Get network information:
$ dockerinspect 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
$ dockerinspect 4c45aea49180 | jq '.[].Args'
[
  "-server",
  "-advertise",
  "192.168.99.100",
  "-bootstrap-expect",
  "1"
]
# Get all the mounted volumes
11:22 $ dockerinspect 4c45aea49180 | jq '.[].Mounts'
[
  {
    "Name": "a8125ffdf6c4be1db4464345ba36b0417a18aaa3a025267596e292249ca4391f",
    "Source": "/mnt/sda1/var/lib/docker/volumes/a8125ffdf6c4be1db4464345ba36b0417a18aaa3a025267596e292249ca4391f/_data",
    "Destination": "/data",
    "Driver": "local",
    "Mode": "",
    "RW": true
  }
]

当然,它也能很好的完成查询其他类型的(Docker-esque) API生成的JSON(e.g Marathon, Mesos, Consul etc.)JQ提供了一个非常广泛的API,用于访问和处理JSON.更多信息可以在这里找到: https://stedolan.github.io/jq/

4. 扩展现有容器和在本地注册

在Docker hub中有大量可以使用的的不同使用场景的镜像。我们注意到,虽然有很多可用的镜像,但是很多时候我们不得对他们做一些修改。比如更好的健康检查consul,通过系统变量或命令行参数的其他配置,为更好地设置或增加我们的集群,这是不容易做到的。如果我们碰到这个是刚刚创建自己的Docker的镜像和把它推到我们的本地注册表。我们通常是这么做的。

比如,我们希望有JQ可在我们的consul 镜像中这样我们就可以很方便的检查我们的服务是否正常。

FROM progrium/consul
USER root
ADD bin/jq /bin/jq
ADD scripts/health-check.sh /bin/health-check.sh
FROMprogrium/consul
USERroot
ADDbin/jq /bin/jq
ADDscripts/health-check.sh /bin/health-check.sh

我们有了health check scripts and JQ我们就可以从我们自己的consul image做health check了。我们也有一个本地注册表运行镜像在创建后,我们只是标记生成的镜像,并将其推到我们的本地注册表

$ docker build .
...
$ docker tag a3157e9edc18 /consul-local:some-tag
$ docker push /consul-local:some-tag
$ dockerbuild .
...
$ dockertaga3157e9edc18 /consul-local:some-tag
$ dockerpush /consul-local:some-tag

现在,它可以提供给我们的开发者了。并且也可在我们的不同的测试环境中使用。

5. 访问远程主机的Docker

Docker的CLI是一个非常酷的工具,其中一个很大的特点是,你可以用它来轻松地访问多Docker守护进程,即使它们在不同的主机。你需要做的就是设置DOCKER_HOST环境变量指向Docker daemon的监听地址。如果该端口是可以的访问,你可以直接在远程主机上的Docker,这和你运行一个Docker daemon ,并设置为通过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-machineenvdemo
exportDOCKER_TLS_VERIFY="1"
exportDOCKER_HOST="tcp://192.168.99.100:2376"
exportDOCKER_CERT_PATH="/Users/jos/.docker/machine/machines/demo"
exportDOCKER_MACHINE_NAME="demo"

但你不必限制自己Docker daemons 程通过docker-machine启动。如果你有你的后台程序运行的控制,以及安全的网络,你可以很容易地从一台机器控制所有的。

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
$ mkdir /Users/jos/temp/samplevolume/
$ ls /Users/jos/temp/samplevolume/
$ dockerrun -v /Users/jos/temp/samplevolume/:/samplevolume  -it --rmbusybox
$ dockerrun -v /Users/jos/temp/samplevolume/:/samplevolume  -it --rmbusybox
/ # 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
  }
]
$ dockerinspect 76465cee5d49 | jq '.[].Mounts'
[
  {
    "Source": "/Users/jos/temp/samplevolume",
    "Destination": "/samplevolume",
    "Mode": "",
    "RW": true
  }
]

我们可以在Docker官网看到更多的特性和使用方 法: https://docs.docker.com/engine/userguide/dockervolumes/

7.添加DNS解析到你的容器

我之前提到过,我们可以通过consul来管理容器。Consul是一个支持多数据中心分布式高可用的服务发现和配置共享的服务软件,可以为容器提供服务发现和健康检查。对于服务发现Consul提供无论是REST API或传统DNS,他的伟大的之处是,当你运行一个具体的镜像,你可以指定你的容器DNS服务器。

当你有Consul运行(或者其它 DNS server)你可以把它添加到您的Docker daemon就像这样:

docker run -d --dns $IP_CONSUL --dns-search service.consul 
dockerrun -d --dns $IP_CONSUL --dns-searchservice.consul 

现在,我们可以解决与Consul的名字注册的所有容器的IP地址,比如在我们的环境我们有了一个cassandra 集群。每个cassandra将自己注册名称为“cassandra”我们的Consul 集群。最酷的是,我们现在只是解决卡cassandra的地址基于主机名(而不必使用Docker链接)

$ docker exec -ti 00c22e9e7c4e bash
[email protected]:/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
[email protected]:/opt/docker$
$ dockerexec -ti 00c22e9e7c4e bash
[email protected]:/opt/docker$ pingcassandra
PINGcassandra.service.consul (192.168.99.100): 56 databytes
64 bytesfrom 192.168.99.100: icmp_seq=0 ttl=64 time=0.053 ms
64 bytesfrom 192.168.99.100: icmp_seq=1 ttl=64 time=0.077 ms
^C--- cassandra.service.consulpingstatistics ---
2 packetstransmitted, 2 packetsreceived, 0% packetloss
round-tripmin/avg/max/stddev = 0.053/0.065/0.077/0.000 ms
[email protected]:/opt/docker$

8. Docker-UI是一个很棒来查看和获取洞察你容器的方式

使用Docker CLI来查看Docker容器所发生的一切并不难。很多时候,虽然你并不需要的Docker CLI的全部功能,但只是想快速浏览其中的容器运行,看看发生了什么。Docker UI ( https://github.com/crosbymichael/dockerui )就是一个这样伟大的项目,并且他是开源的。

[转]10个日常Docker使用技巧

有了这个工具,你可以看到一个特定的Docker deamon的容器和镜像的最重要的东西。

9. Container 不能启动? Overwrite the Entry Point你只需要从bash启动。

有时候一个容器只是没有做你想要它做的事情,你已经重新创建了Docker 镜像,你在启动时运行了几次,但不知何故,该应用程序没有反应,然后日志显示也没什么有用的信息。最简单的调试方法是overwrite the entry point ,看看在容器内部发生的一切,查看文件权限是否正确。拷贝进入镜像的文件是否正确,或者任何其它可能出现的错误。幸运的是,Docker有这样做的一个简单的解决方案。你可以从一个选择的入口点启动你的容器:

$ docker run -ti --entrypoint=bash cassandra
[email protected]:/# ls
bin   dev    etc   lib mediaopt   root  sbin  sys  usr
boot  docker-entrypoint.sh  home  lib64  mntproc  run   srv   tmp  var
[email protected]:/#
$ dockerrun -ti --entrypoint=bashcassandra
[email protected]:/# ls
bin  dev    etc  libmediaopt  root  sbin  sys  usr
boot  docker-entrypoint.sh  home  lib64  mntproc  run  srv  tmp  var
[email protected]:/#

10. 监听一个容器的事件:

当你编写自己的脚本,或者只是想了解发生了什么,你可以Docker event command运行你的镜像,为此编写脚本很容易。

[转]10个日常Docker使用技巧

这是我们没有使用Docker Compose 和Swarm yet和Docker 1.9网络层 特性的情况,Docker一个很酷的工具,有一套伟大的工具。在未来希望Docker越来越好,我也会给大家展示一些Docker更酷的东西。

更多Docker相关教程见以下内容

Docker安装应用(CentOS 6.5_x64) http://www.linuxidc.com/Linux/2014-07/104595.htm 

Ubuntu 14.04安装Docker  http://www.linuxidc.com/linux/2014-08/105656.htm 

Ubuntu使用VNC运行基于Docker的桌面系统  http://www.linuxidc.com/Linux/2015-08/121170.htm

阿里云CentOS 6.5 模板上安装 Docker http://www.linuxidc.com/Linux/2014-11/109107.htm 

Ubuntu 15.04下安装Docker  http://www.linuxidc.com/Linux/2015-07/120444.htm 

在Ubuntu Trusty 14.04 (LTS) (64-bit)安装Docker http://www.linuxidc.com/Linux/2014-10/108184.htm 

在 Ubuntu 15.04 上如何安装Docker及基本用法 http://www.linuxidc.com/Linux/2015-09/122885.htm

Docker 的详细介绍:请点这里
Docker 的下载地址:请点这里 

本文永久更新链接地址:http://www.linuxidc.com/Linux/2015-12/126586.htm


推荐阅读
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • 本文介绍了一个React Native新手在尝试将数据发布到服务器时遇到的问题,以及他的React Native代码和服务器端代码。他使用fetch方法将数据发送到服务器,但无法在服务器端读取/获取发布的数据。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • 解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法
    本文介绍了解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法,包括检查location配置是否正确、pass_proxy是否需要加“/”等。同时,还介绍了修改nginx的error.log日志级别为debug,以便查看详细日志信息。 ... [详细]
  • 本文由编程笔记小编整理,主要介绍了使用Junit和黄瓜进行自动化测试中步骤缺失的问题。文章首先介绍了使用cucumber和Junit创建Runner类的代码,然后详细说明了黄瓜功能中的步骤和Steps类的实现。本文对于需要使用Junit和黄瓜进行自动化测试的开发者具有一定的参考价值。摘要长度:187字。 ... [详细]
  • 背景应用安全领域,各类攻击长久以来都危害着互联网上的应用,在web应用安全风险中,各类注入、跨站等攻击仍然占据着较前的位置。WAF(Web应用防火墙)正是为防御和阻断这类攻击而存在 ... [详细]
  • 恶意软件分析的最佳编程语言及其应用
    本文介绍了学习恶意软件分析和逆向工程领域时最适合的编程语言,并重点讨论了Python的优点。Python是一种解释型、多用途的语言,具有可读性高、可快速开发、易于学习的特点。作者分享了在本地恶意软件分析中使用Python的经验,包括快速复制恶意软件组件以更好地理解其工作。此外,作者还提到了Python的跨平台优势,使得在不同操作系统上运行代码变得更加方便。 ... [详细]
  • 本文介绍了关系型数据库和NoSQL数据库的概念和特点,列举了主流的关系型数据库和NoSQL数据库,同时描述了它们在新闻、电商抢购信息和微博热点信息等场景中的应用。此外,还提供了MySQL配置文件的相关内容。 ... [详细]
  • linux进阶50——无锁CAS
    1.概念比较并交换(compareandswap,CAS),是原⼦操作的⼀种,可⽤于在多线程编程中实现不被打断的数据交换操作࿰ ... [详细]
author-avatar
广工华立城建学部艺术团
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有