发布于 2015-12-05 11:08:31 | 475 次阅读 | 评论: 0 | 来源: 网络整理

  • EC = external containerizer.外部容器化管理器,Mesos slave节点的一个部分,提供给外部插件执行容器化操控的API。
  • ECP = external containerizer program. 外部容器化工具,指与容器化系统(例如: Docker)接口,实际实现容器化的外部插件。

外部容器化管理器 会在 命令行中 执行 外部容器化工具,以命令形式传递参数给外部容器化工具,额外的数据则通过 stdin 和 stdout 交换。

若所有命令都可执行,外部容器化工具将不会退出。如果退出,则表示可能出错了。下文将会列出把所有 外部容器化工具需要实现的功能的概况,及其机制示意图。

外部容器化工具 使用stderr来获得状态和调试信息,这些信息被记录在文件里,详见 Enviroment: Sandbox.

调用和通信示意图

外部容器化工具 通过命令行,实现下面所述的功能。 很多 外部容器化工具 会通过 stdin 传输一个 protobuf 信息。 有些 外部容器化工具 还会通过 stdout 传回一个结果 protobuf 信息。 所有的 protobuf 信息都会把其原有长度放在前缀里——这叫 "Record-IO"-格式。 详见Record-IO De/Serializing示例.

命令 传入INPUT-PROTO 结果RESULT-PROTO
launch containerizer::Launch
update containerizer::Update
usage containerizer::Usage mesos::ResourceStatistics
wait containerizer::Wait containerizer::Termination
destroy containerizer::Destroy
containers containerizer::Containers
recover

命令的执行顺序一般不用特别在意,但有一个例外:当载入一个任务时,外部容器管理器将在特定容器上,先接收到launch,并返回后,容器才可以运行其他的命令。

外部容器化管理器和外部容器工具 加载任务 概况

  • 外部容器化管理器在 外部容器化工具中调入执行launch操作。
    • 外部容器化工具将通过 stdin 收到containerizer::Launch protobuf 信息
    • 外部容器化管理器因此可确认执行器已经开始工作。 Note launch操作不会等待执行结果,而是直接返回 - 外部容器化工具里通过fork-exec实现。
  • 外部容器化管理器在 外部容器化工具里执行等待wait操作。
    • 外部容器化工具将通过 stdin 收到containerizer::Wait protobuf 信息
    • 外部容器化工具将等待,直到载入的命令执行有结果。——可在外部容器化工具通过waitpid实现。
    • 当命令执行有结果了,外部容器化工具将通过 stdout发出一个 containerizer::Termination protobuf信息,然后返回外部容器化管理器

容器生命周期示意图

容器加载

仔细观察 从已经载入的容器启动,直到其结束整个状态。

容器加载示意图

运行容器

容器载入后,slave节点将不再认为其仍然处于命令行环境中,外部容器化工具里的容器,其整个生命周期里都将被下面的命令操控。注:命令顺序不重要。

容器运行示意图

资源限额

当容器是活动状态时,可通过 外部容器化工具 的分隔机制 设置资源限额(比如 内存限额)。

资源限额示意图

Slave节点还原 概况

  • Slave节点可以通过运行状态锚点进行还原。
  • 外部容器化管理器通过 外部容器化工具 调用命令recover,执行还原操作。 - 操作的结果将不返回任何 protobuf 的信息。
  • 必要时,外部容器化工具会利用 自身failover 机制恢复其内部状态。
  • recover命令返回后,外部容器化管理器将调用外部容器化工具里的containers命令。
  • 外部容器化工具会返回所有当前活动状态的容器列表 Note 所有的容器信息可以通过外部容器化工具获得,但部分信息slave节点可能并不知道(比如slave节点若在加载后的等待时间前或之中故障)。 - 这些不为slave节点管理的容器可视为孤机容器。
  • 外部容器化管理器会对比 slave节点已知的容器列表和完整的Containers命令返回的容器列表,对于标记为孤机的容器,slave节点将在调用等待 wait 命令之后,执行destroy销毁之。
  • slave节点将在 外部容器化工具里通过 外部容器化管理器 对所有已经恢复的容器调用等待 wait命令。在生命周期所有其他命令执行完毕后, wait 才退出。

Slave节点还原流程示意图

还原

当容器处于活动状态时,slave节点故障。

还原示意图

孤机销毁

