带安全功能的自定义 Marathon
使用高级非本地 Marathon 实例
本专题描述了如何部署具有独立角色、保留、配额和安全功能的非本地 Marathon 实例 (Marathon on Marathon) 。高级非本地 Marathon 程序只能在您需要 密钥 或细粒度 ACL 时使用。否则,请使用 。
对于本程序,我们假设您已从支持团队成员获得了 Marathon 的企业版。如果您仍然需要企业工件,则需要首先通过 Mesosphere 支持门户 提交故障单。企业工件作为 Docker 镜像文件提供,并包含 Marathon 以及 Marathon 插件,可启用 DC/OS Enterprise 功能 - 例如密钥和细分访问权限控制。
前提条件
- DC/OS 和 DC/OS CLI 。
- DC/OS Enterprise CLI 0.4.14 或更高版本。
- 每个专用 DC/OS 代理可以通过网络访问的专用 Docker 注册表。可以遵循 关于如何在 Marathon 中设置,或使用其他选项的说明(如 DockerHub、和 Quay)。
- 自定义非本机 Marathon 镜像。通过 支持门户 提交故障单以获取企业 Marathon 镜像文件。
- 您必须以超级用户身份登录。
- 对群集的 SSH 访问。
-
将 Marathon 企业镜像推送到您的专用注册表(说明),名称为
${MARATHON_IMAGE}:${MARATHON_TAG}
。 -
将您的专用 Docker 凭据存储在密钥存储库 中,名称为
${DOCKER_REGISTRY_SECRET}
。 警告:密钥的名称应该位于根路径(例如/some-secret-name
)中,或者以应用程序的名称为前缀(例如/${MARATHON_INSTANCE_NAME}/some-secret-name
)。如果不这样做,将使根 Marathon 无法读取密钥值,并且无法启动自定义 Marathon-on-Marathon 实例。
-
创建 2048 位 RSA 公私密钥对 (
${PRIVATE_KEY}
和${PUBLIC_KEY}
) 并将值分别保存到当前目录中的单独文件中。 使用以下命令,我们创建一个公私密钥对。公钥将用于创建 Marathon 服务帐户。我们将私钥存储在 密钥存储库 然后将其传递至 Marathon,供其进行自我授权。dcos security org service-accounts keypair ${PRIVATE_KEY} ${PUBLIC_KEY}
-
使用我们生成的公钥(
${PUBLIC_KEY}
)创建一个名为${SERVICE_ACCOUNT}
的新服务帐户。dcos security org service-accounts create -p ${PUBLIC_KEY} -d "Marathon-on-Marathon User" ${SERVICE_ACCOUNT}
${SERVICE_ACCOUNT_SECRET}
) 将包含私钥 (${PRIVATE_KEY}
) 和服务帐户名称 (${SERVICE_ACCOUNT}
)。Marathon 将使用此信息对 DC/OS 进行身份认证。
##
### 宽容
### 严格
dcos security secrets create-sa-secret ${PRIVATE_KEY} ${SERVICE_ACCOUNT} ${SERVICE_ACCOUNT_SECRET}
#### 建议
dcos security secrets create-sa-secret —strict ${PRIVATE_KEY} ${SERVICE_ACCOUNT} ${SERVICE_ACCOUNT_SECRET}
-
使用以下命令确保您的密钥已就绪:
dcos security secrets list /
-
查看您的密钥,确保其包含正确的服务帐户 ID、私钥和
login_endpoint
URL。如果是strict
模式,应为 HTTPS,如果是permissive
模式,则应为 HTTP。如果 URL 不正确,尝试 ,删除密钥,并重新创建。 您可以使用此命令查看内容(需要安装 jq 1.5 或更高版本): - 从文件系统中删除私钥文件,防止不法之徒利用私钥通过 DC/OS 身份认证。
步骤 4:分配权限(仅限严格模式)
所有 CLI 命令也可通过 IAM API 执行。
授予服务帐户 ${SERVICE_ACCOUNT}
权限,以启动将作为 Linux 用户 nobody
执行的 Mesos 任务。
要以不同 Linux 用户的身份执行任务,请将 nobody
替换为该用户的 Linux 用户名。例如,如需以 Linux 用户 bob
身份启动任务,请替换 nobody
为以下的 bob
。
dcos security org users grant ${SERVICE_ACCOUNT} dcos:mesos:master:task:user:nobody create --description "Tasks can execute as Linux user nobody"
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"
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"
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"
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"
dcos security org users grant ${SERVICE_ACCOUNT} dcos:mesos:master:task:app_id:/ create --description "Controls the ability to launch tasks"
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:安装具有分配角色 {.tabs} 的非本地 Marathon 实例
在此步骤中,非本地 Marathon 实例安装在 DC/OS上,并分配了 Mesos 角色。
-
创建一个自定义 JSON 配置,用于安装自定义非本机 Marathon 实例。JSON 文件内容因您的 安全模式 而有所不同。
确保使用正确的值替换 JSON 文件中的所有
${VARIABLES}
。 或者,如果已在终端会话中导出变量(如 中所述),则可以使用以下命令自动将所有替代变量替换为其导出值。所得文件将保存为marathon-filled.json
:
## ### 宽容 如果在perl -p -e 's/\${(\w+)}/(exists $ENV{$1}?$ENV{$1}:"<missing-variable-$1>")/eg' < marathon.json > marathon-filled.json
permissive
安全模式下运行群集,请使用以下 JSON 模板。不要忘记替换符合${VARIABLES}
格式的所有环境变量:
### 严格 如果在{
"id":"/${MARATHON_INSTANCE_NAME}",
"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}",
"user":"nobody",
"cpus":2,
"mem":4096,
"disk":0,
"instances":1,
"constraints":[
[
"hostname",
"UNIQUE"
]
],
"container":{
"type": "MESOS",
"docker":{
"image":"${MARATHON_IMAGE}:${MARATHON_TAG}",
"pullConfig": {
"secret": "docker-registry-credential"
}
}
},
"env":{
"JVM_OPTS":"-Xms256m -Xmx2g",
"DCOS_STRICT_SECURITY_ENABLED":"false",
"DCOS_SERVICE_ACCOUNT_CREDENTIAL":{
"secret":"service-credential"
"MESOS_AUTHENTICATEE":"com_mesosphere_dcos_ClassicRPCAuthenticatee",
"MESOS_MODULES":"{\"libraries\":[{\"file\":\"/opt/libmesos-bundle/lib/libdcos_security.so\",\"modules\":[{\"name\":\"com_mesosphere_dcos_ClassicRPCAuthenticatee\"}]}]}",
"MESOS_VERBOSE":"true",
"GLOG_v":"2",
"PLUGIN_ACS_URL":"http://master.mesos",
"PLUGIN_AUTHN_MODE":"dcos/jwt+anonymous",
"PLUGIN_FRAMEWORK_TYPE":"marathon"
},
"healthChecks":[
{
"path":"/ping",
"protocol":"HTTP",
"portIndex":0,
"gracePeriodSeconds":1800,
"intervalSeconds":10,
"timeoutSeconds":5,
"ignoreHttp1xx":false
}
],
"secrets":{
"service-credential":{
"source":"${SERVICE_ACCOUNT_SECRET}"
},
"docker-registry-credential": {
"source":"${DOCKER_REGISTRY_SECRET}"
}
},
"labels":{
"DCOS_SERVICE_NAME":"${MARATHON_INSTANCE_NAME}",
"DCOS_SERVICE_PORT_INDEX":"0",
"DCOS_SERVICE_SCHEME":"http"
},
"portDefinitions":[
{
"port":0,
"name":"http"
},
{
"port":0,
"name":"libprocess"
}
]
}
strict
安全模式下运行群集,请使用以下 JSON 模板。不要忘记替换符合${VARIABLES}
格式的所有环境变量:{
"id":"/${MARATHON_INSTANCE_NAME}",
"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}",
"user":"nobody",
"cpus":2,
"mem":4096,
"disk":0,
"instances":1,
"constraints":[
[
"hostname",
"UNIQUE"
]
],
"container":{
"type": "MESOS",
"docker":{
"image":"${MARATHON_IMAGE}:${MARATHON_TAG}",
"pullConfig": {
"secret": "docker-registry-credential"
}
}
},
"env":{
"JVM_OPTS":"-Xms256m -Xmx2g",
"DCOS_STRICT_SECURITY_ENABLED":"true",
"DCOS_SERVICE_ACCOUNT_CREDENTIAL":{
"secret":"service-credential"
},
"MESOS_AUTHENTICATEE":"com_mesosphere_dcos_ClassicRPCAuthenticatee",
"MESOS_MODULES":"{\"libraries\":[{\"file\":\"/opt/libmesos-bundle/lib/libdcos_security.so\",\"modules\":[{\"name\":\"com_mesosphere_dcos_ClassicRPCAuthenticatee\"}]}]}",
"MESOS_VERBOSE":"true",
"GLOG_v":"2",
"PLUGIN_ACS_URL":";,
"PLUGIN_AUTHN_MODE":"dcos/jwt",
"PLUGIN_FRAMEWORK_TYPE":"marathon"
},
"healthChecks":[
{
"path":"/",
"protocol":"HTTP",
"portIndex":0,
"gracePeriodSeconds":1800,
"intervalSeconds":10,
"timeoutSeconds":5,
"maxConsecutiveFailures":3,
"ignoreHttp1xx":false
}
],
"service-credential":{
"source":"${SERVICE_ACCOUNT_SECRET}"
},
"docker-registry-credential": {
"source":"${DOCKER_REGISTRY_SECRET}"
},
"labels":{
"DCOS_SERVICE_NAME":"${MARATHON_INSTANCE_NAME}",
"DCOS_SERVICE_PORT_INDEX":"0",
"DCOS_SERVICE_SCHEME":"http"
},
"portDefinitions":[
{
"port":0,
"name":"http"
},
{
"port":0,
"name":"libprocess"
}
]
}
-
部署 Marathon 实例,传递您在上一步中创建的 JSON 文件。
dcos marathon app add marathon-filled.json
步骤 6:授予用户对非本地 Marathon 的访问权限
到目前为止,您的新 Marathon 实例只能由 DC/OS 超级用户访问。为了提供对常规用户的访问权限,您需要根据群集安全模式明确授予他们访问权限:
对于您要授予访问权限的每个 ${USER_ACCOUNT}
,是否在 permissive
安全模式下运行群集,取决于您要提供的权限类型:
- 为在新创建的 Marathon 上运行的任何服务(或组)提供完全权限:
-
向在新创建的 Marathon 上运行且名为
${CHILD_SERVICE_NAME}
的个体服务(或组)提供权限:# Access to the new Marathon service under
/service/<name>
URLdcos security org users grant ${USER_ACCOUNT} dcos:adminrouter:service:${MARATHON_INSTANCE_NAME} full
dcos security org users grant ${USER_ACCOUNT} dcos:service:marathon:${MARATHON_INSTANCE_NAME}:services:/${CHILD_SERVICE_NAME} full
# Access to the Mesos tasks and their sandbox
dcos security org users grant ${USER_ACCOUNT} dcos:adminrouter:ops:mesos full
dcos security org users grant ${USER_ACCOUNT} dcos:adminrouter:ops:slave full
# (Optionally) Access to the Marathon instance that runs on the root
# Marathon and can be controlled via the DC/OS UI
dcos security org users grant ${USER_ACCOUNT} dcos:adminrouter:service:marathon full
dcos security org users grant ${USER_ACCOUNT} dcos:service:marathon:marathon:services:/${MARATHON_INSTANCE_NAME} full
严格
-
为在新创建的 Marathon 上运行的任何服务(或组)提供完全权限:
# Access to the new Marathon service under
/service/<name>
URLdcos security org users grant ${USER_ACCOUNT} dcos:adminrouter:service:${MARATHON_INSTANCE_NAME} full
dcos security org users grant ${USER_ACCOUNT} dcos:service:marathon:${MARATHON_INSTANCE_NAME}:services:/ full
# Access to the Mesos tasks and their sandbox
dcos security org users grant ${USER_ACCOUNT} dcos:adminrouter:ops:mesos full
dcos security org users grant ${USER_ACCOUNT} dcos:adminrouter:ops:slave full
dcos security org users grant ${USER_ACCOUNT} dcos:mesos:agent:executor:app_id:/ read
dcos security org users grant ${USER_ACCOUNT} dcos:mesos:agent:framework:role:${MESOS_ROLE} read
dcos security org users grant ${USER_ACCOUNT} dcos:mesos:agent:sandbox:app_id:/ read
dcos security org users grant ${USER_ACCOUNT} dcos:mesos:agent:task:app_id:/ read
dcos security org users grant ${USER_ACCOUNT} dcos:mesos:master:executor:app_id:/ read
dcos security org users grant ${USER_ACCOUNT} dcos:mesos:master:framework:role:${MESOS_ROLE} read
dcos security org users grant ${USER_ACCOUNT} dcos:mesos:master:task:app_id:/ read
# (Optionally) Access to the Marathon instance that runs on the root
# Marathon and can be controlled via the DC/OS UI
dcos security org users grant ${USER_ACCOUNT} dcos:adminrouter:service:marathon full
dcos security org users grant ${USER_ACCOUNT} dcos:service:marathon:marathon:services:/${MARATHON_INSTANCE_NAME} full
-
向在新创建的 Marathon 上运行且名为
${CHILD_SERVICE_NAME}
的个体服务(或组)提供权限:# Access to the new Marathon service under
/service/<name>
URLdcos security org users grant ${USER_ACCOUNT} dcos:adminrouter:service:${MARATHON_INSTANCE_NAME} full
dcos security org users grant ${USER_ACCOUNT} dcos:service:marathon:${MARATHON_INSTANCE_NAME}:services:/${CHILD_SERVICE_NAME} full
# Access to the Mesos tasks and their sandbox
dcos security org users grant ${USER_ACCOUNT} dcos:adminrouter:ops:mesos full
dcos security org users grant ${USER_ACCOUNT} dcos:adminrouter:ops:slave full
dcos security org users grant ${USER_ACCOUNT} dcos:mesos:agent:executor:app_id:/${CHILD_SERVICE_NAME} read
dcos security org users grant ${USER_ACCOUNT} dcos:mesos:agent:framework:role:${MESOS_ROLE} read
dcos security org users grant ${USER_ACCOUNT} dcos:mesos:agent:sandbox:app_id:/${CHILD_SERVICE_NAME} read
dcos security org users grant ${USER_ACCOUNT} dcos:mesos:agent:task:app_id:/${CHILD_SERVICE_NAME} read
dcos security org users grant ${USER_ACCOUNT} dcos:mesos:master:executor:app_id:/${CHILD_SERVICE_NAME} read
dcos security org users grant ${USER_ACCOUNT} dcos:mesos:master:framework:role:${MESOS_ROLE} read
dcos security org users grant ${USER_ACCOUNT} dcos:mesos:master:task:app_id:/${CHILD_SERVICE_NAME} read
# (Optionally) Access to the Marathon instance that runs on the root
# Marathon and can be controlled via the DC/OS UI
dcos security org users grant ${USER_ACCOUNT} dcos:adminrouter:service:marathon full
dcos security org users grant ${USER_ACCOUNT} dcos:service:marathon:marathon:services:/${MARATHON_INSTANCE_NAME} full
步骤 7:访问非本地 Marathon 实例
在此步骤中,您以授权用户身份登录非本地 Marathon DC/OS 服务。
-
启动非本地 Marathon 接口,位于:
。
-
输入您的用户名和密码,然后单击 登录。
图 4. 成功了!
后续步骤
-
您可以使用以下命令将 DC/OS CLI 配置为与非本机 Marathon 实例进行交互:
现在,任何未来dcos config set marathon.url \
$(dcos config show core.dcos_url)/service/${MARATHON_INSTANCE_NAME}
dcos marathon …
命令将瞄准您的新 Marathon 实例。 要撤消此更改,请使用以下命令:dcos config unset marathon.url
已知问题
-
启动 Docker 容器时,用户
nobody
可能没有足够的权限来成功运行。例如,无法作为用户nobody
启动nginx
Docker 容器,因为nobody
没有/var/log
所需的nginx
的写入权限。 -
用户
nobody
在不同的系统上具有不同的 UID(在 coreos 上为 99,在 ubuntu 上为 65534)。根据代理的分布情况,您可能需要修改容器镜像以使 UID 匹配!使用用户bob
时也是如此。 - 使用自定义用户(例如,)时,用户必须存在于代理中,若是使用容器,则必须存在于容器内。