Marathon 容器編排


mesos上負責長任務處理的Framework,也就是所謂的服務調度框架。
marathon設計之初的目標是讓shell命令都能通過marathon遠程調度,並保存長任務進程持續進行。

有web界面

 

# 重要概念
Application definition  長服務的定義,規定了APP啟動和運行時的所有行為。Marathon提供了兩種方式讓你來定義你的長服務,
  1、通過Portal來定義,它方便通過終端用戶的理解和使用,
  2、通過json格式的文件來定義,並通過restapi的方式來創建和管理這個app,兩種方式方便和第三方的系統進行集成,提供了再次的可編程接口
Application instance
  app的實例,也稱作mesos的一個task,marathon可以為一個APP創建和管理多個實例,並可以動態的增大和減小某個APP實例的個數
  並且通過marathon-lb實現服務發現和負載均衡
Application  一個長服務,例如(批處理、docker ) Deployments
  對APP或者group的definition的一次修改的提交稱為一次deployment. 他包括創建、銷毀、擴容縮容APP或者group等。多個deployments可以是同時進行。
  但是對於一個應用的deployments必須是串行的,如果前一個deployment沒有結束就執行下一個deployment,那么它將會被拒絕。
Application Group
,同一group中APP可以被marathon統一管理

  

# 生命周期
Running Deploying 應用程序的每一次改變操作沒完成之前,我們的應用都屬於一個deploying的狀態 Suspended 把這個應用的所有正在運行的實例殺掉,並把這個應用的實例的數量減為0,這時這個應用只保留了定義,
  並沒有正在運行的實例。
Waiting
  等待mesos進行下一資源的分配
Delayed
  短時間內,失敗次數過多。

 

# 應用操作
scale
    為某個應用增加或減少指定數量的實例
restart
    重啟應用
suspend
    殺死這個應用正在運行的實例,並把應用任務定義的數量減為0,
destory
    實例和定義全部刪除

 

http://mesosphere.github.io/marathon/docs/
前提是已經安裝好Mesos,見我的系列文章。
Marathon安裝也有兩種方式:官網手動安裝;使用yum安裝。> 這里我們使用yum的簡單安裝。
Note:使用yum安裝Marathon時不需要任何必要的配置,在哪個節點上安裝,Marathon就會在哪個節點上啟動,建議安裝到master節點上
sudo yum -y install marathon(就這么簡單)

其實這個設置和安裝Mesos時配置mesos的hostname效果一樣,不配置會顯示默認的localhost,不影響使用>
mkdir -p /etc/marathon/conf/;touch hostname echo 192.168.1.24 /etc/marathon/conf/hostname systemctl start marathon.service

vi /etc/default/marathon
export HTTP_PORT=8181
export MARATHON_HTTP_PORT=8181
MESOS_NATIVE_JAVA_LIBRARY=/usr/local/lib/libmesos.so /app/marathon-1.5.1/bin/marathon \
 --master local \
 --zk zk://localhost:2181/marathon
curl -X POST http://192.168.9.61:8080/v2/apps -d @basic-3.json
-H "Content-type:application/json"

 

import requests
import json
 

headers = {'Content-type': 'application/json'}


