和磁盘映射一样,你有时候会需要将Container的端口映射到host主机上,同样蛋疼的是,由于多了一层VM,端口映射也显得比较麻烦。首先你需要设置VirtualBox的端口映射,然后再将Container的端口映射到你的VM里面:
具体是这么做的,通过2条命令:
boot2docker ssh -L 8000:localhost:8000
docker run -i -t -p 8000:8000
也就是说在docker run的时候通过-p选项指定要映射的端口到VM,而boot2docker ssh命令则是将VM的8000端口映射到了host(Mac)的8000端口,这样你就可以通过Mac的localhost:8000访问Container的8000端口了。 其实,有另一种解决方案就是你不用映射到host(Mac),而是直接登录到VM里面进行访问就好了,boot2docker ssh就可以登录到VM,这样就类似于你的host是Ubuntu,但这种解决方案的问题是这个ubuntu太弱了(TinyCoreLinux),如果你在这个ubuntu里面开发代码,或者是运行浏览器,是非常蛋疼的事情,关键还是这个ubuntu是每次重启都会复原的!所以我建议还是做多一层映射好了。 最后,实际上在VM里面,你是可以直接访问所有的Container的端口的,因为VM到Container的网络都是桥接的。
其他的一些坑在使用的过程中,还遇到一些不少的坑:
/etc/hosts文件无法修改,这样你就不能自己做域名解析
VM的系统时间是UTC +0000的,而且貌似无法修改
Container的IP无法指定为静态IP,因此每次重启Container时,IP可能会变化
第1个问题的解决方案是通过安装dnsmasq软件来做域名解析:
# 首先,在你的Container里面安装dnsmasq软件:
apt-get install dnsmasq
# 将以下文本添加到 /etc/dnsmasq.conf文件的最后:
listen-address=127.0.0.1 resolv-file=/etc/resolv.dnsmasq.conf conf-dir=/etc/dnsmasq.d user=root
# 接着在/etc/dnsmasq.d/目录下新建一个文件,随意起个名字
vi /etc/dnsmqsq.d/dns.conf
# 指定你要映射的域名,例如google.com,则将下面贴进dns.conf文件
address="/google.com/172.17.0.4"
# 最后退出容器,重启启动容器时,通过-dns选项指定域名服务器
docker run -i -t -dns 127.0.0.1 -dns 8.8.8.8 dev:base /bin/bash
# 一定要注意上面添加google的域名服务器8.8.8.8,否则你访问不了外网
# 进去Container后,启动dnsmasq,这样你就能够ping google.com了
/etc/init.d/dnsmasq start
第2个问题的解决方案就稍微麻烦些,起码我没有找到更好的解决方案,我是将boot2docker.iso文件重新制作一次来解决这个问题的:
# 首先你需要将boot2docker.iso文件mount到一个目录下
hdiutil mount ~/.boot2docker/boot2docker.iso
# 系统会mount到/Volumes/boot2docker目录下,然后你最好将这下面的东西copy出来到一个另外的目录,这样我们好制作一张新的ISO
cp -r /Volumes/boot2docker/* ~/tmp/
# 接着我们修改以下文件
vi ~/tmp/boot/isolinux/isolinux.cfg
# 将其中的以下这行修改:
append loglevel=3 user=docker console=ttyS0 console=tty0 nomodeset norestore base
# 修改为:(其实就是加了tz的启动参数),然后保存
append tz=CST-8 loglevel=3 user=docker console=ttyS0 console=tty0 nomodeset norestore base
# 接着你必须在ubuntu环境下重新制作ISO文件,你可以利用docker跑一个ubuntu,哈哈,假设你将boot2docker目录copy到了ubuntu的/src/目录下,那么接着这么做
# 安装xorriso命令
apt-get install xorriso
# 构建ISO映射
xorriso -as mkisofs -J -R -V boot2docker -no-emul-boot -boot-load-size 4 -boot-info-table -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat -o /boot2docker.iso /src/
# 这样就生成了/boot2docker.iso文件,最后你就可以替换到VM的启动ISO文件了,然后重启VM了
boot2docker restart
# 最后你必须设置你的VM为正确的时间,使用date -s 命令,最后用date命令查看,你就能看到CST时区的正确时间了
Sun Mar 30 00:27:13 CST 2014
# 对于你启动的container,你都必须重新设置TZ环境变量,否则即使VM是CST-8,你的container还是UCT +00:00的时间
export TZ='CST-8'
第三个问题暂时无法解决(可能需要编辑底层的LXC配置文件)。
docker的限制以及后续的一些想法docker其实还是有一些限制的:
要求你的环境是Linux的,而且内核必须很新(>= 2.6.27 (29)),这其实是LXC本身的限制,和docker无关
docker的Container目前host是不能修改的,当然有解决方案(dnsmasq)
docker的Container也暂时无法指定静态IP
用docker作为开发环境甚至是生产环境其实还有很多地方值得尝试:
在团队内部构建本地的仓库,标准化所有的开发环境,使得团队的新人可以快速上手
在生产环境部署docker,这其实是PAAS的虚拟化和自动化的一种方式,利用LXC和Docker能够更便捷地实施PAAS
尝试用docker做分布式集群模拟和测试,成本会更加低廉,更加容器维护