将 Docker 个图像从私有 Docker 注册表保存到 AWS S3 存储桶时出错

Error saving Docker images to AWS S3 bucket from private Docker Registry

我正在尝试设置私有 Docker 注册表并将图像保存到 AWS S3 实例。注册表似乎工作正常——它启动正常,我可以通过 https 对其进行身份验证。我遇到的问题是我在保存到 S3 时出错,所以我假设 S3 IAM 策略存在一些权限问题。

docker run 命令如下所示:

docker run -p 443:5000 \
  --link redis:redis \
  -e REGISTRY_STORAGE=s3 \
  -e REGISTRY_STORAGE_S3_BUCKET=my-docker-registry \
  -e REGISTRY_STORAGE_S3_ACCESSKEY=**** \
  -e REGISTRY_STORAGE_S3_SECRETKEY=**** \
  -e REGISTRY_STORAGE_S3_REGION=us-east-1 \
  -v `pwd`/auth:/auth \
  -e REGISTRY_AUTH=htpasswd \
  -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
  -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
  -v `pwd`/certs:/certs \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/my.com_chain.crt \
  -e REGISTRY_HTTP_TLS_KEY=/certs/my.com.key \
  -e REGISTRY_STORAGE_CACHE_BLOBDESCRIPTOR=redis \
  -e REGISTRY_REDIS_ADDR=redis:6379 \
  registry:2.5

S3 IAM 策略如下所示:

{
   "Version":"2012-10-17",
   "Statement":[
      {
         "Effect":"Allow",
         "Action":[
            "s3:ListAllMyBuckets"
         ],
         "Resource":"arn:aws:s3:::*"
      },
      {
         "Effect":"Allow",
         "Action":[
            "s3:ListBucket",
            "s3:GetBucketLocation"
         ],
         "Resource":"arn:aws:s3:::my-docker-registry"
      },
      {
         "Effect":"Allow",
         "Action":[
              "s3:PutObject",
              "s3:GetObject",
              "s3:DeleteObject",
              "s3:ListMultipartUploadParts",
              "s3:AbortMultipartUpload"
         ],
         "Resource":"arn:aws:s3:::my-docker-registry/*"
      }
   ]
}

错误日志条目是:

level=error msg="error resolving upload: s3aws: AccessDenied: Access Denied\n\tstatus code: 403, request id: 2B224..." auth.user.name=my-user go.version=go1.6.3 http.request.host=my.domain.com http.request.id=13b79c07-... http.request.method=PATCH http.request.remoteaddr="xx.xx.xx.xx:41392" http.request.uri="/v2/my-test/blobs/uploads/467d94ea-2a77...?_state=zQd-..." http.request.useragent="docker/1.12.0 go/go1.6.3 git-commit/8eab123 kernel/4.4.15-moby os/linux arch/amd64 UpstreamClient(Docker-Client/1.12.0 \(darwin\))" instance.id=8a8db6f1-8fe4 vars.name=my-test vars.uuid=467d94ea-2a77 version=v2.5.0

我在其他应用程序中对文件上传使用了类似的策略,所以我不确定问题出在哪里。我需要在 IAM 策略中更改什么才能允许注册表保存到 S3 存储桶?

请检查是否已将 S3 IAM 角色分配给正在使用其访问密钥的 IAM 用户。您还可以将此角色分配给 EC2 实例并避免使用此访问密钥。

我想通了 - 不确定 Docker 保存图像文件的方式是否有所改变,但您现在似乎需要将 s3:ListBucketMultipartUploads 添加到桶级权限(下面的中间块,IAM 完整显示):

{
   "Version":"2012-10-17",
   "Statement":[
      {
         "Effect":"Allow",
         "Action":[
            "s3:ListAllMyBuckets"
         ],
         "Resource":"arn:aws:s3:::*"
      },
      {
         "Effect":"Allow",
         "Action":[
            "s3:ListBucket",
            "s3:GetBucketLocation",
            "s3:ListBucketMultipartUploads"
         ],
         "Resource":"arn:aws:s3:::my-docker-registry"
      },
      {
         "Effect":"Allow",
         "Action":[
              "s3:PutObject",
              "s3:GetObject",
              "s3:DeleteObject",
              "s3:ListMultipartUploadParts",
              "s3:AbortMultipartUpload"
         ],
         "Resource":"arn:aws:s3:::my-docker-registry/*"
      }
   ]
}

现在似乎运行良好。

下一步是使用上述 docker run 参数创建一个 docker-compose 文件,向其中添加一个 redis 容器,这是一个完整的私有注册表解决方案。