class MarathonApi():

    def test_ping(self):
        url = "http://192.168.9.61:8080/v2/info"

        r = requests.get(url, headers=headers)

        print(r.status_code)
        print(json.dumps(r.json(), indent=4))

    def test_create_docker_app(self):
        url = "http://192.168.9.62:8080/v2/apps"

        app = {
            "id": "ch5",
            "cmd": "python app.py",
            "cpus": 0.1,
            "mem": 32.0,
            "instances": 10,
            "upgradeStrategy": {
                "maximumOverCapacity": 1,
                "minimumHealthCapacity": 0.5
            },
            "constraints": [["hostname", "GROUP_BY"]],
            "networks": [{"mode": "container/bridge"}],
            "container": {
                "type": "DOCKER",
                "docker": {"image": "192.168.9.69:5000/imooc:v1.0.6"},
                "portMappings": [{"containerPort": 5000, "hostPort": 0}]   # 0是指隨機端口
            },
            "healthChecks": [       # 200-399
                {
                    "path": "/",
                    "portIndex": 0,
                    "protocol": "HTTP",
                    "gracePeriodSeconds": 300, # 忽略時間,一般啟動的時候用到
                    "intervalSeconds": 60,# 檢查時間
                    "timeoutSeconds": 20,#超時時間
                    "maxConsecutiveFailures": 3,#最大失敗次數
                    "ignoreHttp1xx": False
                }
            ]
        }

        r = requests.post(url, headers=headers, json=app)

        print(r.status_code)
        print(json.dumps(r.json(), indent=4))

   
    def test_scale_app(self):
        url = "http://192.168.9.62:8080/v2/groups/product"
      # 當當前應用處於一個鎖定狀態時,在url后添加  ?force=true,強制進行當前操作
        app = {
            "instances": 1,
        }

        r = requests.put(url, headers=headers, json=app)

        print(r.status_code)
        print(json.dumps(r.json(), indent=4))

    def test_group_app(self):
        url = "http://192.168.9.62:8080/v2/apps"

        group = {
            "id": "/product",
            "groups": [
                {
                    "id": "/product/database",
                    "apps": [

                        {"id": "/product/database/mongo",
                         "cpus": 1,
                         "mem": 32.0,
                         "cmd": "mongod",
                         "networks": [{"mode": "container/bridge"}],
                         "container": {
                             "type": "DOCKER",
                             "docker": {"image": "mongo:3.0"},
                             "portMappings": [{"containerPort": 8081, "hostPort": 0}]
                         }
                         },
                        {
                            "id": "/product/database/mysql",
                            "cpus": 1,
                            "mem": 32.0,
                            "cmd": "mysqld",
                            "networks": [{"mode": "container/bridge"}],
                            "container": {
                                "type": "DOCKER",
                                "docker": {"image": "mysql:5.6"},
                                "portMappings": [{"containerPort": 3306, "hostPort": 0}]
                            }
                        }

                    ]
                }, {
                    "id": "/product/service",
                    "dependencies": ["/product/database"],
                    "apps": [
                        {"id": "/product/service/app",
                         "cpus": 1,
                         "mem": 32.0,
                         "cmd": "python app.py",
                         "networks": [{"mode": "container/bridge"}],
                         "container": {
                             "type": "DOCKER",
                             "docker": {"image": "192.168.9.69:5000/imooc:v1.0.1"},
                             "portMappings": [{"containerPort": 5000, "hostPort": 0}]
                         }
                         }
                    ]
                }
            ]
        }

        r = requests.post(url, headers=headers, json=group)

        print(r.status_code)
        print(json.dumps(r.json(), indent=4))  

    def test_update_group(self):
        url = "http://192.168.9.62:8080/v2/groups/product"

        app = {
            "id": "/product",
            "dependencies": [],
            "apps": [
                {
                    "id": "/product/db",
                    "instances": 10,
                    "cpus": 0.1,
                    "mem": 32,
                    "upgradeStrategy": {
                        "maximumOverCapacity": 1,
                        "minimumHealthCapacity": 0.6
                    },
                    "container": {
                        "type": "DOCKER",
                        "docker": {
                            "image": "mongo:3.4",
                        },
                        "portMappings": [
                            {
                                "containerPort": 27017,
                                "hostPort": 0,
                                "protocol": "tcp",
                                "servicePort": 10001
                            }
                        ]
                    },
                    "healthChecks": [
                        {
                            "gracePeriodSeconds": 300,
                            "intervalSeconds": 60,
                            "maxConsecutiveFailures": 0,
                            "portIndex": 0,
                            "protocol": "TCP",
                            "timeoutSeconds": 20,
                            "delaySeconds": 15
                        }
                    ],
                    "networks": [
                        {
                            "mode": "container/bridge"
                        }
                    ]

                },
                {
                    "id": "/product/service",
                    "cmd": "python app.py",
                    "cpus": 0.1,
                    "mem": 128,
                    "instances": 10,
                    "dependencies": [
                        "/product/db"
                    ],
                    "upgradeStrategy": {
                        "maximumOverCapacity": 1,
                        "minimumHealthCapacity": 0.8 ,#  在新實例啟動前,講舊實例刪除到原80%
                    },
                    "container": {
                        "type": "DOCKER",
                        "docker": {

                            "image": "192.168.9.69:5000/imooc:v1.0.7",

                        },
                        "portMappings": [
                            {
                                "containerPort": 5000,
                                "hostPort": 0,
                                "labels": {},
                                "protocol": "tcp",
                                "servicePort": 10002
                            }
                        ]
                    },
                    "healthChecks": [
                        {
                            "gracePeriodSeconds": 300,
                            "ignoreHttp1xx": False,
                            "intervalSeconds": 60,
                            "maxConsecutiveFailures": 3,
                            "path": "/",
                            "portIndex": 0,
                            "protocol": "HTTP",
                            "timeoutSeconds": 20,
                            "delaySeconds": 15
                        }
                    ],
                    "networks": [
                        {
                            "mode": "container/bridge"
                        }
                    ]
                }
            ],
            "groups": [],
            "pods": []
        }

        r = requests.put(url, headers=headers, json=app)

        print(r.status_code)
        print(json.dumps(r.json(), indent=4))
py請求

 

滾動升級

marathon允許用戶執行滾動升級來部署一個新的版本,具體操作如下:
    1、刪除部分舊版本的實例,保留另外一部分的舊版本實例
    2、啟動新版本的實例,健康檢查通過
    3、刪除剩下的舊版本實例
minimumHealehCapacity == 0
在新實例啟動后,再刪除掉就實例
1、刪除全部舊實例
2、啟動新實例,健康檢查通過
3、pass
minimumHealehCapacity == 1 
在新實例啟動后,再刪除掉就實例
1、刪除0個舊版本實例(啟動n個新的實例)
2、啟動新實例,健康檢查通過
3、刪除剩下的全部舊版本實例
minimumHealehCapacity == 0.5
按比例刪除,舊版本

 

 

