.dockercfg 文件应该如何托管在 Mesosphere-on-AWS 设置中,以便只有 Mesosphere 可以使用它?

How should a .dockercfg file be hosted in a Mesosphere-on-AWS setup so that only Mesosphere can use it?

我们已经在 AWS 上的私有 VPC 中使用 Mesosphere 设置了一个测试集群。我们有一些 Docker 图像 public,它们很容易部署。但是,我们的大部分服务都是私有图像,托管在 Docker Hub 私有计划上,需要身份验证才能访问。

Mesosphere 能够进行私有注册表身份验证,但它以 not-exactly-ideal 方式实现:需要在所有 Mesos/Marathon 任务定义中指定 .dockercfg 文件的 HTTPS URI。

正如标题所暗示的,问题基本上是:.dockercfg 文件应该如何托管在 AWS 中,以便尽可能严格地将访问限制在 Mesos master+slaves 上?

我看到的许多项目都使用您提到的 S3 方法。您的观点仍然有效,我们 should/will 在社区中对此进行讨论。

您还可以在 HDFS 或 FTP/FTPS 服务器中托管 .dockercfg。如果 HTTPS 不可接受,Mesos 提取器可以支持这些协议中的任何一种。

由于 Mesos 文档在这方面的表现很差,我将以维基风格回答这个问题并随时更新这个答案。


应该有效的策略

在 S3 上托管(具有基于网络的访问限制)

在 S3 上托管 .dockercfg 文件。为了更好的安全性,您应该考虑将它放在自己的桶中,或者放在专门用于存储秘密的桶中。这在创建安全策略时提出了一些有趣的挑战,该策略实际上可以锁定 S3 存储桶,以便只有 Mesos 可以看到它,但这是可以做到的。

Mesos 任务配置:

{
  ...
  "uris": ["https://s3-eu-west-1.amazonaws.com/my-s3-bucket-name/.dockercfg"]
  ...
}

S3 存储桶策略(使用 VPC 端点):

注意:此策略允许允许的主体执行任何操作,这对于生产来说过于草率,但在测试集群中进行调试时应该有所帮助。

{
  "Id": "Policy123456",
  "Version": "2012-10-17",
  "Statement": [{
    "Sid": "Stmt123456",
    "Action": "s3:*",
    "Effect": "Allow",
    "Resource": [
      "arn:aws:s3:::my-s3-bucket",
      "arn:aws:s3:::my-s3-bucket/*"
    ],
    "Condition": {
      "StringEquals": {
        "aws:sourceVpce": "vpce-my-mesos-cluster-vpce-id"
      }
    },
    "Principal": "*"
  }]
}

您还需要一个 VPCE 配置,为您提供一个 VPCE ID 以插入上述 S3 存储桶条件。 (我想如果您不使用 VPC 端点,您可以只匹配 VPC id?)

您可以通过转到 Mesos UI(如果您使用的是 DCOS,这不是漂亮的 DCOS UI)并观察是否有您的名称的任务来检查它是否正常工作应用出现在活动任务或已完成任务列表中。

诱人的策略(还)行不通

在 S3 上托管(签名 URLs)

在这个 S3 变体中,我们没有使用基于网络的访问限制,而是对 .dockercfg 文件使用签名 URL。

Mesos 任务配置应如下所示:

{
  ...
  "uris": ["https://my-s3-bucket/.dockercfg?AWSAccessKeyId=foo&Expires=bar&Signature=baz"]
  ...
}

不幸的是,上面的 S3 签名 URL 策略 不起作用 由于 Mesos-1686 观察到任何下载的文件都准确地保留了远程文件名,包括查询字符串,导致文件名类似于“.dockercfg?AWSAccessKeyId=foo&Expires=bar&Signature=baz”。由于 Docker 客户端无法识别该文件,除非它被准确命名为“.dockercfg”,因此无法看到授权凭据。

将.dockercfg文件直接传输到每个slave

可以将 .dockercfg SCP 到每个 Mesos 从站。虽然这是一个快速修复,但它:

  • 需要提前知道所有的slave
  • 不会随着新从属添加到集群而扩展
  • 需要 SSH 访问从站,这些从站是在他们自己的 VPC 内配置的(因此他们的 IP 地址通常在 10.0.[blah] 范围内)。

如果使用像 Chef 这样的配置管理工具实现自动化,这可能会变成一种更可行的生产方法,它将 运行 在从服务器上,并将 .dockercfg 文件拉入正确的地方。

这将导致如下配置:

{
  ...
  "uris": ["file:///home/core/.dockercfg"]
  ...
}

因为 'core' 是基于 CoreOS 的 Mesos 从服务器上的默认用户,并且 .dockercfg 按照惯例应该位于想要使用 Docker.

Update:这应该是最靠谱的方法了,但是我还没找到办法。就 Marathon 而言,该应用程序仍然永远停留在 'Deploying' 阶段。

使用密钥库服务

当我们处理用户名和密码时,AWS Key Management Service(甚至极端情况下甚至是 CloudHSM)似乎应该是个好主意——但 AFAIK Mesos 对此没有内置支持,并且我们不是在处理单个变量,而是在处理一个文件。


故障排除

设置好您选择的解决方案后,您可能会发现 .dockercfg 文件正在被拉下,但您的应用程序仍停留在 'Deploying' 阶段。检查这些东西...

确保您的 .dockercfg 是 Mesos Docker 版本

的正确格式

在某些时候,'auth' 字段的格式已更改。如果您提供的 .dockercfg 与此格式不匹配,那么 docker 拉取将无提示地失败。集群从属上的 Mesos Docker 版本期望的格式是:

{
  "https://index.docker.io/v1/": {
    "auth": [base64 of the username:password],
    "email": "your_docker_registry_user@yourdomain.com"
  }
}

不要为您的应用程序使用端口 80

如果您正在尝试部署 Web 应用程序,请确保您没有使用主机端口 80 - 它没有写在文档中的任何地方,但是 Mesos Web 服务本身需要端口 80,如果您尝试使用80 对于您自己的应用程序,它将永远挂起。精明的 reader 会注意到,除其他原因外,这就是 Mesosphere“Oinker”Web 应用程序绑定到端口 0 的稍微不寻常的选择的原因。

您可以在集群中部署一个简单的 S3 代理服务,以便使用标准 Mesos 提取器从受凭据保护的 S3 存储桶中下载:github.com/adyatlov/s3proxy。不需要 HDFS 或其他机密存储。