Mesos+Marathon docker 集羣管理


前面我們瞭解了docker常見的操作和部署方法,在企業中,如果要大規模使用docker就不能通過純手工的方式去維護和部署了。目前比較流行的有兩種解決方案,一種是使用 Mesos+Marathon+docker的方式對集羣中的容器進行管理,另一種方式是使用Kubernetes,就目前Kubernetes有引領行業的趨勢,但是對於小型的集羣管理,mesos符合傳統主從架構,更加簡單。


Mesos介紹

Mesos容器管理的理念個人覺得類似於OpenStack, 通過master將整個集羣的資源蒐集起來,當需要創建容器,或執行某個task時,會根據當前集羣中的資源情況進行調度,對集羣中運行的應用進行統一的資源管理。創建的容器在節點上是隨機分配的(前提是資源足夠的情況下),當某個容器或任務因故障終止後,在其它節點會自動創建一個新的容器來實現高可用。

在 Mesos 上運行的 framework 由兩部分組成:一個是 scheduler ,通過註冊到 master 來獲取集羣資源。另一個是在 slave 節點上運行的 executor 進程,它可以執行 framework 的 task 。 Master 決定爲每個 framework 提供多少資源, framework 的 scheduler 來選擇其中提供的資源。當 framework 同意了提供的資源,它通過 master 將 task發送到提供資源的 slaves 上運行。


配置mesos集羣

本次示例使用6臺CentOS7.2主機,3臺作爲mesos-master集羣,另外3臺作爲mesos-slave。slave上運行容器執行task.

1、系統初始化:

對這六臺機器配置hosts解析,並添加yum源:

cat >>/etc/hosts <<EOF
192.168.20.41 mesos1       # master
192.168.20.42 mesos2       # master
192.168.20.43 mesos3       # master
192.168.20.44 mesos4       # slave
192.168.20.45 mesos5       # slave
192.168.20.46 mesos6       # slave
EOF
setenforce 0
sed -i 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/sysconfig/selinux
systemctl stop firewalld
systemctl disable firewalld
rpm -Uvh http://repos.mesosphere.io/el/7/noarch/RPMS/mesosphere-el-repo-7-2.noarch.rpm


2、配置mesos-master

在mesos1,mesos2和mesos3上配置zookeeper集羣:

yum install -y java-1.8.0-openjdk-devel java-1.8.0-openjdk
yum -y install mesos marathon mesosphere-zookeeper

配置zookeeper集羣ID

mesos1: 

echo 1 > /var/lib/zookeeper/myid

mesos2: 

echo 2 > /var/lib/zookeeper/myid

mesos3: 

echo 3 > /var/lib/zookeeper/myid

在3臺master上, 配置zookeeper集羣信息:

vim /etc/zookeeper/conf/zoo.cfg
maxClientCnxns=50                     #單個客戶端與單臺服務器之間的連接數的限制,是ip級別的,默認是50,如果設置爲0,那麼表明不作任何限制。請注意這個限制的使用範圍,僅僅是單臺客戶端機器與單臺ZK服務器之間的連接數限制,不是針對指定客戶端IP,也不是ZK集羣的連接數限制,也不是單臺ZK對所有客戶端的連接數限制。
tickTime=2000                         #Zookeeper 服務器之間或客戶端與服務器之間維持心跳的時間間隔,也就是每個 tickTime 時間就會發送一個心跳
initLimit=10                          #Zookeeper的Leader 接受客戶端(Follower)初始化連接時最長能忍受多少個心跳時間間隔數。當已經超過 5個心跳的時間(也就是tickTime)長度後 Zookeeper 服務器還沒有收到客戶端的返回信息,那麼表明這個客戶端連接失敗。總的時間長度就是 5*2000=10 秒
syncLimit=5                           #表示 Leader 與 Follower 之間發送消息時請求和應答時間長度,最長不能超過多少個tickTime 的時間長度,總的時間長度就是 2*2000=4 秒
dataDir=/var/lib/zookeeper            #zookeeper數據文件存放目錄
clientPort=2181                       #客戶端連接端口
server.1=192.168.20.41:3181:4181      #數字1,2,3表示這個是第幾號服務器(是上面myid文件裏對應的數字);中間的是master主節點的ip地址
server.2=192.168.20.42:3181:4181      #第一個端口2888(這個端口可以自己定義)表示的是這個服務器與集羣中的 Leader 服務器交換信息的端口
server.3=192.168.20.43:3181:4181      #第二個端口3888表示的是萬一集羣中的 Leader 服務器掛了,需要一個端口來重新進行選舉,選出一個新的 Leader,而這個端口就是用來執行選舉時服務器相互通信的端口。