策略約束定義

用來約束控制程序運行的位置,實現優化容錯。


分散容器運行在不同的節點上
[hostname,cluster,mesos-node1]
字段名稱  操作符  可選參數
hostname;rack_id 機架ID

 

操作符
UNIQUE
CLUSTER  // 與unique相反,允許你將任務運行在同一個資源中 --->同一台機器
      //【hostname ,cluster,node2】 LIKE
    // [hostname ,like ,mesos-node[1-2]] UNLIKE GROUP_BY  // 將任務均勻地分散到機架或數據中心,提高可用性

 

服務注冊、服務發現
1:n           將路由分配后多個docker當中

marathon中實例對外提供服務需解決的兩個問題:
    1、集群中實例的網絡地址  是動態分配
    2、marathon自動擴縮容,滾動升級等因素隨時改變實例服務器端口


解決思路:
1、需要一個列表,隨時記錄應用的IP和端口情況(服務注冊)
2、需要一個負載均衡,並能根據端口情況隨時修改配置,實現轉發    (負載均衡)
服務注冊中心保存了各個服務可用的實例的相關信息。
服務注冊中心提供了管理API和查詢API。使用管理API進行服務注冊、注銷。
系統的其他組件可以通過查詢API來獲得可用的服務實例信息
負載均衡是一種服務器或網絡設備的集群技術。負載均衡將特定的業務分擔給多個服務器或網
絡設備,從而提高了業務處理能力,保證了業務的高可用性。
# marathon-lb

import requests
import json

headers = {'Content-type': 'application/json'}


class ServiceDiscoveryApi():

    def test_create_marathon_lb(self):
        """安裝marathon-lb"""
        url = "http://192.168.9.62:8080/v2/apps"
        app = {
            "id": "/marathon-lb",
            "cmd": None,
            "cpus": 1,
            "mem": 128,
            "disk": 0,
            "instances": 1,
            "container": {
                "type": "DOCKER",
                "volumes": [],
                "docker": {
                    "image": "docker.io/mesosphere/marathon-lb",
                    "network": "HOST",
                    "portMappings": [],
                    "privileged": True
                }
            },
            "healthChecks": [
                {
                    "gracePeriodSeconds": 30,
                    "intervalSeconds": 5,
                    "timeoutSeconds": 5,
                    "maxConsecutiveFailures": 5,
                    "port": 9090,
                    "path": "/_haproxy_health_check",
                    "protocol": "HTTP",
                    "ignoreHttp1xx": False
                }
            ],
            "args": ["sse", "-m", "http://192.168.9.62:8080", "--group", "external"]
        }

        r = requests.post(url, headers=headers, json=app)
        print(json.dumps(r.json(), indent=4))

    def test_create_app(self):
        url = "http://192.168.9.62:8080/v2/apps"
        app = {
            "id": "ch6-green",
            "cmd": "python app.py",
            "cpus": 0.1,
            "mem": 32.0,
            "instances": 1,
            "upgradeStrategy": {
                "maximumOverCapacity": 1,
                "minimumHealthCapacity": 0.5
            },
            "networks": [
                {"mode": "container/bridge"}],
            "container": {
                "type": "DOCKER",
                "docker": {"image": "192.168.9.69:5000/imooc:v1.0.7"},
                "portMappings": [
                    {
                        "containerPort": 5000,
                        "hostPort": 0,
                        "labels": {},
                        "protocol": "tcp",
                        "servicePort": 10001
                    }
                ]
            },
            "healthChecks": [
                {
                    "path": "/",
                    "portIndex": 0,
                    "protocol": "HTTP",
                    "gracePeriodSeconds": 300,
                    "intervalSeconds": 60,
                    "timeoutSeconds": 20,
                    "maxConsecutiveFailures": 3,
                    "ignoreHttp1xx": False
                }
            ],
            "labels": {
                "HAPROXY_GROUP": "external"
            }
        }

        r = requests.put(url, headers=headers, json=app)
        print(json.dumps(r.json(), indent=4))
View Code

 

# 1、創建
"args": ["sse", "-m", "http://192.168.9.62:8080", "--group", "external"]
# 2、注冊
"
portMappings": [ { "containerPort": 5000, "hostPort": 0, "labels": {}, "protocol": "tcp", "servicePort": 10001 # 集群分配給APP的一個端口,對於每個應用來說是唯一的,對外暴露的端口, ip是lb這個容器運行的機器地址。 } ]
"labels": {
          "HAPROXY_GROUP": "external"
}

 

 

負載均衡實現-HAProxy

HAProxy是一款提高高可用性、負載均衡以及基於TCP和HTTP應用的代理軟件,HAProxy特別適用於那些負載特大的web站點
,完全可以支持數以萬計的並發連接。並且它的運行模式使得它可以很簡單、安全的整合進您當前的架構中,
同時可以保護你的web服務器不被暴露到網絡中。
運行在了9090端口上
lb容器機器IP:9090/haproxy?stat;csv

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM