前面我們瞭解了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的管理界面:
在端口爲5050的mesos 界面,angent欄中可以看到三臺slave已經被添加進來:
使用8080端口訪問的Marathon,由於還沒有添加任務,所以顯示的是“No Application”:
測試容器應用
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界面可以看到已經有一個任務在運行:
在marathon界面,可以看到此容器對外開放的端口:
直接對此端口進行訪問,就可以訪問到我們熟悉的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的創建應用界面,我們可以看到對應的配置選項:
在此界面,我們也可以直接使用json配置的方式,直接編寫我們需要的配置:
輸入以下內容:
{ "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容器:
這裏在配置json的時候,我們指定了默認的端口爲31001:
如果當某個節點出現故障,或者docker 服務意外退出,mesos會自動掉度容器到其他可用的主機上,如果是指定了容器的對外端口,端口不會改變:
停止mesos6上的docker 服務,tomcat 容器將會漂移到其他slave節點
[root@mesos6 ~]# systemctl stop docker
查看Marathon上容器狀態:
容器從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