上个星期学习了一下docker,写了一个伪分布式的Dockerfile。
通过--link
的方式master能访问slaver,毕竟slaver的相关信息已经被写入到master的hosts文件里面去了嘛!理所当然认为,直接把master的hosts文件全部复制一份到所有slaver节点问题就解决了。
等真正操作的时刻,发现不是那么回事,docker容器不给修改hosts文件!!(2016-1-7 14:18:11 注: Docker 1.6.2已经可以修改/etc/hosts了!重启后hosts的变更也没了,囧)
错误实现
首先,看下不当的操作:
1
2
3
4
5
6
7
8
9
10
| # 注意:没有填写image,会去找Dockerfile
[root@docker hadoop]# docker run -d --name slaver1 -h slaver1 hadoop
[root@docker hadoop]# docker run -d --name slaver2 -h slaver2 hadoop
[root@docker hadoop]# docker run -d --name master -h master --link slaver1:slaver1 --link slaver2:slaver2 hadoop
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dafc82678811 hadoop:latest /bin/sh -c '/usr/sbi 40 seconds ago Up 40 seconds 22/tcp master
86d2da5209c5 hadoop:latest /bin/sh -c '/usr/sbi 49 seconds ago Up 48 seconds 22/tcp master/slaver2,slaver2
7b9761fb05a8 hadoop:latest /bin/sh -c '/usr/sbi 56 seconds ago Up 55 seconds 22/tcp master/slaver1,slaver1
|
此时,通过--link
连接方式,master的hosts中已经包括了slaver1和slaver2,按照正常的路子,登录master拷贝其hosts到slaver节点,一切就妥妥的了。现实是残酷的:
1
2
| -bash-4.1# scp /etc/hosts slaver1:/etc/
scp: /etc//hosts: Read-only file system
|
DNS完美解决问题
首先需要在宿主机器上安装dns服务器,bind不多说比较麻烦。这里参考网上人家解决方式,使用dnsmasq来搭建DNS服务器。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| [root@docker ~]# yum install dnsmasq -y
[root@docker ~]# cp /etc/resolv.conf /etc/resolv.dnsmasq.conf
[root@docker ~]# touch /etc/dnsmasq.hosts
[root@docker ~]# vi /etc/resolv.conf
[root@docker ~]# cat /etc/resolv.conf
; generated by /sbin/dhclient-script
nameserver 127.0.0.1
[root@docker ~]# vi /etc/dnsmasq.conf
[root@docker ~]# cat /etc/dnsmasq.conf
...
resolv-file=/etc/resolv.dnsmasq.conf
...
addn-hosts=/etc/dnsmasq.hosts
[root@docker ~]# service dnsmasq restart
[root@docker ~]# dig www.baidu.com
...
;; SERVER: 127.0.0.1#53(127.0.0.1)
...
|
通过dig可以查看当前的DNS服务器你已经修改为localhost了。然后启动docker容器来搭建环境。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| # 注意:没有填写image,会去找Dockerfile
[root@docker hadoop]# docker run -d --dns 172.17.42.1 --name slaver1 -h slaver1 hadoop
[root@docker hadoop]# docker run -d --dns 172.17.42.1 --name slaver2 -h slaver2 hadoop
[root@docker hadoop]# docker run -d --dns 172.17.42.1 --name master -h master hadoop
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f6e63b311e60 hadoop:latest /bin/sh -c '/usr/sbi 6 seconds ago Up 5 seconds 22/tcp master
454ae2c3e435 hadoop:latest /bin/sh -c '/usr/sbi 13 seconds ago Up 12 seconds 22/tcp slaver2
7698230a03fb hadoop:latest /bin/sh -c '/usr/sbi 21 seconds ago Up 20 seconds 22/tcp slaver1
[root@docker ~]# docker ps | grep hadoop | awk '{print $1}' | xargs -I{} docker inspect -f '{{.NetworkSettings.IPAddress}} {{.Config.Hostname}}' {} > /etc/dnsmasq.hosts
[root@docker ~]# service dnsmasq restart
[root@docker ~]# ssh hadoop@master
hadoop@master's password:
[hadoop@master ~]$ ping slaver1
PING slaver1 (172.17.0.9) 56(84) bytes of data.
64 bytes from slaver1 (172.17.0.9): icmp_seq=1 ttl=64 time=1.79 ms
...
[hadoop@master ~]$ ping slaver2
PING slaver2 (172.17.0.10) 56(84) bytes of data.
64 bytes from slaver2 (172.17.0.10): icmp_seq=1 ttl=64 time=1.96 ms
...
|
节点互通后,后面的步骤都类似了,ssh无密钥通信,格式化namenode,启动等等。
遇到的问题
- 一开始我把配置文件放在/root目录下,dnsmasq总是不起作用。最后放到/etc目录就可以,不知道啥子问题。
- 配置dns启动docker容器后,如果不起作用看下
/etc/resolv.conf
。如果互ping不同,去掉resolv的search localhost
再试下。
DNS可以正常工作的配置:
1
2
3
4
5
6
7
8
9
10
| -bash-4.1# ping slaver
PING slaver (172.17.0.7) 56(84) bytes of data.
64 bytes from slaver (172.17.0.7): icmp_seq=1 ttl=64 time=0.095 ms
-bash-4.1# cat /etc/resolv.conf
nameserver 172.17.42.1
search localdomain
-bash-4.1# cat /etc/resolv.conf
nameserver 172.17.42.1
|
如果还是不行的话,关掉防火墙然后重启下docker服务: service iptables stop; service docker restart
如果要访问外网,也可以条件其他的DNS服务解析:
1
2
3
| -bash-4.1# vi /etc/resolv.conf
nameserver 172.17.42.1
nameserver 8.8.8.8
|
常用命令
1
2
3
| ~]# docker run -d --dns 172.17.42.1 --name puppet -h puppet winse/hadoop:2.6.0 /usr/sbin/sshd -D
~]# docker inspect `docker ps -a | grep centos | awk '{print $1}'` | grep IPAddress
~]# docker stop `docker ps -a | grep centos | awk '{print $1}'`
|
参考
–END