温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Docker实用技巧实例分析

发布时间:2022-05-26 16:20:08 来源:亿速云 阅读:135 作者:iii 栏目:大数据

这篇文章主要讲解了“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 <local-registry>/consul-local:some-tag
$ docker push <local-registry>/consul-local:some-tag
$ dockerbuild .
...
$ dockertaga3157e9edc18 <local-registry>/consul-local:some-tag
$ dockerpush <local-registry>/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 <rest of confguration>

dockerrun -d --dns $ip_consul --dns-searchservice.consul <restofconfguration>

现在,我们可以解决与consul的名字注册的所有容器的ip地址,比如在我们的环境我们有了一个cassandra 集群。每个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$
$ dockerexec -ti 00c22e9e7c4e bash
daemon@00c22e9e7c4e:/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
daemon@00c22e9e7c4e:/opt/docker$

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

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

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

9. container 不能启动? overwrite the entry point你只需要从bash启动。

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

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

root@896757f0bfd4:/#

感谢各位的阅读,以上就是“Docker实用技巧实例分析”的内容了,经过本文的学习后,相信大家对Docker实用技巧实例分析这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI