天天看点

基于Mesos+Marathon+Zookeeper的Docker容器管理平台

刚接触docker的时候,发现docker很像一个虚拟机,随着使用的增多,它给我们的开发工作带来了极大的方便,因此就想自己搭建一个docker集群环境,以便更深入了解docker集群的工作原理。

之前曾经尝试分别安装mesos,marathon和zookeeper,组成分布式系统,但是在安装、配置过程中遇到了各种各样的问题,特别是mesos,问题比较多。既然docker容器的使用十分方便,所以我就使用基于容器的方式来搭建docker集群环境,我也推荐大家这样做,特别方便。

1. 准备工作

1.1 三台虚拟机

  • 192.168.56.103:ubuntu-1
  • 192.168.56.101:ubuntu-2
  • 192.168.56.102:ubuntu-3

1.2 应用部署

三台主机分别部署zookeeper,mesos-master,mesos-slave,marathon

hostname application
ubuntu-1 zookeeper,mesos-master,mesos-slave,marathon
ubuntu-2 zookeeper,mesos-master,mesos-slave,marathon
ubuntu-3 zookeeper,mesos-master,mesos-slave,marathon

1.3 安装docker环境

参考docker官网ubuntu操作系统安装过程

https://docs.docker.com/engine/installation/linux/ubuntulinux/

2. 下载docker镜像

docker pull mesoscloud/zookeeper   #zookeeper
docker pull mesoscloud/mesos-master   #mesos-master
docker pull mesoscloud/mesos-slave   #mesos-slave 
docker pull mesoscloud/marathon   #marathon 
docker pull davidcaste/alpine-tomcat   #tomcat
           

3. 启动docker镜像

以下命令分别在三台主机运行,将ip地址和相关参数修改为对应主机的ip地址和参数

3.1 运行zookeeper

docker run -d \
-e MYID= \ #每台主机对应一个id,三台主机分别对应1,2,3
-e SERVERS=.,.,. \ #三台主机的ip地址
--name=zookeeper \
--net=host \
--restart=always \
mesoscloud/zookeeper
           

3.2 运行mesos-master

docker run -d \
-e MESOS_HOSTNAME=. \ #第一台主机ip地址
-e MESOS_IP=. \ #第一台主机ip地址
-e MESOS_QUORUM= \
-e MESOS_ZK=zk://192.168.56.103:2181,192.168.56.101:2181,192.168.56.102:2181/mesos \
--name mesos-master \
--net host \
--restart=always \
mesoscloud/mesos-master
           

3.3 运行mesos-slave

docker run -d \
-e MESOS_HOSTNAME=. \ #第一台主机ip地址
-e MESOS_IP=. \ #第一台主机ip地址
-e MESOS_MASTER=zk://192.168.56.103:2181,192.168.56.101:2181,192.168.56.102:2181/mesos \
-v /sys/fs/cgroup:/sys/fs/cgroup \
-v /var/run/docker.sock:/var/run/docker.sock \
--name mesos-slave \
--net host \
--privileged \
--restart=always \
mesoscloud/mesos-slave
           

3.4 运行marathon

docker run -d \
-e MARATHON_HOSTNAME=. \ #第一台主机ip地址
-e MARATHON_HTTPS_ADDRESS=. \ #第一台主机ip地址
-e MARATHON_HTTP_ADDRESS=. \ #第一台主机ip地址
-e MARATHON_MASTER=zk://192.168.56.103:2181,192.168.56.101:2181,192.168.56.102:2181/mesos \
-e MARATHON_ZK=zk://192.168.56.103:2181,192.168.56.101:2181,192.168.56.102:2181/marathon \
--name marathon \
--net host \
--restart=always \
mesoscloud/marathon
           

4. 通过Marathon发布应用

4.1 在第一台一台主机访问http://192.168.56.103:8080,任何一台主机的8080端口都可以访问marathon,打开marathon UI,创建应用,点击Create Application,填写应用信息,发布应用,Json模式数据如下:

{
  "id": "tomcat",
  "cmd": "/opt/tomcat/bin/catalina.sh run",
  "cpus": ,
  "mem": ,
  "disk": ,
  "instances": ,
  "container": {
    "docker": {
      "image": "davidcaste/alpine-tomcat",
      "network": "BRIDGE",
      "portMappings": [
        {
          "containerPort": ,
          "protocol": "tcp",
          "name": null
        }
      ],
      "parameters": []
    },
    "type": "DOCKER",
    "volumes": [
      {
        "hostPath": "/var/dockertest/logs",
        "containerPath": "/logs",
        "mode": "RW"
      }
    ]
  },
  "env": {},
  "labels": {},
  "healthChecks": []
}
           

4.2 也可以通过marathon提供的rest接口发布应用

