最简单的启动Docker实例Mesos Golang Framework

工作了很长时间最近有时间第一次写,希望支持

如果大家了解Mesos,就知道Mesos是经典的两层调度,官网的架构图(http://mesos.apache.org/documentation/latest/mesos-architectur

大致的流程:

Mesos slave会向Mesos master汇报自己的空闲资源(CPU和Mem),

Mesos master作为全局资源调度器,将Mesos slave上的空闲资源通知给Framework, Framework可以分为scheduler和executor,scheduler向Mesos master注册以接入集群, Framework的scheduler回复Mesos master其所要调度的task及相应需要的资源,

Mesos       slave在收到Mesos       master分配的task后,则启动Framework的executor执行task。Mesos在0.20版本之后,对Docker提供了原生支持,Mesosslave可直接调度Docker实例。               Mesos的Framework已经很丰富了,参见http://mesos.apache.org/documentation/latest/mesos-frameworks/ 现在,Mesos也支持用Golang来开发自己的Framework了。

这里写个最简的Framework,使用Mesos                                                                                     slave来启动Docker实例,所以就省去了Framework的executor部分,只需写个scheduler就可以了。(代码已放置于https://github.com/chend h521/mesos-go/)

mesos-go(https://github.com/mesos/mesos-go)里提供了一个example,这里忽略executor,直接来看scheduler,我们主要需要完成sched uler的两个函数:

```

ResourceOffers(driver sched.SchedulerDriver, offers []*mesos.Offer) StatusUpdate(driver sched.SchedulerDriver, status *mesos.TaskStatus)

```

ResourceOffers中,scheduler获取slave上的空闲资源,然后进行task调度。

StatusUpdate中,会通知scheduler所调度的task的状态,并可相应地做出处理。

ResourceOffers函数中,如果要调度Docker实例,需要指定容器类型、image、及网络模式, 可以在mesos-go/mesosproto/mesos.pb.go中看到相应容器类型及网络模式的类型定义:

```

// All container implementation types. type ContainerInfo_Type int32

const (

ContainerInfo_DOCKER ContainerInfo_Type = 1 ContainerInfo_MESOS ContainerInfo_Type = 2

)

```

```

// Network options.

type ContainerInfo_DockerInfo_Network int32 const (

ContainerInfo_DockerInfo_HOST ContainerInfo_DockerInfo_Network = 1 ContainerInfo_DockerInfo_BRIDGE ContainerInfo_DockerInfo_Network = 2 ContainerInfo_DockerInfo_NONE ContainerInfo_DockerInfo_Network = 3

)

```

这样,我们便可指定容器信息,然后启动相应的task:

 

// container info

networkInfo := mesos.ContainerInfo_DockerInfo_BRIDGE dockerInfo := &mesos.ContainerInfo_DockerInfo{ Image: &sched.imageName,

Network: &networkInfo,

}

typeInfo := mesos.ContainerInfo_DOCKER container := &mesos.ContainerInfo{ Type: &typeInfo,

Docker: dockerInfo,

}

shellBool := false

command := &mesos.CommandInfo{ Shell: &shellBool,

}

// schedule task to run task := &mesos.TaskInfo{

Name: proto.String("go-task-" + taskId.GetValue()), TaskId: taskId,

SlaveId: offer.SlaveId, Resources: []*mesos.Resource{

util.NewScalarResource("cpus", CPUS_PER_TASK), util.NewScalarResource("mem", MEM_PER_TASK),

},

Container: container, Command: command,

}

```

StatusUpdate函数中,当task出现异常时(TASK_LOST,TASK_KILLED或TASK_FAILED),即Docker实例异常时,重新进行task调度:

```

// re-schedule task to run when task lost, killed or failed if status.GetState() == mesos.TaskState_TASK_LOST || status.GetState() == mesos.TaskState_TASK_KILLED || status.GetState() == mesos.TaskState_TASK_FAILED { log.Errorln(

"Task", status.TaskId.GetValue(),

"is in unexpected state", status.State.String(), "with message", status.GetMessage(),

)

sched.tasksLaunched--

}

```

编译,并尝试启动3个centos6:latest的Docker实例(需要提前部署Mesos), 并可尝试杀掉某个Docker实例进程,检查scheduler会重新进行调度:

```

cd $GOPATH/src/github.com/mesos/mesos-go/examples

go build -tags=example-sched -o example-scheduler example_scheduler.go

./example-scheduler --master=127.0.0.1:5050 --image=centos6:latest --task-count=3 --logtostderr=true

```

OK,到此就完成了这个最简单的启动Docker实例的MesosGolang Framework, 当然,你可能还想:

1) 让它支持弹性调度

2) 常驻侦听请求

3) 支持更丰富的调度策略

...

如果要用到生产环境,可能还要

1) 选择合适的网络模式(可能就需要为Framework写executor了)

2) 增加健康检查

...

Anyway,相信这些你都可以来实现。

如有需要,Marathon和Aurora是很好的参考 :) 参考:

http://java.dzone.com/articles/building-massively-scalable http://codefutures.com/mesos-docker-tutorial-how-to-build-your-own-framework/

 

posted @ 2018-11-08 23:01  不懂就装懂  阅读(391)  评论(0编辑  收藏  举报