外部容器化管理器标记的孤机,处于虽然活动但无法被slave节点恢复的状态,最终将被销毁。

孤机销毁示意图

加载launch

启动容器化执行器

执行器载入任务 的所有必须的信息都通过该命令获取。 此命令不会等待执行器或命令返回信息。 wait 才会等待程序执行完成返回信息后才退出。

launch < containerizer::Launch

此操作会通过stdin 收到 containerizer::Launch protobuf 如下:

/**
 * Encodes the launch command sent to the external containerizer
 * program.
 */
message Launch {
  required ContainerID container_id = 1;
  optional TaskInfo task_info = 2;
  optional ExecutorInfo executor_info = 3;
  optional string directory = 4;
  optional string user = 5;
  optional SlaveID slave_id = 6;
  optional string slave_pid = 7;
  optional bool checkpoint = 8;
}

此操作不会通过stdout返回任何数据。

等待wait

从终止的执行器处获得信息

用于中止执行器或命令,此命令会阻塞直至执行器或命令被中止。

wait < containerizer::Wait > containerizer::Termination

此操作会通过stdin 收到 containerizer::Wait protobuf 如下:

/**
 * Encodes the wait command sent to the external containerizer
 * program.
 */
message Wait {
  required ContainerID container_id = 1;
}

此操作会通过stdout 返回 containerizer::Termination protobuf 如下:

/**
 * Information about a container termination, returned by the
 * containerizer to the slave.
 */
message Termination {
  // A container may be killed if it exceeds its resources; this will
  // be indicated by killed=true and described by the message string.
  required bool killed = 1;
  required string message = 2;

  // Exit status of the process.
  optional int32 status = 3;
}

只有当 容器化工具或者 底层隔离器通过终止任务进程来强制使用限制时(例如:任务使用内存超过内存使用限额),终止参数 killed才会被设置。

更新update

更新容器的资源限额

用于给指定的容器发送新的资源配额。新的资源配额会改变容器内任务的处理速度。

update < containerizer::Update

此操作会通过stdin 收到 containerizer::Update protobuf 如下:

/**
 * Encodes the update command sent to the external containerizer
 * program.
 */
message Update {
  required ContainerID container_id = 1;
  repeated Resource resources = 2;
}

此操作不会通过stdout返回任何数据。

使用情况usage

采集容器任务的资源使用数据

用于获知指定容器当前资源使用情况。

usage < containerizer::Usage > mesos::ResourceStatistics

此操作会通过stdin 收到 containerizer::Usage protobuf 如下:

/**
 * Encodes the usage command sent to the external containerizer
 * program.
 */
message Usage {
  required ContainerID container_id = 1;
}

此操作会通过stdout 收到 containerizer::ResourceStatistics protobuf 如下:

/*
 * A snapshot of resource usage statistics.
 */
message ResourceStatistics {
  required double timestamp = 1; // Snapshot time, in seconds since the Epoch.

  // CPU Usage Information:
  // Total CPU time spent in user mode, and kernel mode.
  optional double cpus_user_time_secs = 2;
  optional double cpus_system_time_secs = 3;

  // Number of CPUs allocated.
  optional double cpus_limit = 4;

  // cpu.stat on process throttling (for contention issues).
  optional uint32 cpus_nr_periods = 7;
  optional uint32 cpus_nr_throttled = 8;
  optional double cpus_throttled_time_secs = 9;

  // Memory Usage Information:
  optional uint64 mem_rss_bytes = 5; // Resident Set Size.

  // Amount of memory resources allocated.
  optional uint64 mem_limit_bytes = 6;

  // Broken out memory usage information (files, anonymous, and mmaped files)
  optional uint64 mem_file_bytes = 10;
  optional uint64 mem_anon_bytes = 11;
  optional uint64 mem_mapped_file_bytes = 12;
}

销毁destroy

终止容器化执行器

比较少用,有点像被控关机,不过是在slave节点出现故障切换的时候。详见Slave Recovery。

destroy < containerizer::Destroy

此操作会通过stdin 收到 containerizer::Destroy protobuf 如下:

/**
 * Encodes the destroy command sent to the external containerizer
 * program.
 */
message Destroy {
  required ContainerID container_id = 1;
}

此操作不会通过stdout返回任何数据。

容器containers

获取所有活动的容器识别号

返回所有活动状态的容器识别号。

containers > containerizer::Containers

