mesos-execute

src/cli/execute.cpp

这也是如何写自己的framework的一个很好的例子。

启动

  • 676-736:处理命令行参数
  • 740-792:处理HDFS。。。。。。。。
  • 794-807:如果命令行指定了APPC或是DOCKER的映像。。。。。
  • 810-832:设置framework的初始Capability为TASK_KILLING_STATE,再根据命令行参数--framework_capabilities指定的值设置Capability
  • 835-849:设置volumes
  • 851-858:初始化frameworkInfo,设置user,name,role等
  • 860-871:如果命令行提供了认证信息,也进行相关设置
  • 873-889:创建scheduler
  • 891:启动
  • 892:等待结束

CommandScheduler类

CommandScheduler类定义

私有变量定义在654-670行:

  • master
  • name
  • Owned<Mesos> mesos(Mesos对象,这里不是指针。Owned见libprocess

Mesos对象对应的是mesos::v1::scheduler::Mesos

CommandScheduler:initialize

新建一个Mesos对象,传递了三个函数作为回调函数(298-300)。再调用mesos.reset初始化,这里的Mesos对象对应的是mesos::v1::scheduler::Mesos,见辅助对象,mesos.reset将对象的引用计数重置。

此处Mesos对象对应的是mesos::v1::scheduler::Mesos,见81行。

doReliableRegistration

  • 318-320:若是SUBSCRIBED/DISCONNECTED状态,则返回
  • 322-323:构造一个Call,类型为Call::SUBSCRIBE
  • 325-327:若有framework ID,则拷贝到Call
  • 329-330:拷贝frameworkInfo
  • 332:调用mesos->send(call)
  • 334:延迟一秒后,再调用本函数?????

received

当收到事件消息时被调用

  • 460:事件队列不为空就一直处理
    • 461-462:从事件队列取出一个事件event
    • 464:根据事件类型处理:
      • 465-473:SUBSCRIBED,记录下framework ID???
      • 475-478:OFFERS,调用offers函数
      • 480-483:UPDATE,调用update函数
      • 485-490:ERROR,调用EXIT。。。。。。。
      • 492-504:HEARTBEAT/INVERSE_OFFERS/FAILURE/RESCIND/RESCIND_INVERSE_OFFER/MESSAGE,这些只是master给来的应答信息,无须处理
      • 501-504:UNKNOWN,不认识的信息,报警告

offers

当收到OFFERS消息时被调用

参数:

  • const vector<Offer>& offers:offers向量

  • 357:确保当前状态为SUBSCRIBED

  • 359-365:解析resources(resources是CommandScheduler类的私有变量,定义在660行,若命令行未指定(见881行),则默认是"cpus:1;mem:128",见121-124行)
  • 367:对offers中每一个offer处理:
    • 368:得到offer中的资源
    • 370:若还未启动且offer中已经含有任务运行需要的资源:
      • 372-374:设置任务名称、agent ID
      • 377-378:根据framework指定的role从offer中寻找对应的资源
      • 380:确保资源已经找到
      • 382:资源信息拷贝到任务中
      • 384-394:设置commandInfo,shell
      • 396-406:设置环境变量
      • 408-410:设置URI?????
      • 412-421:拷贝容器相关信息
      • 423-424:初始化一个Call对象,类型为ACCEPT
      • 426:确保framework ID已经设置
      • 429-430:设置call.accept的offer ID为刚收到的offer ID
      • 432-435:设置call.accept的操作为LAUNCH,并拷贝任务相关信息
      • 437:发送消息给master
      • 442:设置launched=true
    • 444-453:否则,资源不满足要求,设置CALL类型为DECLINE,并发送消息给master

资源Resources定义在include/mesos/v1/resources.hpp,实现在src/common/resources.cpp

update

当任务状态更新时被调用

  • 511-512:当前状态必须为SUBSCRIBED,任务ID与收到的状态消息中的ID必须一致
  • 514-527:输出状态消息的一些信息到标准输出
  • 529-541:若状态消息中含有UUID,则回复一个ACKNOWLEDGE的消息,为什么???
  • 545-551:若定义了killAfter,则延迟killAfter定义的时间后调用killTask
  • 553-555:若检测到任务状态已经是终止(收到master发来的消息TASK_FINISHED),则调用terminate终止自己。因为本命令只启动一个task。

killAfter是在命令行传入的,表示多久之后会自动将任务杀掉,格式类似:10secs,2mins等

Mesos类

定义在include/mesos/v1/scheduler.hpp,这个对象是mesos对scheduler的接口。

Mesos(const std::string& master, ContentType contentType, const std::function& connected, const std::function& disconnected, const std::function&)>& received, const Option& credential);

这里定义了三个回调函数:

  • 连接
  • 断连
  • 收到master发来的事件

Mesos类还有几个函数:

  • send:发送一个调用给master。scheduler只应在收到connected回调时调用本函数
  • reconnect:强迫与master重连

及一个私有变量:MesosProcess* process

构造函数Mesos::Mesos

src/scheduler/scheduler.cpp

  • 749-758:读取标志
  • 760-768:设置私有变量process为新的MesosProcess对象
  • 770:启动process

Mesos的其他函数

send/reconnect:在process上调用MesosProcess::send/reconnect

MesosProcess类

这个process是负责发送HTTP消息到master或者是从master接收HTTP消息

构造函数

  • 154:初始化libprocess
  • 156-163:如果是在LOOPBACK接口上,输出警告
  • 166-170:初始化LOG
  • 176-179:若master是"local",则调用local::launch。若命令行未指定master则master是"local"
  • 181-190:若_detector为空,则创建一个detector,并调用reset,作用是??????
  • 191-193:否则得到detector

