带安全功能的自定义 Marathon

使用高级非本地 Marathon 实例

本专题描述了如何部署具有独立角色、保留、配额和安全功能的非本地 Marathon 实例 (Marathon on Marathon) 。高级非本地 Marathon 程序只能在您需要 或细粒度 ACL 时使用。否则,请使用 基本程序.

对于本程序,我们假设您已从支持团队成员获得了 Marathon 的企业版。如果您仍然需要企业工件,则需要首先通过 [Mesosphere 支持门户] 提交故障单。(). 企业工件作为 Docker 镜像文件提供,并包含 Marathon 以及 Marathon 插件,可启用 DC/OS Enterprise 功能 - 例如密钥和细分访问权限控制。

前提条件:

  • DC/OS 和 DC/OS CLI 已安装
  • 每个专用 DC/OS 代理可以通过网络访问的专用 Docker 注册表。可以遵循 以下 关于如何在 Marathon 中设置,或使用其他选项的说明(如 、Amazon EC2 容器注册表和 ).
  • 自定义非本机 Marathon 镜像部署在您的专用 Docker 注册表中。通过 提交故障单以获取企业 Marathon 镜像文件。
  • 您必须以超级用户身份登录。
  • 对群集的 SSH 访问。

此示例中的变量

整个页面将指示您调用命令或执行使用特定于群集的值的操作。我们使用 表示法引用这些特定于群集的值;请将以下变量替换为您的群集的合适值。

该表包含本页所用的所有变量:

如果您使用的是 Mac OS 或 Linux 计算机,则可以在终端会话中预先定义上述大多数变量,只需将片段复制并粘贴到终端中即可:

步骤 1:准备

在以下步骤中,我们假设您已经:

  1. 将 Marathon 企业镜像推送到您的专用注册表(说明),名称为 ${MARATHON_IMAGE}:${MARATHON_TAG}.

  2. 将您的专用 Docker 凭据存储在密钥存储库 中,名称为 ${DOCKER_REGISTRY_SECRET}.

    警告:密钥的名称应该位于根路径(例如 /some-secret-name)中,或者以应用程序的名称为前缀(例如 /${MARATHON_INSTANCE_NAME}/some-secret-name). 如果不这样做,将使根 Marathon 无法读取密钥值,并且无法启动自定义 Marathon-on-Marathon 实例。

步骤 2:创建 Marathon 服务帐户

本步骤创建了 Marathon 服务账户 Marathon 将使用此帐户对其余 DC/OS 组件进行身份认证。稍后授予此帐户的权限将定义允许 Marathon 执行的操作。

Marathon 服务账户可能是可选或必填项,具体取决于您的

  1. 创建 2048 位 RSA 公私密钥对 (${PRIVATE_KEY}${PUBLIC_KEY}) 并将值分别保存到当前目录中的单独文件中。

    使用以下命令,我们创建一个公私密钥对。公钥将用于创建 Marathon 服务帐户。我们将私钥存储在 密钥存储库 然后将其传递至 Marathon,供其进行自我授权。

    1. dcos security org service-accounts keypair ${PRIVATE_KEY} ${PUBLIC_KEY}
  2. 使用我们生成的公钥(${SERVICE_ACCOUNT})创建一个名为 ${PUBLIC_KEY}). 的新服务帐户。

    1. dcos security org service-accounts create -p ${PUBLIC_KEY} -d "Marathon-on-Marathon User" ${SERVICE_ACCOUNT}

步骤 3:创建服务帐户密钥

在此步骤中,为 Marathon 服务帐户创建密钥,并存储在密钥存储库中。

  1. dcos security secrets create-sa-secret ${PRIVATE_KEY} ${SERVICE_ACCOUNT} ${SERVICE_ACCOUNT_SECRET}

严格

  1. dcos security secrets create-sa-secret --strict ${PRIVATE_KEY} ${SERVICE_ACCOUNT} ${SERVICE_ACCOUNT_SECRET}