此操作不会通过stdin接收任何额外数据。

此操作会通过stdout 传回 containerizer::Containers protobuf 如下:

/**
 * Information on all active containers returned by the containerizer
 * to the slave.
 */
message Containers {
  repeated ContainerID containers = 1;
}

还原recover

外部容器化工具 状态恢复

可以让外部容器化工具对其本身进行状态恢复。 若 外部容器化工具通过 文件系统来使用状态检查锚点,那就可以方便的将该状态信息进行反序列化。详见slave节点还原概况

recover

此操作不会通过stdin收到任何数据。 此操作不会通过stdout返回任何数据。

Protobuf 消息定义

上面所提及的protobuf和消息可通过下面方式查看详细信息:

  • containerizer::XXX 是在 include/mesos/containerizer/containerizer.proto 中定义的。

  • mesos::XXX 是在 include/mesos/mesos.proto中定义的。

沙箱

沙箱环境,由两部分构成: 执行器会通过 cd 进入工作目录,同时 stderr 重定向进执行器的"stderr"日志文件。

Note 不是所有的 容器化调用 都有完整的沙箱环境。

附加的环境变量

在外部容器化工具里,有一些额外的环境变量可供设置:

  • MESOS_LIBEXEC_DIRECTORY = mesos-executor, mesos-usage, ...等的路径。 This information is always present.

  • MESOS_WORK_DIRECTORY = slave节点的工作目录。这用于区分不同的slave实例。 This information is always present.

Note 这两项设置对于将一批容器绑定于一个slave节点中十分有用,且可以在需要的时候正确的还原。

  • MESOS_DEFAULT_CONTAINER_IMAGE = 默认由slave节点的default_container_image提供的镜像。这变量只有当调用加载命令launch时可用。

增强细化的日志

在mesos启动slave节点时,在其命令前面添加 GLOG 级别,以便显示更多 外部容器管理工具的状态信息。级别可设置为大于或等于2。

GLOG_v=2 ./bin/mesos-slave --master=[...]

外部容器工具 stderr 日志

外部容器工具将从执行器的stderr日志文件获得其本身 stderr 日志,可通过增强细化日志 展开具体位置。

日志输出示例:

I0603 02:12:34.165662 174215168 external_containerizer.cpp:1083] Invoking external containerizer for method 'launch'
I0603 02:12:34.165675 174215168 external_containerizer.cpp:1100] calling: [/Users/till/Development/mesos-till/build/src/test-containerizer launch]
I0603 02:12:34.165678 175824896 slave.cpp:497] Successfully attached file '/tmp/ExternalContainerizerTest_Launch_lP22ci/slaves/20140603-021232-16777343-51377-7591-0/frameworks/20140603-021232-16777343-51377-7591-0000/executors/1/runs/558e0a69-70da-4d71-b4c4-c2820b1d6345'
I0603 02:12:34.165686 174215168 external_containerizer.cpp:1101] directory: /tmp/ExternalContainerizerTest_Launch_lP22ci/slaves/20140603-021232-16777343-51377-7591-0/frameworks/20140603-021232-16777343-51377-7591-0000/executors/1/runs/558e0a69-70da-4d71-b4c4-c2820b1d6345

容器工具stderr输出的目录可在 stderr 文件里找到(文件目录参见上方最后一行日志)。

cat /tmp/ExternalContainerizerTest_Launch_lP22ci/slaves/20140603-021232-16777343-51377-7591-0/frameworks/20140603-021232-16777343-51377-7591-0000/executors/1/runs/558e0a69-70da-4d71-b4c4-c2820b1d6345/stderr

Record-IO Proto 示例:加载

record-io格式化的protobuf形式如下:

name: offset

  • length: 00 - 03 = record length in byte

  • payload: 04 - (length + 4) = protobuf payload

Example length: 00000240h = 576 byte total protobuf size