配置集羣端口:

vim /etc/mesos/zk 

zk://192.168.20.41:2181,192.168.20.42:2181,192.168.20.43:2181/mesos

配置仲裁,此處使用的是3個節點,所以配置仲裁數目爲2 (集羣節點數目/2,四捨五入):

cat /etc/mesos-master/quorum
2

mesos集羣是通過zookeeper來交互的,所以只需要配置zookeeper即可, 配置完成之後,啓動mesos-master集羣:

systemctl enable zookeeper && systemctl enable mesos-master && systemctl enable marathon
systemctl start zookeeper && systemctl start mesos-master && systemctl start marathon
systemctl disable mesos-slave

查看zookeeper的狀態:

/opt/mesosphere/zookeeper/bin/zkServer.sh status /etc/zookeeper/conf/zoo.cfg

確認mesos-master 和marathon啓動,並開放端口:

systemctl status mesos-master 
systemctl status marathon


3.  配置各slave節點

安裝docker 和mesos :

yum install docker -y
yum install mesos -y

配置slave的master信息以及運行方式:

echo "zk://192.168.20.41:2181,192.168.20.42:2181,192.168.20.43:2181/mesos" > /etc/mesos/zk
echo 'docker,mesos' > /etc/mesos-slave/containerizers

啓動服務:

systemctl start docker && systemctl enable docker
systemctl start mesos-slave && systemctl enable mesos-slave

下載docker 鏡像(可參考配置國內鏡像源的方式):

docker pull nginx
docker pull tomcat

4. 登錄master上的任意一臺機器, 分別進入 mesos和marathon的管理界面:

http://192.168.20.41:5050

http://192.168.20.41:8080 


在端口爲5050的mesos 界面,angent欄中可以看到三臺slave已經被添加進來:

wKioL1mKadDB80-oAAGke7PhkmI864.jpg

使用8080端口訪問的Marathon,由於還沒有添加任務,所以顯示的是“No Application”:

wKioL1mKataCrBsjAAESE9FyFpk285.jpg


測試容器應用


1、marathon可以使用REST API的方式來處理任務需求,我們先測試通過API的方式來創建一個nginx的docker容器

在master上編輯nginx.json:

{
  "id":"nginx",
  "cpus":0.2,
  "mem":20.0,
 "instances": 1,
 "constraints": [["hostname", "UNIQUE",""]],
 "container": {
    "type":"DOCKER",
   "docker": {
     "image": "nginx",
     "network": "BRIDGE",
     "portMappings": [
        {"containerPort": 80, "hostPort": 0,"servicePort": 0, "protocol": "tcp" }
      ]
    }
  }
}

使用POST 方法執行:

curl -X POST http://192.168.20.41:8080/v2/apps -d @nginx.json -H "Content-type: application/json"

執行此命令後,會返回一串json的詳細配置信息,在mesos界面可以看到已經有一個任務在運行:

wKiom1mKcMHT0KdvAAIorY3iK3U321.jpg

在marathon界面,可以看到此容器對外開放的端口:

wKiom1mKcZ7jbFKZAAFWDLQgbBI202.jpg

直接對此端口進行訪問,就可以訪問到我們熟悉的nginx初始界面。


我們可以查看在mesos5這臺機器上的容器狀態:

