Winse Blog

走走停停, 熙熙攘攘, 忙忙碌碌, 不知何畏.

Dnsmasq解决docker集群节点互通问题

上个星期学习了一下docker,写了一个伪分布式的Dockerfile

通过--link的方式master能访问slaver,毕竟slaver的相关信息已经被写入到master的hosts文件里面去了嘛!理所当然认为,直接把master的hosts文件全部复制一份到所有slaver节点问题就解决了。

等真正操作的时刻,发现不是那么回事,docker容器不给修改hosts文件!!

错误实现

首先,看下不当的操作:

1
2
3
4
5
6
7
8
9
[root@docker ~]# docker run -d --name slaver1 -h slaver1 hadoop
[root@docker ~]# docker run -d --name slaver2 -h slaver2 hadoop
[root@docker ~]# 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

[root@docker ~]# docker run -d  --dns 172.17.42.1 --name slaver1 -h slaver1 hadoop
[root@docker ~]# docker run -d  --dns 172.17.42.1 --name slaver2 -h slaver2 hadoop
[root@docker ~]# 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

参考

Comments