建议

  • 使用以下命令确保您的密钥已就绪:

    1. dcos security secrets list /
  • 查看您的密钥,确保其包含正确的服务帐户 ID、私钥和 login_endpoint URL。如果是 strict 模式,应为 HTTPS,如果是 permissive 模式,则应为 HTTP。如果 URL 不正确,尝试 ,删除密钥,并重新创建。

    您可以使用此命令查看内容(需要安装 jq 1.5 或更高版本

  • 从文件系统中删除私钥文件,防止不法之徒利用私钥通过 DC/OS 身份认证。

步骤 4:分配权限(仅限严格模式)

在此步骤中,权限被分配至 Marathon-on-Marathon 实例。在严格模式下需要权限,而在其他安全模式将其忽略即可。

所有 CLI 命令也可通过 [IAM API]执行。(/mesosphere/dcos/cn/2.1/security/ent/iam-api/).

授予服务帐户 ${SERVICE_ACCOUNT} 权限,以启动将作为 Linux 用户 nobody. 执行的 Mesos 任务。

要以不同 Linux 用户的身份执行任务,请将 nobody 替换为该用户的 Linux 用户名。例如,如需以 Linux 用户 bob 身份启动任务,请替换 nobody 为以下的 bob

请注意,nobodyroot 用户是默认出现在所有代理上的;如果指定自定义用户(例如,bob),则用户 bob 需要在可以执行这些任务的每个代理上手动创建(例如,使用 Linux adduser 或类似实用程序)。

  1. dcos security org users grant ${SERVICE_ACCOUNT} dcos:mesos:master:task:user:nobody create --description "Tasks can execute as Linux user nobody"
  2. dcos security org users grant ${SERVICE_ACCOUNT} dcos:mesos:master:framework:role:${MESOS_ROLE} create --description "Controls the ability of ${MESOS_ROLE} to register as a framework with the Mesos master"
  3. dcos security org users grant ${SERVICE_ACCOUNT} dcos:mesos:master:reservation:role:${MESOS_ROLE} create --description "Controls the ability of ${MESOS_ROLE} to reserve resources"
  4. dcos security org users grant ${SERVICE_ACCOUNT} dcos:mesos:master:volume:role:${MESOS_ROLE} create --description "Controls the ability of ${MESOS_ROLE} to access volumes"
  5. dcos security org users grant ${SERVICE_ACCOUNT} dcos:mesos:master:reservation:principal:${SERVICE_ACCOUNT} delete --description "Controls the ability of ${SERVICE_ACCOUNT} to reserve resources"
  6. dcos security org users grant ${SERVICE_ACCOUNT} dcos:mesos:master:task:app_id:/ create --description "Controls the ability to launch tasks"
  7. dcos security org users grant ${SERVICE_ACCOUNT} dcos:mesos:master:volume:principal:${SERVICE_ACCOUNT} delete --description "Controls the ability of ${SERVICE_ACCOUNT} to access volumes"

步骤 5:安装具有分配角色 的非本地 Marathon 实例

在此步骤中,非本地 Marathon 实例安装在 DC/OS上,并分配了 Mesos 角色。

  1. 创建一个自定义 JSON 配置,用于安装自定义非本机 Marathon 实例。JSON 文件内容因您的 [安全模式]而有所不同。(/mesosphere/dcos/cn/2.1/security/ent/#security-modes).

    确保使用正确的值替换 JSON 文件中的所有 ${VARIABLES}

    或者,如果已在终端会话中导出变量(如 中所述),则可以使用以下命令自动将所有替代变量替换为其导出值。所得文件将保存为 marathon-filled.json:

    1. perl -p -e 's/\$\{(\w+)\}/(exists $ENV{$1}?$ENV{$1}:"<missing-variable-$1>")/eg' < marathon.json > marathon-filled.json

    如果在 permissive 安全模式下运行群集,请使用以下 JSON 模板。不要忘记替换符合 ${VARIABLES} 格式的所有环境变量:

    1. {
    2. "id":"/${MARATHON_INSTANCE_NAME}",
    3. "cmd":"cd $MESOS_SANDBOX && LIBPROCESS_PORT=$PORT1 && /marathon/bin/start --default_accepted_resource_roles \"*,${MESOS_ROLE}\" --enable_features \"vips,task_killing,external_volumes,secrets,gpu_resources\" --framework_name ${MARATHON_INSTANCE_NAME} --hostname $LIBPROCESS_IP --http_port $PORT0 --master zk://master.mesos:2181/mesos --max_instances_per_offer 1 --mesos_leader_ui_url /mesos --mesos_role ${MESOS_ROLE} --zk zk://master.mesos:2181/universe/${MARATHON_INSTANCE_NAME} --mesos_user nobody --mesos_authentication --mesos_authentication_principal ${SERVICE_ACCOUNT}",
    4. "user":"nobody",
    5. "cpus":2,
    6. "mem":4096,
    7. "disk":0,
    8. "instances":1,
    9. "constraints":[
    10. [
    11. "hostname",
    12. "UNIQUE"
    13. ]
    14. ],
    15. "container":{
    16. "type": "MESOS",
    17. "docker":{
    18. "image":"${MARATHON_IMAGE}:${MARATHON_TAG}",
    19. "pullConfig": {
    20. "secret": "docker-registry-credential"
    21. }
    22. }
    23. },
    24. "env":{
    25. "JVM_OPTS":"-Xms256m -Xmx2g",
    26. "DCOS_STRICT_SECURITY_ENABLED":"false",
    27. "DCOS_SERVICE_ACCOUNT_CREDENTIAL":{
    28. },
    29. "MESOS_AUTHENTICATEE":"com_mesosphere_dcos_ClassicRPCAuthenticatee",
    30. "MESOS_MODULES":"{\"libraries\":[{\"file\":\"/opt/libmesos-bundle/lib/libdcos_security.so\",\"modules\":[{\"name\":\"com_mesosphere_dcos_ClassicRPCAuthenticatee\"}]}]}",
    31. "MESOS_VERBOSE":"true",
    32. "GLOG_v":"2",
    33. "PLUGIN_ACS_URL":"http://master.mesos",
    34. "PLUGIN_AUTHN_MODE":"dcos/jwt+anonymous",
    35. "PLUGIN_FRAMEWORK_TYPE":"marathon"
    36. },
    37. "healthChecks":[
    38. {
    39. "path":"/ping",
    40. "portIndex":0,
    41. "gracePeriodSeconds":1800,
    42. "intervalSeconds":10,
    43. "timeoutSeconds":5,
    44. "maxConsecutiveFailures":3,
    45. "ignoreHttp1xx":false
    46. }
    47. ],
    48. "secrets":{
    49. "service-credential":{
    50. "source":"${SERVICE_ACCOUNT_SECRET}"
    51. },
    52. "docker-registry-credential": {
    53. "source":"${DOCKER_REGISTRY_SECRET}"
    54. }
    55. },
    56. "labels":{
    57. "DCOS_SERVICE_NAME":"${MARATHON_INSTANCE_NAME}",
    58. "DCOS_SERVICE_PORT_INDEX":"0",
    59. "DCOS_SERVICE_SCHEME":"http"
    60. },
    61. "portDefinitions":[
    62. {
    63. "port":0,
    64. "name":"http"
    65. },
    66. {
    67. "port":0,
    68. "name":"libprocess"
    69. }
    70. ]
    71. }

    严格

    如果在 strict 安全模式下运行群集,请使用以下 JSON 模板。不要忘记替换符合 ${VARIABLES} 格式的所有环境变量:

    1. {
    2. "id":"/${MARATHON_INSTANCE_NAME}",
    3. "cmd":"cd $MESOS_SANDBOX && LIBPROCESS_PORT=$PORT1 && /marathon/bin/start --default_accepted_resource_roles \"*,${MESOS_ROLE}\" --enable_features \"vips,task_killing,external_volumes,secrets,gpu_resources\" --framework_name ${MARATHON_INSTANCE_NAME} --hostname $LIBPROCESS_IP --http_port $PORT0 --master zk://master.mesos:2181/mesos --max_instances_per_offer 1 --mesos_leader_ui_url /mesos --mesos_role ${MESOS_ROLE} --zk zk://master.mesos:2181/universe/${MARATHON_INSTANCE_NAME} --mesos_user nobody --mesos_authentication --mesos_authentication_principal ${SERVICE_ACCOUNT}",
    4. "user":"nobody",
    5. "cpus":2,
    6. "mem":4096,
    7. "disk":0,
    8. "instances":1,
    9. "constraints":[
    10. [
    11. "hostname",
    12. "UNIQUE"
    13. ]
    14. ],
    15. "container":{
    16. "type": "MESOS",
    17. "docker":{
    18. "image":"${MARATHON_IMAGE}:${MARATHON_TAG}",
    19. "pullConfig": {
    20. "secret": "docker-registry-credential"
    21. }
    22. }
    23. },
    24. "env":{
    25. "JVM_OPTS":"-Xms256m -Xmx2g",
    26. "DCOS_STRICT_SECURITY_ENABLED":"true",
    27. "DCOS_SERVICE_ACCOUNT_CREDENTIAL":{
    28. "secret":"service-credential"
    29. },
    30. "MESOS_AUTHENTICATEE":"com_mesosphere_dcos_ClassicRPCAuthenticatee",
    31. "MESOS_MODULES":"{\"libraries\":[{\"file\":\"/opt/libmesos-bundle/lib/libdcos_security.so\",\"modules\":[{\"name\":\"com_mesosphere_dcos_ClassicRPCAuthenticatee\"}]}]}",
    32. "MESOS_VERBOSE":"true",
    33. "GLOG_v":"2",
    34. "PLUGIN_ACS_URL":"https://master.mesos",
    35. "PLUGIN_AUTHN_MODE":"dcos/jwt",
    36. "PLUGIN_FRAMEWORK_TYPE":"marathon"
    37. },
    38. "healthChecks":[
    39. {
    40. "path":"/",
    41. "protocol":"HTTP",
    42. "portIndex":0,
    43. "gracePeriodSeconds":1800,
    44. "intervalSeconds":10,
    45. "timeoutSeconds":5,
    46. "maxConsecutiveFailures":3,
    47. "ignoreHttp1xx":false
    48. }
    49. "secrets":{
    50. "service-credential":{
    51. "source":"${SERVICE_ACCOUNT_SECRET}"
    52. "docker-registry-credential": {
    53. "source":"${DOCKER_REGISTRY_SECRET}"
    54. }
    55. },
    56. "labels":{
    57. "DCOS_SERVICE_NAME":"${MARATHON_INSTANCE_NAME}",
    58. "DCOS_SERVICE_PORT_INDEX":"0",
    59. "DCOS_SERVICE_SCHEME":"http"
    60. },
    61. "portDefinitions":[
    62. {
    63. "port":0,
    64. "name":"http"
    65. },
    66. {
    67. "port":0,
    68. "name":"libprocess"
    69. }
    70. ]
    71. }
  2. 部署 Marathon 实例,传递您在上一步中创建的 JSON 文件。

    1. dcos marathon app add marathon-filled.json

步骤 6:授予用户对非本地 Marathon 的访问权限

到目前为止,您的新 Marathon 实例只能由 DC/OS 超级用户访问。为了提供对常规用户的访问权限,您需要根据群集安全模式明确授予他们访问权限:

  • 为在新创建的 Marathon 上运行的任何服务(或组)提供完全权限:

  • 向在新创建的 Marathon 上运行且名为 的个体服务(或组)提供权限:${CHILD_SERVICE_NAME}:

    1. # Access to the new Marathon service under `/service/<name>` URL
    2. dcos security org users grant ${USER_ACCOUNT} dcos:adminrouter:service:${MARATHON_INSTANCE_NAME} full
    3. dcos security org users grant ${USER_ACCOUNT} dcos:service:marathon:${MARATHON_INSTANCE_NAME}:services:/${CHILD_SERVICE_NAME} full
    4. # Access to the Mesos tasks and their sandbox
    5. dcos security org users grant ${USER_ACCOUNT} dcos:adminrouter:ops:mesos full
    6. dcos security org users grant ${USER_ACCOUNT} dcos:adminrouter:ops:slave full
    7. # (Optionally) Access to the Marathon instance that runs on the root
    8. # Marathon and can be controlled via the DC/OS UI
    9. dcos security org users grant ${USER_ACCOUNT} dcos:adminrouter:service:marathon full
    10. dcos security org users grant ${USER_ACCOUNT} dcos:service:marathon:marathon:services:/${MARATHON_INSTANCE_NAME} full

严格

对于您要授予访问权限的每个 ${USER_ACCOUNT},是否在 strict 安全模式下运行群集,取决于您要提供的权限类型:

  • 为在新创建的 Marathon 上运行的任何服务(或组)提供完全权限:

    1. # Access to the new Marathon service under `/service/<name>` URL
    2. dcos security org users grant ${USER_ACCOUNT} dcos:adminrouter:service:${MARATHON_INSTANCE_NAME} full
    3. dcos security org users grant ${USER_ACCOUNT} dcos:service:marathon:${MARATHON_INSTANCE_NAME}:services:/ full
    4. # Access to the Mesos tasks and their sandbox
    5. dcos security org users grant ${USER_ACCOUNT} dcos:adminrouter:ops:mesos full
    6. dcos security org users grant ${USER_ACCOUNT} dcos:adminrouter:ops:slave full
    7. dcos security org users grant ${USER_ACCOUNT} dcos:mesos:agent:executor:app_id:/ read
    8. dcos security org users grant ${USER_ACCOUNT} dcos:mesos:agent:framework:role:${MESOS_ROLE} read
    9. dcos security org users grant ${USER_ACCOUNT} dcos:mesos:agent:sandbox:app_id:/ read
    10. dcos security org users grant ${USER_ACCOUNT} dcos:mesos:agent:task:app_id:/ read
    11. dcos security org users grant ${USER_ACCOUNT} dcos:mesos:master:executor:app_id:/ read
    12. dcos security org users grant ${USER_ACCOUNT} dcos:mesos:master:framework:role:${MESOS_ROLE} read
    13. dcos security org users grant ${USER_ACCOUNT} dcos:mesos:master:task:app_id:/ read
    14. # (Optionally) Access to the Marathon instance that runs on the root
    15. # Marathon and can be controlled via the DC/OS UI
    16. dcos security org users grant ${USER_ACCOUNT} dcos:adminrouter:service:marathon full
    17. dcos security org users grant ${USER_ACCOUNT} dcos:service:marathon:marathon:services:/${MARATHON_INSTANCE_NAME} full
  • 向在新创建的 Marathon 上运行且名为 的个体服务(或组)提供权限:${CHILD_SERVICE_NAME}:

    1. # Access to the new Marathon service under `/service/<name>` URL
    2. dcos security org users grant ${USER_ACCOUNT} dcos:adminrouter:service:${MARATHON_INSTANCE_NAME} full
    3. dcos security org users grant ${USER_ACCOUNT} dcos:service:marathon:${MARATHON_INSTANCE_NAME}:services:/${CHILD_SERVICE_NAME} full
    4. # Access to the Mesos tasks and their sandbox
    5. dcos security org users grant ${USER_ACCOUNT} dcos:adminrouter:ops:mesos full
    6. dcos security org users grant ${USER_ACCOUNT} dcos:adminrouter:ops:slave full
    7. dcos security org users grant ${USER_ACCOUNT} dcos:mesos:agent:executor:app_id:/${CHILD_SERVICE_NAME} read
    8. dcos security org users grant ${USER_ACCOUNT} dcos:mesos:agent:framework:role:${MESOS_ROLE} read
    9. dcos security org users grant ${USER_ACCOUNT} dcos:mesos:agent:sandbox:app_id:/${CHILD_SERVICE_NAME} read
    10. dcos security org users grant ${USER_ACCOUNT} dcos:mesos:agent:task:app_id:/${CHILD_SERVICE_NAME} read
    11. dcos security org users grant ${USER_ACCOUNT} dcos:mesos:master:executor:app_id:/${CHILD_SERVICE_NAME} read
    12. dcos security org users grant ${USER_ACCOUNT} dcos:mesos:master:framework:role:${MESOS_ROLE} read
    13. dcos security org users grant ${USER_ACCOUNT} dcos:mesos:master:task:app_id:/${CHILD_SERVICE_NAME} read
    14. # (Optionally) Access to the Marathon instance that runs on the root
    15. # Marathon and can be controlled via the DC/OS UI
    16. dcos security org users grant ${USER_ACCOUNT} dcos:adminrouter:service:marathon full
    17. dcos security org users grant ${USER_ACCOUNT} dcos:service:marathon:marathon:services:/${MARATHON_INSTANCE_NAME} full

步骤 7:访问非本地 Marathon 实例

在此步骤中,您以授权用户身份登录非本地 Marathon DC/OS 服务。

  1. 启动非本地 Marathon 接口,位于:http://<master-public-ip>/service/${SERVICE_ACCOUNT}/.

  2. 输入您的用户名和密码,然后单击 登录

    图 4. 成功了!

    Marathon on Marathon

后续步骤

  • 您可以使用以下命令将 DC/OS CLI 配置为与非本机 Marathon 实例进行交互:

    1. dcos config set marathon.url \
    2. $(dcos config show core.dcos_url)/service/${MARATHON_INSTANCE_NAME}

    现在,任何未来 dcos marathon ... 命令将瞄准您的新 Marathon 实例。

    要撤消此更改,请使用以下命令:

    1. dcos config unset marathon.url

已知问题

  • 启动 Docker 容器时,用户 nobody 可能没有足够的权限来成功运行。例如,无法作为用户 nginx 启动 nobody Docker 容器,因为 nobody 没有 /var/log 所需的 nginx 的写入权限。

  • 用户 nobody 在不同的系统上具有不同的 UID(在 coreos 上为 99,在 ubuntu 上为 65534)。根据代理的分布情况,您可能需要修改容器镜像以使 UID 匹配!使用用户 时也是如此。bob.