curl -X POST -H "Accept: application/json" -H "Content-Type: application/json" :/v2/apps -d'
{
  "id": "tomcat",
  "cmd": "/opt/tomcat/bin/catalina.sh run",
  "cpus": ,
  "mem": ,
  "disk": ,
  "instances": ,
  "container": {
    "docker": {
      "image": "davidcaste/alpine-tomcat",
      "network": "BRIDGE",
      "portMappings": [
        {
          "containerPort": ,
          "protocol": "tcp",
          "name": null
        }
      ],
      "parameters": []
    },
    "type": "DOCKER",
    "volumes": [
      {
        "hostPath": "/var/dockertest/logs",
        "containerPath": "/logs",
        "mode": "RW"
      }
    ]
  },
  "env": {},
  "labels": {},
  "healthChecks": []
}'
           

5. 查看应用状态

5.1 marathon主页面(http://192.168.56.103:8080)

基于Mesos+Marathon+Zookeeper的Docker容器管理平台

5.2 击进入应用页面,只有一个实例

基于Mesos+Marathon+Zookeeper的Docker容器管理平台

5.3 点击Scale Application扩展三个实例

基于Mesos+Marathon+Zookeeper的Docker容器管理平台

5.4 打开mesos主页面(http://192.168.56.103:5050),可以看到有三个tomcat实例

基于Mesos+Marathon+Zookeeper的Docker容器管理平台

5.5 在Mesos中打开Framework页面,我们可以看到marathon框架的正在运行。

基于Mesos+Marathon+Zookeeper的Docker容器管理平台

5.6 接下来我们看一下mesos-slave页面,看到运行正常的三个mesos-slave。

基于Mesos+Marathon+Zookeeper的Docker容器管理平台

6. 调用服务

我们通过marathon把tomcat运行起来了,但是tomcat里没有war包,所以我们将准备好的一个war包放进三台主机的tomcat里,这里是为了测试方便,我们直接使用docker cp命令将war包复制到docker容器当中。在实际应用中我们可以通过其他方式来加载war包,比如,在CMD命令里通过wget方式将war包下载到容器里,或者通过卷Volume的方式共享,将war包放到tomcat的webaps目录下。

[email protected]-:~$ docker ps
CONTAINER ID        IMAGE                      COMMAND                  CREATED             STATUS              PORTS                     NAMES
dd014c78d8ec        davidcaste/alpine-tomcat   "/bin/sh -c '/opt/tom"    minutes ago      Up  minutes       :->/tcp   mesos-b67-e403-a0-bffd-cbfa03da51b-S0.e9647bd1--b-a01e-a0ae68c62f9
dbe2256d5        mesoscloud/marathon        "/usr/local/bin/dumb-"    hours ago         Up  hours                                    marathon
dfaabf2cd3e        mesoscloud/mesos-slave     "/usr/local/bin/dumb-"    hours ago         Up  hours                                    mesos-slave
e94c3202f529        mesoscloud/mesos-master    "/usr/local/bin/dumb-"    hours ago         Up  hours                                    mesos-master
a3389a386a11        mesoscloud/zookeeper       "/usr/local/bin/dumb-"    hours ago         Up  hours                                    zookeeper
[email protected]-:~$ docker cp /mnt/share/backendresource.war dd014c78d8ec:/opt/tomcat/webapps #dd014c78d8ec为Container ID
[email protected]-:~$ 
           

接下来我们访问服务查看返回结果

suser@ubuntu-:~$ curl .:/backendresource///
{"ACT_TAG":"1","X_RESULTCODE":"0"}
suser@ubuntu-:~$ curl .:/backendresource///
{"ACT_TAG":"1","X_RESULTCODE":"0"}
suser@ubuntu-:~$ curl .:/backendresource///
{"ACT_TAG":"1","X_RESULTCODE":"0"}
           

查看docker容器日志

[email protected]:~$ docker logs dd014c78d8ec
log4j:WARN No such property [encoding] in org.apache.log4j.net.SyslogAppender.
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
-- :: [INFO ](BackendResources              ) [TxId :  , SpanId : ] 榛戝悕鍗昩ackendresource缁撴灉:{"ACT_TAG":"1","X_RESULTCODE":"0"},鏈璋冪敤鑰楁椂:ms
-- :: [INFO ](BackendResources              ) [TxId :  , SpanId : ] 榛戝悕鍗昩ackendresource缁撴灉:{"ACT_TAG":"0","X_RESULTCODE":"0"},鏈璋冪敤鑰楁椂:ms
[email protected]:~$ 
           

在容器也看到了调用日志,看到中文是乱码,这个可能是容器字符编码问题。

7. 通过marathon rest接口获取数据

#通过marathon接口获取所有应用信息
suser@ubuntu-:~$ curl .:/v2/apps
{"apps":[{"id":"/tomcat","cmd":"/opt/tomcat/bin/catalina.sh run","args":null,"user":null,"env":{},"instances":,"cpus":.,"mem":,"disk":,"executor":"","constraints":[],"uris":[],"fetch":[],"storeUrls":[],"ports":[],"portDefinitions":[{"port":,"protocol":"tcp","labels":{}}],"requirePorts":false,"backoffSeconds":,"backoffFactor":,"maxLaunchDelaySeconds":,"container":{"type":"DOCKER","volumes":[],"docker":{"image":"davidcaste/alpine-tomcat","network":"BRIDGE","portMappings":[{"containerPort":,"hostPort":,"servicePort":,"protocol":"tcp","labels":{}}],"privileged":false,"parameters":[],"forcePullImage":false}},"healthChecks":[],"readinessChecks":[],"dependencies":[],"upgradeStrategy":{"minimumHealthCapacity":,"maximumOverCapacity":},"labels":{},"acceptedResourceRoles":null,"ipAddress":null,"version":"2016-10-15T21:20:55.434Z","residency":null,"versionInfo":{"lastScalingAt":"2016-10-15T21:20:55.434Z","lastConfigChangeAt":"2016-10-15T16:58:42.119Z"},"tasksStaged":,"tasksRunning":,"tasksHealthy":,"tasksUnhealthy":,"deployments":[]}]}suser@ubuntu-:~$ 

##通过marathon接口获取tomcat应用信息
suser@ubuntu-:~$ curl .:/v2/apps/tomcat
{"app":{"id":"/tomcat","cmd":"/opt/tomcat/bin/catalina.sh run","args":null,"user":null,"env":{},"instances":,"cpus":.,"mem":,"disk":,"executor":"","constraints":[],"uris":[],"fetch":[],"storeUrls":[],"ports":[],"portDefinitions":[{"port":,"protocol":"tcp","labels":{}}],"requirePorts":false,"backoffSeconds":,"backoffFactor":,"maxLaunchDelaySeconds":,"container":{"type":"DOCKER","volumes":[],"docker":{"image":"davidcaste/alpine-tomcat","network":"BRIDGE","portMappings":[{"containerPort":,"hostPort":,"servicePort":,"protocol":"tcp","labels":{}}],"privileged":false,"parameters":[],"forcePullImage":false}},"healthChecks":[],"readinessChecks":[],"dependencies":[],"upgradeStrategy":{"minimumHealthCapacity":,"maximumOverCapacity":},"labels":{},"acceptedResourceRoles":null,"ipAddress":null,"version":"2016-10-15T21:20:55.434Z","residency":null,"versionInfo":{"lastScalingAt":"2016-10-15T21:20:55.434Z","lastConfigChangeAt":"2016-10-15T16:58:42.119Z"},"tasksStaged":,"tasksRunning":,"tasksHealthy":,"tasksUnhealthy":,"deployments":[],"tasks":[{"id":"tomcat.a143d29d-92f8-11e6-b002-9e1a99d79ec2","slaveId":"81974b67-e403-47a0-bffd-7cbfa03da51b-S2","host":"192.168.56.102","startedAt":"2016-10-15T16:58:48.013Z","stagedAt":"2016-10-15T16:58:43.876Z","ports":[],"version":"2016-10-15T16:58:42.119Z","ipAddresses":[{"ipAddress":"172.17.0.2","protocol":"IPv4"}],"appId":"/tomcat"},{"id":"tomcat.424d101e-931d-11e6-b002-9e1a99d79ec2","slaveId":"81974b67-e403-47a0-bffd-7cbfa03da51b-S1","host":"192.168.56.101","startedAt":"2016-10-15T21:21:06.234Z","stagedAt":"2016-10-15T21:20:55.709Z","ports":[],"version":"2016-10-15T21:20:55.434Z","ipAddresses":[{"ipAddress":"172.17.0.2","protocol":"IPv4"}],"appId":"/tomcat"},{"id":"tomcat.4263a55f-931d-11e6-b002-9e1a99d79ec2","slaveId":"81974b67-e403-47a0-bffd-7cbfa03da51b-S0","host":"192.168.56.103","startedAt":"2016-10-15T21:21:10.236Z","stagedAt":"2016-10-15T21:20:55.858Z","ports":[],"version":"2016-10-15T21:20:55.434Z","ipAddresses":[{"ipAddress":"172.17.0.2","protocol":"IPv4"}],"appId":"/tomcat"}]}}suser@ubuntu-:~$ 
           

8. 总结

通过以上过程大家可以发现直接把docker容器起来就应用可以使用了,通过容器来运行服务简单而高效,省去了很多不必要的麻烦。相信随着越来越多的人使用docker技术,不断的推动docker技术的快速发展,docker技术会更加流行,应用会更加广泛。