机器准备
机器准备和mesos本身没有关系,主要由于本身机器申请机制有关,这段主要记录下如何通过配置systemd,将agent启动并且正确注册到服务器上。
这里的核心问题是需要开机获取本机IP,然后按照顺序启动docker和agent的镜像。
由于docker0设备的存在,之前agent获取本机IP的方式会出现问题,所有基于docker启动的agent都需要通过环境变量传入本机IP。因此首先需要在镜像启动前,获取本机IP。systemd本身可以通过%H
来指代主机名,但是没有提供本机IP的变量。这边通过开机自动运行脚本,按照k=v的方式写入文件,提供给其他unit file作为environment file使用。
#cat ip.service
[Unit]
Description=get host ip and write to /etc/ip.txt
[Service]
ExecStart=/etc/host-ip.sh
[Install]
WantedBy=multi-user.target
对应的脚本文件内容为:
#cat /etc/host-ip.sh
#!/bin/sh
ip=$(/sbin/ifconfig eth0 | awk '/inet/ {print $2}')
echo IP=$ip > /etc/ip.txt;
这样每次服务启动之后,会写入到ip.txt文件,其内容类似:
IP=1.1.1.1
将unit文件放置在/etc/systemd/system
目录中,别忘了设置成自动启动:
systemctl enable ip.service
搞定机器IP之后,就是agent的启动了。首先需要确保的是docker服务本身已经配置成自动启动。
systemctl enable docker
然后创建agent对应的unit文件:
#cat agent.service
[Unit]
Description=aenv agent
Requires=docker.service ip.service
After=docker.service ip.service
[Service]
EnvironmentFile=/etc/ip.txt
Restart=on-failure
RestartSec=10
ExecStartPre=-/usr/bin/docker kill agent
ExecStartPre=-/usr/bin/docker rm agent
ExecStart=/usr/bin/docker run --net host --env HOST_IP=$IP --name agent agent:1.0
ExecStop=-/usr/bin/docker stop agent
[Install]
WantedBy=multi-user.target
这里需要注意几个地方:
- 依赖关系:在unit部分中,必须指定当前配置文件的依赖关系,这里指定依赖docker和ip两个服务,同时指定当前服务在这两个服务启动之后再启动。
- 环境变量文件:之前的ip服务已经自动将ip地址写入到了ip.txt文件中,unit文件中可以直接将该文件设置为EnvironmentFile。这样可以通过引用文件中的KEY来获取实际的数据。
- 启动命令:这里指定了几个阶段的命令,分别是预启动命令,如果当前已经有agent容器,直接杀死并删除;启动命令,设置agent容器启动命令,特别注意设置I变量;关闭命令,关闭服务时执行的命令,直接关闭agent容器。
最后别忘了设置开机自动启动:
systemctl enable agent.service
mesos+marathon集群搭建
mesos和marathon的基本安装可以参照mesosphere的文档进行。这次尝试安装使用的操作系统镜像是Centos 7,因此只要按照文中关于Centos 7的步骤即可。由于之前已经完成了zk集群的搭建,这里不再需要安装zk。
为了能够组建高可用集群,mesos master和marathon都使用3台机器搭建。因此需要修改部分配置文件。
对于mesos master,首先修改/etc/mesos中的zk文件,里面修改成已经搭建完成的zk集群,多个地址之前用逗号分割,mesos master之间通过zk来相互感知和进行选举。其他需要修改的文件都在/etc/mesos-master目录中,对于集群来说,首要设置的是quorum文件。按照官方文档说明,对于3台master,quorum需要设置为2,以进行单点失效后的选举。按照文档,这两个文件设置完成之后,就可以启动三台mesos master机器上的mesos-master服务了:
systemctl start mesos-master
但是,此时当三台机器都启动完成之后,访问任意一台的5050端口,会出现两个问题:
- 当访问机器不是当前leader时,网页无法正确跳转,直接跳转到了服务器的hostname(目前主机名只能通过机房DNS才能解析);
- 跳转到leader机器之后,过几秒钟就会跳转到其他机器,查看日志发现mesos master在不停的失效,不停的选举;
对于问题1,由于mesos master默认获取的主机名在非机房DNS中都无法解析,最方便的做法就是将hostname直接设置成机器IP。既在/etc/mesos-master目录中创建文件hostname,并将其内容设置为机器IP。
对于问题2,查了很多文档,也尝试了很多方式,最终尝试给mesos-master指定ip为当前机器IP后解决。既在/etc/mesos-master目录中创建文件ip,并将其内容设置为机器IP。这里需要特别注意的是,mesos master会将内容缓存在work_dir中,其值通过/etc/mesos-master目录中的work_dir文件内容指定。通过mesosphere rpm包安装之后默认值为/var/lib/mesos。因此修改了ip文件之后,需要清空其中内容,才会生效。
完成上面两步之后,mesos master集群启动成功。之后可以将mesos-master服务设置为开机自动启动:
systemctl enable mesos-master
然后就是安装marathon集群,还是直接使用rpm包进行安装。其中只有一个需要注意的地方(另一个大坑后面会介绍),就是设置机器的hostname为IP,原因前面已经介绍过。marathon的配置在/etc/marathon/conf目录中,对于主机名,创建hostname文件,并在其中设置当前机器IP即可。marathon启动之后,默认监听8080端口。
最后将marathon服务设置为开机自动启动:
systemctl enable marathon
添加slave和执行docker任务
前面已经介绍了mesos master集群和marathon集群的搭建,要真正能够分配资源并运行任务,还需要向master注册slave。slave和master使用了相同的机器镜像,确保rpm包已经正确安装,同时zk都已经完成配置(slave也使用/etc/mesos/zk的配置)。对于slave的所有配置,都在/etc/mesos-slave目录中,配置方式和mesos相同,防止和参数名称相同的文件即可。最简单的配置和master类似,设置hostname即可。既创建/etc/mesos-slave/hostname文件,并写入当前机器IP。其他服务器可用资源可以让slave自动检测并上报。
设置完成之后,就可以启动slave了。可以在master上看见注册上来的slave及其资源信息。同时记得将slave设置为开机自动启动:
systemctl enable mesos-slave
启动之后,尝试在marathon上提交一个docker任务:启动redis:alpine
镜像。但是发现任务没有能够正确的在slave上启动。参照marathon文档介绍,要让slave支持docker,需要设置containerizers参数。执行:
echo 'docker,mesos' > /etc/mesos-slave/containerizers
echo '5mins' > /etc/mesos-slave/executor_registration_timeout
后面那个参数主要是由于docker任务启动的时候,需要去远程拉取镜像,一般刚开始容易超时。(虽然这样设置了之后还是会超时,不过由于marathon的重试机制,超时的任务会稍后重新启动,并且docker镜像本地也会缓存,目前感觉影响不大。)
完成这些配置之后,再重启mesos-slave服务,即可在marathon上提交刚才无法成功的redis:alpine镜像了。
另外,marathon还提供了任务的健康检测。按照其文档描述,在mesos master v0.23.1和v0.24.1以后,针对docker任务也已经支持通过命令来进行健康检测(实际查看slave日志后发现,执行的命令最终被转化成了docker exec
命令,进入容器之后运行指定的命令)。对于redis任务,我们可以配置redis-cli info
命令来进行健康检测,如果命令执行超时则判定为失败。不过marathon的健康检测还不支持对命令返回值的断言。