刚接触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=1 \ #每台主机对应一个id,三台主机分别对应1,2,3
-e SERVERS=192.168.56.103,192.168.56.101,192.168.56.102 \ #三台主机的ip地址
--name=zookeeper \
--net=host \
--restart=always \
mesoscloud/zookeeper
3.2 运行mesos-master
docker run -d \
-e MESOS_HOSTNAME=192.168.56.103 \ #第一台主机ip地址
-e MESOS_IP=192.168.56.103 \ #第一台主机ip地址
-e MESOS_QUORUM=2 \
-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=192.168.56.103 \ #第一台主机ip地址
-e MESOS_IP=192.168.56.103 \ #第一台主机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=192.168.56.103 \ #第一台主机ip地址
-e MARATHON_HTTPS_ADDRESS=192.168.56.103 \ #第一台主机ip地址
-e MARATHON_HTTP_ADDRESS=192.168.56.103 \ #第一台主机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": 1,
"mem": 512,
"disk": 512,
"instances": 1,
"container": {
"docker": {
"image": "davidcaste/alpine-tomcat",
"network": "BRIDGE",
"portMappings": [
{
"containerPort": 8080,
"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" 192.168.56.103:8080/v2/apps -d'
{
"id": "tomcat",
"cmd": "/opt/tomcat/bin/catalina.sh run",
"cpus": 1,
"mem": 512,
"disk": 512,
"instances": 1,
"container": {
"docker": {
"image": "davidcaste/alpine-tomcat",
"network": "BRIDGE",
"portMappings": [
{
"containerPort": 8080,
"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)
5.2 击进入应用页面,只有一个实例
5.3 点击Scale Application扩展三个实例
5.4 打开mesos主页面(http://192.168.56.103:5050),可以看到有三个tomcat实例
5.5 在Mesos中打开Framework页面,我们可以看到marathon框架的正在运行。
5.6 接下来我们看一下mesos-slave页面,看到运行正常的三个mesos-slave。
6. 调用服务
我们通过marathon把tomcat运行起来了,但是tomcat里没有war包,所以我们将准备好的一个war包放进三台主机的tomcat里,这里是为了测试方便,我们直接使用docker cp命令将war包复制到docker容器当中。在实际应用中我们可以通过其他方式来加载war包,比如,在CMD命令里通过wget方式将war包下载到容器里,或者通过卷Volume的方式共享,将war包放到tomcat的webaps目录下。
suser@ubuntu-1:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dd014c78d8ec davidcaste/alpine-tomcat "/bin/sh -c '/opt/tom" 17 minutes ago Up 17 minutes 0.0.0.0:31204->8080/tcp mesos-81974b67-e403-47a0-bffd-7cbfa03da51b-S0.e9647bd1-2771-487b-a01e-6a0ae68c62f9
601dbe2256d5 mesoscloud/marathon "/usr/local/bin/dumb-" 5 hours ago Up 5 hours marathon
1dfaabf2cd3e mesoscloud/mesos-slave "/usr/local/bin/dumb-" 5 hours ago Up 5 hours mesos-slave
e94c3202f529 mesoscloud/mesos-master "/usr/local/bin/dumb-" 5 hours ago Up 5 hours mesos-master
a3389a386a11 mesoscloud/zookeeper "/usr/local/bin/dumb-" 5 hours ago Up 5 hours zookeeper
suser@ubuntu-1:~$ docker cp /mnt/share/backendresource.war dd014c78d8ec:/opt/tomcat/webapps #dd014c78d8ec为Container ID
suser@ubuntu-1:~$
接下来我们访问服务查看返回结果
suser@ubuntu-1:~$ curl 192.168.56.102:31515/backendresource/11/1/1
{"ACT_TAG":"1","X_RESULTCODE":"0"}
suser@ubuntu-1:~$ curl 192.168.56.101:31299/backendresource/11/1/1
{"ACT_TAG":"1","X_RESULTCODE":"0"}
suser@ubuntu-1:~$ curl 192.168.56.103:31204/backendresource/11/1/1
{"ACT_TAG":"1","X_RESULTCODE":"0"}
查看docker容器日志
suser@ubuntu-1:~$ 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.
2016-10-15 21:46:27 [INFO ](BackendResources ) [TxId : , SpanId : ] 榛戝悕鍗昩ackendresource缁撴灉:{"ACT_TAG":"1","X_RESULTCODE":"0"},鏈璋冪敤鑰楁椂:1117ms
2016-10-15 21:47:13 [INFO ](BackendResources ) [TxId : , SpanId : ] 榛戝悕鍗昩ackendresource缁撴灉:{"ACT_TAG":"0","X_RESULTCODE":"0"},鏈璋冪敤鑰楁椂:2ms
suser@ubuntu-1:~$
在容器也看到了调用日志,看到中文是乱码,这个可能是容器字符编码问题。
7. 通过marathon rest接口获取数据
#通过marathon接口获取所有应用信息
suser@ubuntu-1:~$ curl 192.168.56.103:8080/v2/apps
{"apps":[{"id":"/tomcat","cmd":"/opt/tomcat/bin/catalina.sh run","args":null,"user":null,"env":{},"instances":3,"cpus":0.5,"mem":512,"disk":512,"executor":"","constraints":[],"uris":[],"fetch":[],"storeUrls":[],"ports":[10000],"portDefinitions":[{"port":10000,"protocol":"tcp","labels":{}}],"requirePorts":false,"backoffSeconds":1,"backoffFactor":1.15,"maxLaunchDelaySeconds":3600,"container":{"type":"DOCKER","volumes":[],"docker":{"image":"davidcaste/alpine-tomcat","network":"BRIDGE","portMappings":[{"containerPort":8080,"hostPort":0,"servicePort":10000,"protocol":"tcp","labels":{}}],"privileged":false,"parameters":[],"forcePullImage":false}},"healthChecks":[],"readinessChecks":[],"dependencies":[],"upgradeStrategy":{"minimumHealthCapacity":1,"maximumOverCapacity":1},"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":0,"tasksRunning":3,"tasksHealthy":0,"tasksUnhealthy":0,"deployments":[]}]}suser@ubuntu-1:~$
##通过marathon接口获取tomcat应用信息
suser@ubuntu-1:~$ curl 192.168.56.103:8080/v2/apps/tomcat
{"app":{"id":"/tomcat","cmd":"/opt/tomcat/bin/catalina.sh run","args":null,"user":null,"env":{},"instances":3,"cpus":0.5,"mem":512,"disk":512,"executor":"","constraints":[],"uris":[],"fetch":[],"storeUrls":[],"ports":[10000],"portDefinitions":[{"port":10000,"protocol":"tcp","labels":{}}],"requirePorts":false,"backoffSeconds":1,"backoffFactor":1.15,"maxLaunchDelaySeconds":3600,"container":{"type":"DOCKER","volumes":[],"docker":{"image":"davidcaste/alpine-tomcat","network":"BRIDGE","portMappings":[{"containerPort":8080,"hostPort":0,"servicePort":10000,"protocol":"tcp","labels":{}}],"privileged":false,"parameters":[],"forcePullImage":false}},"healthChecks":[],"readinessChecks":[],"dependencies":[],"upgradeStrategy":{"minimumHealthCapacity":1,"maximumOverCapacity":1},"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":0,"tasksRunning":3,"tasksHealthy":0,"tasksUnhealthy":0,"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":[31515],"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":[31299],"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":[31204],"version":"2016-10-15T21:20:55.434Z","ipAddresses":[{"ipAddress":"172.17.0.2","protocol":"IPv4"}],"appId":"/tomcat"}]}}suser@ubuntu-1:~$
8. 总结
通过以上过程大家可以发现直接把docker容器起来就应用可以使用了,通过容器来运行服务简单而高效,省去了很多不必要的麻烦。相信随着越来越多的人使用docker技术,不断的推动docker技术的快速发展,docker技术会更加流行,应用会更加广泛。