[root@mesos5 ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                        PORTS                   NAMES
ee6639983450        nginx               "nginx -g 'daemon off"   11 minutes ago      Up 11 minutes                 0.0.0.0:31495->80/tcp   mesos-398a0a16-fe13-48e6-9a9c-6932c6c58014-S1.525f7318-9bb7-486c-9c3a-13d5294f37ff

查看端口:

[root@mesos5 ~]# docker port ee6639983450 
80/tcp -> 0.0.0.0:31495

mesos上創建的容器映射的對外端口,默認會使用31000-32000之間的隨機端口。


使用Marathon管理容器

在日常的操作中,爲了更加方便快捷的使用docker,可以通過使用Marathon來管理容器。

在Marathon的創建應用界面,我們可以看到對應的配置選項:

wKiom1mKd0Gz5p87AAEHySJl-8c245.jpg

在此界面,我們也可以直接使用json配置的方式,直接編寫我們需要的配置:

wKioL1mKeynBADYfAAEGp3tZsMs781.jpg

輸入以下內容:

{  
"id":"tomcat",  
"cpus":1,  
"mem":128,  
"instances": 1,  
"constraints": [["hostname", "UNIQUE",""]],  
"container": {  
"type":"DOCKER",  
"docker": {  
"image": "tomcat",                                              
"network": "BRIDGE", 
"portMappings": [  
{"containerPort": 8080, "hostPort": 31001,"servicePort": 31002, "protocol": "tcp" }  
]  
  }  
    }  
      }

這裏指定了容器端口和對外映射的端口,hostPort爲主機上映射的端口,可指定的範圍是31000到32000,如果設置爲0 表示隨機分配端口。當containerPort和hostPort都設置爲0時,將隨機分配一個相同的端口。


點擊“Create Application”即可創建出一個tomcat容器:

wKiom1mKe8ayPI0AAAEdLhgGuBA769.jpg


這裏在配置json的時候,我們指定了默認的端口爲31001:

wKioL1mKfMyTEKGJAAFFEmYndEs641.jpgwKiom1mKfYKSK8pqAAGItmL94h0435.jpg

如果當某個節點出現故障,或者docker 服務意外退出,mesos會自動掉度容器到其他可用的主機上,如果是指定了容器的對外端口,端口不會改變:

停止mesos6上的docker 服務,tomcat 容器將會漂移到其他slave節點

[root@mesos6 ~]# systemctl stop docker

查看Marathon上容器狀態:

wKiom1mKf2Hgp-XVAAD7uUTr1Uc086.jpg

容器從mesos6 漂移到了mesos4, 對外端口不變:

[root@mesos4 ~]# docker ps 
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                     NAMES
03b70cad8ad9        tomcat              "catalina.sh run"   4 minutes ago       Up 3 minutes        0.0.0.0:31001->8080/tcp   mesos-398a0a16-fe13-48e6-9a9c-6932c6c58014-S0.6b97951a-336e-47ab-84c9-38229e9ba132
[root@mesos4 ~]# docker port 03b70cad8ad9
8080/tcp -> 0.0.0.0:31001


mesos創建容器流程

目前,Docker Containerizer 作爲任務啓動時,需要執行以下操作:

將所有在 CommandInfo 中指定的文件放入一個隔離的沙盒中

從遠程倉庫拉取 docker 鏡像

使用 Docker executor 來運行 docker 鏡像,同時將沙盒目錄映射到容器中環境變量 MESOS_SANDBOX 所指定的目錄。 executor 也將容器的日誌流重新定向到外部的 stdout/stderr 文件。

當退出容器或者銷燬 containerizer 時,停止並移除 docker 容器實例。

Docker Containerizer 啓動的容器的 ID 由 前綴" mesos- " 加上 slave ID( 如,mesos-slave1-abcdefghji )組成,並且假設所有以 " mesos- "爲前綴的容器都由 slave 管理,slave 可以任意停止和銷燬容器。


在創建容器的時候會出現容器創建不成功的情況,一般有如下幾種原因:

1、環境資源不足。在mesos資源管理界面,可以看到當前資源的使用情況,如果容器的cpu,內存,磁盤等資源超出當前環境可以提供的範圍,容器創建會失敗。

2、當前環境中無可用的鏡像。創建容器時,如果本地沒有對應的鏡像,docker默認會從官方下載,但是下載不一定會成功,可以查看系統進程,如果長時間卡在 docker pull等命令上,就是無法獲取鏡像。建議先在本地創建好鏡像資源。

3、端口指定超出範圍。在指定hostPort時,也需要指定servicePort, 且端口範圍必須在31000-32000之間,否則創建容器的時候會出錯。這個端口範圍可以通過配置修改,在實際應用中一般使用marathon-lb來解決隨機端口的問題。



參考資料:

https://mesos-cn.gitbooks.io/mesos-cn/content/OverView/Mesos-Architecture.html 

http://www.cnblogs.com/kevingrace/p/5685313.html 

https://mesosphere.github.io/marathon/docs/ports.html 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章