JSON

关于docker的15个小tip(技巧)(2)

字号+ 作者:H5之家 来源:H5之家 2017-08-28 12:00 我要评论( )

刚接触Docker的人或许会有这样的疑问:Docker容器有自己的IP地址吗?Docker容器是一个进程?还是一个虚拟机?嗯…也许两者兼 具?哈哈,其实,Docker容器确实有自己的IP,就像一个具有IP的进程。只要分别在主机和Do

刚接触Docker的人或许会有这样的疑问:Docker容器有自己的IP地址吗?Docker容器是一个进程?还是一个虚拟机?嗯…也许两者兼 具?哈哈,其实,Docker容器确实有自己的IP,就像一个具有IP的进程。只要分别在主机和Docker容器中执行查看ip的命令就知道了。


查看主机的ip:




$ ip -4 -o addr show eth0


得到结果:


2: eth0 inet 162.243.139.222/24 


查看Docker容器的ip:




$ docker run ubuntu ip -r -o addr show eth0


得到结果:


149: eth0   inet 172.17.0.43/16


两者并不相同,说明Docker容器有自己的ip。


10.基于命令行的瘦客户端,使用UNIX Socket和Docker后台服务的REST接口进行通信


Docker默认是用UNIX socket通信的,一直到大概0.5、0.6的版本还是用端口来通信,但现在则改成UNIX socket,所以从外部无法控制Docker容器的内部细节。下面我们来搞点有趣的事情,从主机链接到docker的UNIX socket:




# 像HTTP客户端一样连接到UNIX socket

$ nc -U / /var/run/docker.sock


连接成功后,输入:




GET /images/json HTTP/1.1


输入后连敲两个回车,第二个回车表示输入结束。然后,得到的结果应该是:




HTTP/1.1 200 OK

Content-Type: application/json

Date: Tue, 05 Nov 2013 23:18:09 GMT

Transfer-Encoding: chunked

16aa

[{“Repository”:”postgres”,”Tag”:”......


有一天,我不小心把提交的名称打错了,名字开头打成”-xxx”(我把命令和选项的顺序搞混了),所以当我删除的时候出了问题,docker rm -xxx,会把-xxx当成参数而不是镜像的名称。所以我只得通过socket直接连到容器来调用REST Server把错误的东西删掉。


11.把镜像的依赖关系绘制成图


docker images命令有一个很拉风的选项:-viz,可以把镜像的依赖关系绘制成图并通过管道符号保存到图片文件:




# 生成一个依赖关系的图表

$ docker images -viz | dot -T png -o docker.png


这样,主机的当前路径下就生成了一张png图,然后,用python开启一个微型的HTTP服务器:




python -m SimpleHTTPServer



然后在别的机器上用浏览器打开::8000/docker.png 


OK,依赖关系一目了然!


(译者注:要使用dot命令,主机要安装graphviz包。另外,如果主机ip没有绑定域名,machinename换成主机的ip即可。)


12.Docker把东西都存到哪里去了?


Docker实际上把所有东西都放到/var/lib/docker路径下了。切换成super用户,到/var/lib/docker下看看,你能学到很多有趣的东西。执行下面的命令:




$ sudo su

# cd /var/lib/docker

# ls -F

containers/ graph/ repositories volumes/


可以看到不少目录,containers目录当然就是存放容器(container)了,graph目录存放镜像,文件层(file system layer)存放在graph/imageid/layer路径下,这样你就可以看看文件层里到底有哪些东西,利用这种层级结构可以清楚的看到文件层是如 何一层一层叠加起来的。


13.Docker源代码:Go, Go, Go, Golang!


Docker的源代码全部是用Go语言写的。Go是一门非常酷的语言。其实,不只是Docker,很多优秀的软件都是用Go写的。对我来说,Docker源文件中,有4个是我非常喜欢阅读的:


commands.go


docker的命令行接口,是对REST API的一个轻量级封装。Docker团队不希望在命令中出现逻辑,因此commands.go只是向REST API发送指令,确保其较小的颗粒性。


api.go


REST API的路由(接受commands.go中的请求,转发到server.go)


server.go


大部分REST API的实现


buildfile.go


Dockerfile的解析器


有的伙计惊叹”Wow!Docker是怎么实现的?!我无法理解!”没关系,Docker是开源软件,去看它的源代码就可以了。如果你不太清楚Dockerfile中的命令是怎么回事,直接去看buildfile.go就明白了。


14.运行几个Docker后台程序,再退出容器,会发生什么?


OK,倒数第二个要点。如果在Docker中运行几个后台程序,再退出Docker容器,会发生什么?答案是:不要这么做!因为这样做后台程序就全丢了。


Dockerfile中用RUN命令去开启一个后台程序,如:




RUN pg_ctl start


这样的话,RUN命令开启的后台程序就会丢失。调用容器的bash连到容器的shell:




$ docker run -i -t postgresimage bash


然后调用 ps aux查看进程,你会发现postgres的进程并没有跑起来。 RUN命令会影响文件系统。因此,不要再Dockerfile中用启动后台程序,要把后台程序启动成前台进程。或者,像一些高手提议的那样,写一个启动脚 本,在脚本中启动这些后台程序或进程。


15.容器之间进行友好沟通:链接


这是最拉风的功能!我把它留到最后压轴!这是0.6.5中最重要的新功能,我们前面已经提过两次了。运行一个容器,给它一个名称,在下面的例子中,我们通过-name参数给容器指定名称”loldb”:




$ docker run -d -name loldb loldbimage


再运行另一个容器,加上-link参数来连接到第一个容器(别名为loldb),并给第二个容器也指定一个别名(这里用的是cheez):




$ docker run -link /loldb:cheez otherimage env


顺便得到cheez的环境变量:




CHEEZ_PORT=tcp://172.17.0.8:6379

CHEEZ_PORT_1337_TCP=tcp://172.17.0.8.6379

CHEEZ_PORT_1337_TCP_ADDR=tcp://172.17.0.12

CHEEZ_PORT_1337_TCP_PORT=6379

CHEEZ_PORT_1337_TCP_PROTO=tcp


 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
网友点评