在Docker上使用Weave搭建Hadoop和Spark跨主機容器集群
功能和環境說明
實際環境是開發使用的兩臺服務器,每個服務器上是三個集群容器節點,總共六個節點,使用weave實現跨主機的通信,并且利用小插件可以實現在局域網或者是在外網查看監控集群的webUI和開放7077等關鍵端口進行程序遠程調試功能。
目前網上跨主機的工具很多,我挑選的是使用普遍點和資料多點的weave,我實習的這個公司的需求并不大,只需要解決他們的hadoop,spark的開發環境就行了。
本文的重點有兩個,第一,使用weave解決跨主機通信,第二,實際使用當中,開放端口調試程序和webUI監控等。至于hadoop,spark本身的安裝配置等參數并沒有涉及。
----------
時間:起草于2016/2/4,截止于2016/2/24。
地點:寒假老家和回到某高校教研室。
作者:duweike。
原因:某實習公司spark開發環境需要。
主機系統:CentOS7,兩臺服務器,分別32G內存。
軟件版本:hadoop-2.6.0,jdk1.8.0_66,scala-2.10.4,spark-1.6.0-bin-hadoop2.6,docker版本:1.8.2(CentOS7默認安裝的是這個版本,極力推薦升級到最新版),鏡像:ubuntu14.04(不建議使用centos作為基礎鏡像)。
----------
具體部署過程
建議閱讀我上一篇的單機版集群,雖然上篇的實際使用價值并不算大,但是其中的很多知識和技巧還是有參考價值的,比如ssh免密碼登錄技巧等。下面的過程沒有辦法那么詳盡,請實際動手操作搞定。
第一步,制作Spark基礎鏡像。
這一步和我上一篇的意思差不多,基本操作也很簡單,具有一定的實際操作經驗的話會更順利的完成。
1.我使用的是ubuntu14.04作為基礎鏡像,然后安裝vim,ssh,并配置ssh允許遠程root登錄,然后ssh-keygen生成秘鑰,然后設置“自己免密碼登錄自己”,請注意這里是一個很實用的小技巧。上面過程請自己完成,還是比較簡單的。
2.把hadoop,spark,scala,java傳入到這個鏡像。在傳入之前,要把hadoop,spark的“配置文件修改好”,修改的內容可以參考下文的集群信息,這里就不贅述了。在啟動ssh的情況下可以使用scp,也可以在啟動鏡像的時候,利用數據卷傳入。我是把所有的軟件放到容器目錄/opt/下面。
root@master:/opt# ls
hadoop-2.6.0 jdk1.8.0_66 scala-2.10.4 spark-1.6.0-bin-hadoop2.6
3.下面把所有的變量寫入/root/.bashrc,不寫入/etc/profile里面是因為不起作用,讀者可以自己嘗試一下,我就套用上篇的變量,自己修改為自己的吧
export JAVA_HOME=/opt/jdk1.7.0_79
export CLASSPATH=.:/opt/jdk1.7.0_79/lib/dt.jar:/opt/jdk1.7.0_79/lib/tools.jar
export HADOOP_HOME=/opt/hadoop-2.6.0
export SCALA_HOME=/opt/scala-2.10.5
export SPARK_HOME=/opt/spark-1.2.0-bin-hadoop2.4
export PATH=$JAVA_HOME/bin:$PATH:$SCALA_HOME/bin:$SPARK_HOME/bin
4.設置開機啟動ssh,這一步很簡單,寫一個run.sh腳本就行了。
root@master:~# pwd
/root
root@master:~# cat run.sh
#!/bin/bash
/etc/init.d/ssh start -D
5.新建文件/root/hosts,來提前寫入自己規劃的IP-主機名的對應關系,這是為下面的操作做準備的,/root/hosts內容如下:
root@master:~# cat hosts
192.168.0.100 master
192.168.0.101 node1
192.168.0.102 node2
192.168.0.103 node3
192.168.0.104 node4
192.168.0.105 node5
6.使用docker commit提交成鏡像,鏡像名稱為:spark:v1,然后分發到另外一臺主機上。
如果有私有倉庫就用push,pull分發。
如果沒有,就使用save,load命令分發。
到這一步,spark:v1基礎鏡像也就是做好了,步驟太多沒有辦法那么詳盡,不過應該沒有太大問題。最終的目的就是hadoop,spark的基礎鏡像包生成。雖然工作量是蠻大的,但這并不是本文的重點。
----------
第二步,安裝weave,創建容器,啟動spark容器集群。
關于weave的介紹,請參考這兩篇文檔,請先閱讀下面的文檔之后再往下看。
github網址: https://github.com/weaveworks/weave
推薦網址: http://blog.csdn.net/wangtaoki ... 44525
我覺得他們的介紹意境很清楚了,閱讀幾遍,操作幾遍,熟悉一下之后再繼續下往下看。
首先介紹一下環境規劃(此時是我筆記本的虛擬機IP):
服務器docker100 IP:172.16.203.100
服務器docker101 IP:172.16.203.101
服務器docker100和docker101的/etc/hosts添加一下映射會方便很多,還有ssh相互免密碼登錄
服務器docker100,一個主節點,二個從節點:
容器名:master,容器主機名:master,IP:192.168.0.100,
容器名:node1,容器主機名:node1,IP:192.168.0.101,
容器名:node2,容器主機名:node2,IP:192.168.0.102,
服務器docker101,三個從節點:
容器名:node3,容器主機名:node3,IP:192.168.0.103,
容器名:node4,容器主機名:node4,IP:192.168.0.104,
容器名:node5,容器主機名:node5,IP:192.168.0.105,
1.啟動weave:weave launch。
2.執行:weave connect IP,這時兩臺主機的容器就可以連通了。IP不要使用主機名,直接使用IP地址。
3.下面開始利用weave啟動集群。我這里是寫了一個腳本來方便啟動,初期可以手動一個一個節點執行啟動。下面是腳本是在docker100服務器上執行的,這樣就可以利用這個腳本一鍵創建集群了。
1 weave run 192.168.0.100/24 -itd --name master -p 8090:18090 -p 8998:18998 -p 23233:23233 -p 50070:50070 -p 8080:8080 -p 9000:19000 -p 8088:8088 -p 4040:4040 -p 6066:16066 -p 7077:17077 spark:v1 /root/run.sh
2 weave run 192.168.0.101/24 -itd --name node1 spark:v1 /root/run.sh
3 weave run 192.168.0.102/24 -itd --name node2 spark:v1 /root/run.sh
4
5 ssh root@172.16.203.101 "weave run 192.168.0.103/24 -itd --name node3 spark:v1 /root/run.sh"
6 ssh root@172.16.203.101 "weave run 192.168.0.104/24 -itd --name node4 spark:v1 /root/run.sh"
7 ssh root@172.16.203.101 "weave run 192.168.0.105/24 -itd --name node5 spark:v1 /root/run.sh"
8
9 docker exec master cp /root/hosts /etc/hosts
10 docker exec node1 cp /root/hosts /etc/hosts
11 docker exec node2 cp /root/hosts /etc/hosts
12
13 ssh root@172.16.203.101 "docker exec node3 cp /root/hosts /etc/hosts"
14 ssh root@172.16.203.101 "docker exec node4 cp /root/hosts /etc/hosts"
15 ssh root@172.16.203.101 "docker exec node5 cp /root/hosts /etc/hosts"
上面的腳本需要詳細的解釋一下:
1)這里使用的是docker原生的網絡功能,端口映射,實際當中并不需要運行weave expose來暴露端口到本機,后面會再次解釋為什么。第1行的意思是,啟動master主節點容器,其中映射出來很多端口都是按照需求映射的,例如spark的端口7077和webUI端口8080,下一個過程解釋為什么7077映射的是17077端口。
這里需要注意的是,--name master,給的是容器名,不過這里的容器主機名也已經變為master,著實方便了很多。
還有一個點是,在master容器內部運行一下ifconfig,可以查看到是兩個網卡,兩個IP,其中一個是原生的網橋docker0生成的172.17.0.0網段,另一個是使用weave生成的192.168.0.0網段。
第2行,第3行,就是創建node1,和node2節點了。這三個節點使用的IP地址是提前規劃好的內網IP地址192.168.0.*。
2)第5,6,7行是利用ssh功能遠程執行命令,創建node3,node4,node5節點。也可以在docker101上面直接執行。
3)第9-15行,是修改這六個容器的/etc/hosts文件,上面已經提前把/root/hosts這個文件寫到容器里面了,容器啟動之后再修改/etc/hosts為自己需要的,因為容器關閉重啟之后這個文件會變動,所以如果容器關閉再次啟動的時候,需要再次執行此段代碼。
4.到目前為止,已經啟動了使用weave創建的192.168.0.0網段相互連通的六個容器,并且IP地址,主機名,/etc/hosts文件,ssh免密碼登錄都已經設定好了。現在就可以登錄到master節點,格式化HDFS,啟動hdfs,yarn,spark等了。關于hadoop和spark都是安裝我們的網絡規劃提前配置好集群的配置文件,和普通的主機集群配置一樣。如果hadoop,spark的配置有點問題,為了方便也可以直接在容器里面再次修改正確就行了。
------------
網絡部分解釋----很重要
此時利用的weave生成的容器會有兩個網卡。其中一個網卡時weave生成的,目的是為了跨主機連通,ip地址是自己規劃的192.168.0.0網段。另一個網卡是原生網絡docker0網橋生成的,可以連接外網使用,由于是NAT方式,所以要使用端口映射從外網連接進入“容器”,IP地址是自動生成的172.17.0.0網段。這一點相當重要,也是下一步為什么要進行端口轉發的問題所在,可以在容器里面運行ifconfig查看一下兩個IP。
----------
第三步,打開端口,實現遠程監控和調試。
在實際生產中遠程的web監控和程序調試是相當實用的,我實習的公司實際的需求就是這樣,先看一個我畫的整體的網絡拓撲圖。
----------
一,整體構架介紹和存在的一個問題。
從上面這個圖來看,貌似有點復雜,先來解釋一下這個真實的環境。
1.網絡部分。
藍色圓形和箭頭是weave相關的網絡部分,是實現跨主機通信的。
紅色圓形和箭頭是docker原生網絡部分,是實現容器訪問外網和外網訪問容器的。
2.client1,client2,client3,這三個客戶端是訪問“master容器”的三種情況。
1)client3,在docker100服務器上訪問容器集群。第一種方法,利用docker0原生網絡端口映射進去。第二種方法,利用weave expose暴露集群的端口到本地主機docker100。
2)client2,從局域網內部別的主機訪問容器集群。只能通過原生網絡docker0。
3)client1,從外網訪問局域網內部的容器集群。只能通過原生網絡docker0。
實際當中,并不需要client3這個方式,下面就不再涉及,client2和client1這兩個方式其實是可以歸為一類,下面以client2來舉例。
3.右上角的那個圖是對master容器節點的一個解釋,現在存在一個問題需要解決--那就是,可以實現client2訪問master容器,但是client2無法訪問到spark集群。下面解釋為什么。
先在master容器里面輸入netstat -tunlp查看一下端口的情況。
root@master:~# netstat -tunlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp6 0 0 192.168.0.100:7077 :::* LISTEN 9843/java
tcp6 0 0 :::8080 :::* LISTEN 9843/java
上面是還以8080和7077端口為例,
: : : 8080 ,8080 端口前面是 : : : ,也就是任意IP。
192.168.0.100:7077,但是7077端口已經被綁定到預先設定好的192.168.0.100上了。
結合畫的圖示解釋:
docker100的IP為IP2:172.16.203.100.
原生網絡docekr0生成的IP3為:172.17.0.*。
weave生成的集群地址IP4位:192.168.0.100。
從圖上顯示可知,利用docker的 -p 參數端口映射可以順利實現IP2 :Port2 --> IP3 :Port3,但是在容器內部無法實現IP3 :Port3 --> IP4 :Port4訪問集群。分析可知,從client2通過原生網絡訪問到容器集群的master容器節點,如果訪問8080端口,可以順利顯示webUI,但是如果想要使用IDEA工具遠程調試程序使用7077端口則不行,因為7077端口是被weave的IP 192.168.0.100占用,此時的問題就是如何才能實現master容器內部從172.17.0.*:prot到192.168.0.100:7077端口的訪問,這樣才能最終訪問到整個spark集群。
----------
二,利用rinetd實現容器內部端口的轉發。
參考網址推薦:
官方網址: http://www.boutell.com/rinetd/
推薦博客: http://iblog.daobidao.com/linu ... BiDao
通過上面兩個資料的閱讀學習,相信已經知道的問題所在和如何解決了。下面就解釋一下是如何操作的。
----------
假設已經在master容器上安裝好rinetd和了解如何使用了。
1.首先查看所有的端口映射的配置文件,這個配置文件按需設定。然后使用命令:rinetd -c /root/rinetd.conf,啟動端口轉發功能,也就是在master內部,端口17077的數據會重定向到spark集群IP和端口192.168.0.100:7077上,最終實現外網訪問spark集群的目的。
root@master:~# cat rinetd.conf
0.0.0.0 19000 192.168.0.100 9000
0.0.0.0 17077 192.168.0.100 7077
0.0.0.0 16066 192.168.0.100 6066
0.0.0.0 18090 192.168.0.100 8090
0.0.0.0 18998 192.168.0.100 8998
0.0.0.0 23233 192.168.0.100 23233
2.再次回顧一下上面生成master 節點容器的命令。
weave run 192.168.0.100/24 -itd --name master -p 8090:18090 -p 8998:18998 -p 23233:23233 -p 50070:50070 -p 8080:8080 -p 9000:19000 -p 8088:8088 -p 4040:4040 -p 6066:16066 -p 7077:17077 spark:v1 /root/run.sh
3.結合上面的整體框架示意圖,以client2和spark程序端口7077和webUI端口8080為例,來描述一下整個實際流程。
1)瀏覽器查看spark集群,在瀏覽器中輸入:172.16.203.100:8080。
172.16.203.100:8080-->master:8080 #端口映射
2)client2主機上面裝有IDEA來編寫scala程序,IDEA軟件里面的地址應該填:172.16.203.100:7077。
172.16.203.100:7077-->master:17077-->master:7077
第一次是端口映射,創建時-p參數指定的17077,第二次是利用rinetd重定向到7077的。
----------
結束語
到此,整個過程就結束了,這篇文章的重點我覺得是畫的那個圖,這是真實的實際環境,應該有點幫助。
再次總結一下重點:
第一,利用weave實現跨主機的通信。
容器可以跨主機通信了,在上面部署hadoop,spark集群就沒有什么壓力了。
第二,實現在外網訪問spark集群程序端口在線調試程序。
也就是就是端口之間的映射,轉發的一些復雜關系,最終的效果就是可以實現遠程調試程序的目的,相當方便。
為了把整個過程講清楚花費了大量的口舌,也不知道講的怎么樣,如有問題,請聯系QQ:604212506,非誠勿擾。
下一篇寫一個shipyard加swarm來監控集群容器的一個工具。
----------
來自: http://dockone.io/article/1047