十六进制dump示例:

    00000000:  4002 0000 0a26 0a24 3433 3532 3533 6162 2d64 3234 362d 3437  :@....&.$435253ab-d246-47
    00000018:  6265 2d61 3335 302d 3335 3432 3034 3635 6438 3638 1a81 020a  :be-a350-35420465d868....
    00000030:  030a 0131 2a16 0a04 6370 7573 1000 1a09 0900 0000 0000 0000  :...1*...cpus............
    00000048:  4032 012a 2a15 0a03 6d65 6d10 001a 0909 0000 0000 0000 9040  :@2.**...mem............@
    00000060:  3201 2a2a 160a 0464 6973 6b10 001a 0909 0000 0000 0000 9040  :2.**...disk............@
    00000078:  3201 2a2a 180a 0570 6f72 7473 1001 220a 0a08 0898 f201 1080  :2.**...ports..".........
    00000090:  fa01 3201 2a3a 2a1a 2865 6368 6f20 274e 6f20 7375 6368 2066  :..2.*:*.(echo 'No such f
    000000a8:  696c 6520 6f72 2064 6972 6563 746f 7279 273b 2065 7869 7420  :ile or directory'; exit
    000000c0:  3142 2b0a 2932 3031 3430 3532 362d 3031 3530 3036 2d31 3637  :1B+.)20140526-015006-167
    000000d8:  3737 3334 332d 3535 3430 332d 3632 3536 372d 3030 3030 4a3d  :77343-55403-62567-0000J=
    000000f0:  436f 6d6d 616e 6420 4578 6563 7574 6f72 2028 5461 736b 3a20  :Command Executor (Task:
    00000108:  3129 2028 436f 6d6d 616e 643a 2073 6820 2d63 2027 7768 696c  :1) (Command: sh -c 'whil
    00000120:  6520 7472 7565 203b 2e2e 2e27 2952 0131 22c5 012f 746d 702f  :e true ;...')R.1"../tmp/
    00000138:  4578 7465 726e 616c 436f 6e74 6169 6e65 7269 7a65 7254 6573  :ExternalContainerizerTes
    00000150:  745f 4c61 756e 6368 5f6c 5855 6839 662f 736c 6176 6573 2f32  :t_Launch_lXUh9f/slaves/2
    00000168:  3031 3430 3532 362d 3031 3530 3036 2d31 3637 3737 3334 332d  :0140526-015006-16777343-
    00000180:  3535 3430 332d 3632 3536 372d 302f 6672 616d 6577 6f72 6b73  :55403-62567-0/frameworks
    00000198:  2f32 3031 3430 3532 362d 3031 3530 3036 2d31 3637 3737 3334  :/20140526-015006-1677734
    000001b0:  332d 3535 3430 332d 3632 3536 372d 3030 3030 2f65 7865 6375  :3-55403-62567-0000/execu
    000001c8:  746f 7273 2f31 2f72 756e 732f 3433 3532 3533 6162 2d64 3234  :tors/1/runs/435253ab-d24
    000001e0:  362d 3437 6265 2d61 3335 302d 3335 3432 3034 3635 6438 3638  :6-47be-a350-35420465d868
    000001f8:  2a04 7469 6c6c 3228 0a26 3230 3134 3035 3236 2d30 3135 3030  :*.till2(.&20140526-01500
    00000210:  362d 3136 3737 3733 3433 2d35 3534 3033 2d36 3235 3637 2d30  :6-16777343-55403-62567-0
    00000228:  3a18 736c 6176 6528 3129 4031 3237 2e30 2e30 2e31 3a35 3534  ::.slave(1)@127.0.0.1:554
    00000240:  3033 4000

Record-IO De/Serializing 示例

用Python来发送和接收 record-io 格式化信息

  • 可在 src/examples/python/test_containerizer.py 见下面示例源码*
    # Read a data chunk prefixed by its total size from stdin.
    def receive():
        # Read size (uint32 => 4 bytes).
        size = struct.unpack('I', sys.stdin.read(4))
        if size[0] <= 0:
            print >> sys.stderr, "Expected protobuf size over stdin. " \
                             "Received 0 bytes."
            return ""

        # Read payload.
        data = sys.stdin.read(size[0])
        if len(data) != size[0]:
            print >> sys.stderr, "Expected %d bytes protobuf over stdin. " \
                             "Received %d bytes." % (size[0], len(data))
            return ""

        return data

    # Write a protobuf message prefixed by its total size (aka recordio)
    # to stdout.
    def send(data):
        # Write size (uint32 => 4 bytes).
        sys.stdout.write(struct.pack('I', len(data)))

        # Write payload.
        sys.stdout.write(data)
最新网友评论  共有(0)条评论 发布评论 返回顶部

Copyright © 2007-2017 PHPERZ.COM All Rights Reserved   冀ICP备14009818号  版权声明  广告服务