initialize

299-300:调用detector(对应zookeeper.cpp或standalone.cpp)检测master,调用MesosProcess::detected

    detection = detector->detect()
      .onAny(defer(self(), &MesosProcess::detected, lambda::_1));

void detected(const Future<Option<mesos::MasterInfo>>& future)

  • 413-416:判断是否已经失败(什么时候失败??????)这个探测也是异步动作
  • 418-425:若状态是CONNECTED/SUBSCRIBING/SUBSCRIBED,表示之前已经连接,调用断连。
  • 428:断连
  • 430-439:若future(异步MasterInfo)已经被discard或不存在,将master设为None。这种情况的例子可见standalone.cpp,当StandaloneMasterDetectorProcess调用discard时。
  • 440-452:使用HTTPS吗?
  • 454-459:得到master对应的URL,URL是/master/api/v1/scheduler
  • 463:使用一个随机的UUID作为connectionId
  • 467-468:计算一个0-flags.connectionDelayMax(默认是500ms)之间的随机数作为延迟
  • 473:延迟一段时间后调用MesosProcess::connect
  • 477-478:每隔一段时间再调用自己(detected),确保当master意外退出,或产生新的master时能够及时连接上。

void connect(const UUID& _connectionId)

  • 307-310:参数_connectionId必须和初始化时记录的connectionId一致,否则返回
  • 312:状态必须为DISCONNECTED
  • 313:master必须已经设置
  • 315:状态设置为CONNECTING
  • 317-319:设置一个连接函数connector,它调用process::http::connect,连接master
  • 323-324:????调用两次connector,得到两个connection,对每个connection,调用connected,这些都是异步的。。。。
       collect(connector(), connector())
        .onAny(defer(self(), &Self::connected, connectionId.get(), lambda::_1));
    

void connected

参数:

  • const UUID& _connectionId
  • const Future>& _connections)

这里定义了两个连接,一个是用于subscribe,一个是用于non-subscribe,定义见116行。

  • 333-336:检查连接ID
  • 338:检查状态
  • 339:连接ID必须已经设置
  • 341-347:两个连接变量若未准备好,则断连,并给出断连原因
  • 351:状态改为CONNECTED

void send(const Call& call)

  • 210-229:判断各种错误
  • 237-251:构建POST请求,包括请求内容(支持PROTOBUF和JSON两种格式),认证信息
  • 253:确保connections已经初始化
  • 256-260:若Call的类型是SUBSCRIBE,则从connections->subscribe发送请求
  • 261-268:否则从connections->nonSubscribe发送请求,这种情况要带上Mesos-Stream-Id,不知做什么用????????
  • 270-275:当应答就绪,调用_send

_send

参数:

  • _connectionId
  • call
  • response

流程:

  • 514-516:判断连接ID未发生变化
  • 518-528:检查状态,检查response是否还可用
  • 530-556:如果返回的response是“200 OK”,则:
    • 536:将状态改为SUBSCRIBED
    • 538:得到reader
    • 540-544:构建解码函数
    • 546-555:读response内容并返回
  • 。。。。。。。。。。

mesos-containerizer

src/slave/containerizer/mesos/main.cpp

只有这几行代码:

  return Subcommand::dispatch(
      None(),
      argc,
      argv,
      new MesosContainerizerLaunch(),
      new MesosContainerizerMount(),
      new NetworkCniIsolatorSetup());

Subcommand的定义在: 3rdparty/stout/include/stout/subcommand.hpp

三种命令的定义,都是继承Subcommand类,定义都在目录下:

类名称 定义文件
MesosContainerizerLaunch src/slave/containerizer/mesos/launch.hpp
MesosContainerizerMount src/slave/containerizer/mesos/mount.hpp
NetworkCniIsolatorSetup src/slave/containerizer/mesos/isolators/network/cni/cni.hpp

MesosContainerizerLaunch:

MesosContainerizerLaunch::NAME = "launch"
MesosContainerizerMount::NAME = "mount";
MesosContainerizerMount::MAKE_RSLAVE = "make-rslave";
NetworkCniIsolatorSetup::NAME = "network-cni-setup"

MesosContainerizerLaunch的构造函数只是调用Subcommand(NAME)

在Subcommand构造命令后,调用subcommand->execute,该虚函数由各个具体的类实现。

因此,这里大约是会依次调用MesosContainerizerLaunch::execute、MesosContainerizerMount::execute、NetworkCniIsolatorSetup::execute

MesosContainerizerLaunch::execute

  • 111-114:要有--command标志的定义
  • 116-124:读写管道要同时可用,或都不可用
  • 127-146:解析命令
  • 148:若定义了管道
    • 149-164:处理管道相关操作。。。。。。
    • 167-170:一直在pipe[0]上等待,等待该管道有另外的进程写入内容,以启动本进程
    • 172-178:内容要符合特定的长度,否则报错退出
    • 180-184:关闭管道pipe[0]
  • 187-195:若标志中有unshare_namespace_mnt,调用相关操作。。。。
  • 199-202:若定义了pre_exec_commands,对pre_exec_commands中定义的每一条执行以下操作:
    • 203-206:若是不合法的JSON格式,报错返回
    • 208-218:解析JSON
    • 222-235:调用subprocess生成新的进程,并执行程序
    • 243:等新进程执行结束
    • 245-254:若新进程的退出状态有错,则返回失败
  • 273-303:若定义了用户,获取用户ID
  • 310:得到根文件系统路径
  • 314-343:若定义了根文件系统路径,调用chroot
  • 349-370:设置各种用户ID。。。。。。
  • 373-381:改变进程的工作目录
  • 386-397:执行exec,不再返回

results matching ""

    No results matching ""