简体   繁体   English

如何使用 Pulumi 配置 AWS ECS Fargate 任务/集群以访问私有 Docker 容器注册表(如 GitHub 容器注册表)?

[英]How to configure AWS ECS Fargate Tasks/Cluster to access private Docker Container Registry (like GitHub Container Registry) with Pulumi?

I'am working on a AWS Fargate Cluster setup with Pulumi and my current program already successfully creates a Cluster incl.我正在使用 Pulumi 进行 AWS Fargate 集群设置,我当前的程序已经成功创建了一个集群,包括。 Fargate Tasks that run a public accessible container image.运行可公开访问的容器映像的 Fargate 任务。 My image is based on Spring Boot ( project code on GitHub ):我的图像基于 Spring 引导(GitHub 上的项目代码):

import * as awsx from "@pulumi/awsx";

// Spring Boot Apps port
const port = 8098;

// Create a ApplicationLoadBalancer to listen for requests and route them to the container.
const alb = new awsx.lb.ApplicationLoadBalancer("fargateAlb");

const albTargetGroup = alb.createTargetGroup("fargateAlbTargetGroup", {
    port: port,
    protocol: "HTTP",
    healthCheck: {
        // Use the default spring-boot-actuator health endpoint
        path: "/actuator/health"
    }
});

const albListener = albTargetGroup.createListener("fargateAlbListener", { port: port, protocol: "HTTP" });

// Define Container image published to the GitHub Container Registry
const service = new awsx.ecs.FargateService("microservice-api-spring-boot", {
    taskDefinitionArgs: {
        containers: {
            microservice_api_spring_boot: {
                image: "ghcr.io/jonashackt/microservice-api-spring-boot:latest",
                memory: 768,
                portMappings: [ albListener ]
            },
        },
    },
    desiredCount: 2,
});

// Export the URL so we can easily access it.
export const apiUrl = albListener.endpoint.hostname;

Everything works as expected, but now I need to use a private container image ghcr.io/jonashackt/microservice-api-spring-boot-private:latest instead.一切都按预期工作,但现在我需要使用私有容器映像ghcr.io/jonashackt/microservice-api-spring-boot-private:latest Switching my code to use the new image, my Fargate Cluster Service keeps stopping and starting new Tasks/Containers endlessly.切换我的代码以使用新映像,我的 Fargate 集群服务不断停止和启动新的任务/容器。 Looking into my Fargate Cluster's Service' Task tab and switching to the Stopped Task status I see lot's of STOPPED (CannotPull... errors like this:查看我的 Fargate 集群的“服务” Task选项卡并切换到“已Stopped任务”状态,我看到很多STOPPED (CannotPull...类似这样的错误:

在此处输入图像描述

If I click into one of the stopped Tasks I see the following Stopped reason :如果我单击其中一个已停止的任务,我会看到以下已Stopped reason

CannotPullContainerError: inspect image has been retried 1 time(s): failed to resolve ref "ghcr.io/jonashackt/microservice-api-spring-boot-private:latest": failed to authorize: failed to fetch anonymous token: unexpected status: 401 Unauthorized

So how can I configure access to a private Container Registry (here GitHub Container Registry) using Pulumi?那么如何使用 Pulumi 配置对私有 Container Registry(此处为 GitHub Container Registry)的访问?

In the AWS docs there's a detailed guide on how to grant ECS EC2 & Fargate launch type Tasks access to private Registries .在 AWS 文档中有一个关于如何授予 ECS EC2 和 Fargate 启动类型 Tasks 访问私有 Registries的详细指南。 Derived from that there are 4 steps to take:由此推导出有4个步骤:

  1. Obtain Token or credentials to access private Container Registry获取 Token 或凭证以访问私有 Container Registry
  2. Create AWS Secrets Manager Secret containing Token/Creds to private Registry为私有注册表创建包含令牌/凭据的 AWS Secrets Manager Secret
  3. Craft Task Execution Role (using aws.iam.Role) containing inlinePolicy for private Container Registry access制作任务执行角色(使用 aws.iam.Role),其中包含用于私有 Container Registry 访问的 inlinePolicy
  4. Enhance awsx.ecs.FargateService to use our Task Execution Role & Secret ARN in repositoryCredentials增强 awsx.ecs.FargateService 以在 repositoryCredentials 中使用我们的任务执行角色和秘密 ARN

0. Obtain Token or credentials to access private Container Registry 0.获取Token或凭证访问私有Container Registry

If you don't already have them, you'll need to create an Access Token or credentials inside our private Registry so that an external service is able to access it.如果您还没有它们,则需要在我们的私有注册表中创建访问令牌或凭据,以便外部服务能够访问它。 With GitHub Container Registry for example we need to create a Personal Access Token ( see docs here ) using the read:packages scope as a minimum:以 GitHub 容器注册表为例,我们需要使用read:packages scope 创建一个个人访问令牌( 请参阅此处的文档):

在此处输入图像描述


1. Create AWS Secrets Manager Secret containing Token/Creds to private Registry 1. 创建 AWS Secrets Manager Secret 包含 Token/Creds 到私有 Registry

Now head over to the AWS Secrets Manager console at https://console.aws.amazon.com/secretsmanager/ and create a new Secret via the Store a new secret button.现在前往位于https://console.aws.amazon.com/secretsmanager/ 的 AWS Secrets Manager 控制台,并通过Store a new secret按钮创建一个新 Secret。 In the GUI choose Other type of secrets and Plaintext - and then fill in your private Registry credentials as JSON:在 GUI 中选择Other type of secretsPlaintext - 然后将您的私有注册表凭据填写为 JSON:

{
  "username": "yourGitHubUserNameHere",
  "password": "yourGitHubPATHere"
}

Select Next and provide a Secret Name like githubContainerRegistryAccess . Select Next并提供一个秘密名称,如githubContainerRegistryAccess Hit Next again and leave Disable automatic rotation as the default.再次点击下一步并将Disable automatic rotation保留为默认值。 Next again and hit Store to create the Secret.再次点击Store以创建 Secret。 Finally copy the Secret ARN like arn:aws:secretsmanager:awsRegionHere:yourAccountIdHere:secret:githubContainerRegistryAccess-randomNumberHere to your notepad or editor for later reference.最后将秘密 ARN(如arn:aws:secretsmanager:awsRegionHere:yourAccountIdHere:secret:githubContainerRegistryAccess-randomNumberHere到您的记事本或编辑器以供以后参考。


2. Craft Task Execution Role (using aws.iam.Role) containing inlinePolicy for private Container Registry access 2. 制作包含用于私有容器注册表访问的 inlinePolicy 的任务执行角色(使用 aws.iam.Role)

As the docs tell us we need to add the permission to access the Secrets Manager Secret as Inline Policy to the Fargate Tasks Execution Role. 正如文档告诉我们的那样,我们需要将访问 Secrets Manager Secret 作为内联策略的权限添加到 Fargate 任务执行角色。 Now as the new awsx.ecs.FargateService automatically creates such a Task Execution Role, but we can't access it afterwards really, we need to create the whole thing ourselves.现在由于new awsx.ecs.FargateService自动创建了这样一个任务执行角色,但是我们之后真的无法访问它,我们需要自己创建整个东西。 To create the aws.iam.Role we can have a look into the Pulumi docs about it .要创建aws.iam.Role ,我们可以查看有关它的 Pulumi 文档 A Pulumi aws.iam.Role consists of multiple components, and we need 3 of them:一个 Pulumi aws.iam.Role由多个组件组成,我们需要其中 3 个:

  • assumeRolePolicy : I didn't really wanted to define this myself, but the aws.iam.Role can't be created without it. assumeRolePolicy :我真的不想自己定义它,但是没有它就无法创建aws.iam.Role It's crucial to choose "sts:AssumeRole" as the Action and "ecs-tasks.amazonaws.com" as the Service Principal.选择"sts:AssumeRole"作为Action ,选择"ecs-tasks.amazonaws.com"作为服务主体至关重要。
  • inlinePolicies : This array will take our InlinePolicy which the Task needs to access the Secrets Manager Secret (aka the whole point of this Role creation here). inlinePolicies :该数组将采用我们的 InlinePolicy,Task 需要它来访问 Secrets Manager Secret(也就是此处创建此角色的全部要点)。 It's exactly the same as described in the AWS docs - really keep an eye on the correct arn names inside Resources .与 AWS 文档中描述的完全相同- 真正关注Resources中正确的arn名称。 One of the two is exactly our Secrets Manager Secret ARN!两者之一正是我们的 Secrets Manager Secret ARN!
  • managedPolicyArns contains the default Policies attached to a Fargate Task by Pulumi (I simply had a look into the AWS Console to find their arns). managedPolicyArns包含 Pulumi 附加到 Fargate 任务的默认策略(我只是查看了 AWS 控制台以找到它们的 arn)。

Here's the Pulumi code we need for the InlinePolicy to be defined correctly:这是正确定义 InlinePolicy 所需的 Pulumi 代码:

const taskExecutionRole = new aws.iam.Role("microservice-api-spring-boot-execution", {
    assumeRolePolicy: {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "",
                "Effect": "Allow",
                "Principal": {
                    "Service": "ecs-tasks.amazonaws.com"
                },
                "Action": "sts:AssumeRole"
            }
        ]
    }, inlinePolicies: [
        {
            name: "ghcr-secret-access",
            policy: JSON.stringify({
                Version: "2012-10-17",
                Statement: [
                    {
                        Effect: "Allow",
                        Action: [
                            "kms:Decrypt",
                            "secretsmanager:GetSecretValue"
                        ],
                        Resource: [
                            "arn:aws:secretsmanager:awsRegionHere:yourAccountIdHere:secret:githubContainerRegistryAccess-randomNumberHere",
                            "arn:aws:kms:awsRegionHere:yourAccountIdHere:key/key_id"
                        ]
                    }]
            })
        },
    ],
    managedPolicyArns: [
        "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy",
        "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
    ]
});

3. Enhance awsx.ecs.FargateService to use our Task Execution Role & Secret ARN in repositoryCredentials 3. 增强 awsx.ecs.FargateService 以在 repositoryCredentials 中使用我们的任务执行角色和秘密 ARN

Now this is the final step.现在这是最后一步。 We need to use our created Task Execution Role and attach it to our awsx.ecs.FargateService using the executionRole parameter.我们需要使用我们创建的任务执行角色并使用executionRole参数将其附加到我们的awsx.ecs.FargateService And we also need to provide our Secrets Manager Secret ARN (again) as repositoryCredentials:credentialsParameter to our awsx.ecs.FargateService . 我们还需要将 Secrets Manager Secret ARN(再次)作为repositoryCredentials:credentialsParameter提供给我们的awsx.ecs.FargateService This looks somehow like this:这看起来像这样:

// Define Container image published to the GitHub Container Registry
const service = new awsx.ecs.FargateService("microservice-api-spring-boot", { 
    taskDefinitionArgs: {
        containers: {
            blueprint_helloworld: {
                image: "ghcr.io/jonashackt/microservice-api-spring-boot-private:latest",
                memory: 768,
                portMappings: [ albListener ],
                // Access private GitHub Container Registry: we need to provide the Secret ARN as repositoryCredentials
                // see https://www.pulumi.com/docs/reference/pkg/nodejs/pulumi/awsx/ecs/#Container-repositoryCredentials
                repositoryCredentials: {
                    credentialsParameter: "arn:aws:secretsmanager:awsRegionHere:yourAccountIdHere:secret:githubContainerRegistryAccess-randomNumberHere",
                }
            },
        },
        executionRole: taskExecutionRole,
    },
    desiredCount: 2,
});

Now a pulumi up should bring up your Fargate Tasks as expected, since they're now able to pull the container images from the private GitHub Container Registry.现在pulumi up应该会按预期启动您的 Fargate 任务,因为它们现在能够从私有 GitHub 容器注册表中提取容器映像。 Inside the AWS ECS Cluster view you should see your running Tasks:在 AWS ECS 集群视图中,您应该看到正在运行的任务:

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 AWS Fargate ECS CLI撰写专用注册表 - AWS Fargate ECS CLI Compose Private Registry 在 AWS ECS 的单独账户中从私有注册表中拉取容器 - pull container from private registry in separate account in AWS ECS AWS ECS Fargate 任务陷入重启循环 - 如何使用 Pulumi 配置 LoadBalancer TargetGroup 健康检查? - AWS ECS Fargate Tasks caught in restart-loop - How to configure LoadBalancer TargetGroup health checks with Pulumi? 在AWS ECS集群中显示Docker容器日志 - Showing docker container log in aws ECS cluster 亚马逊容器注册表只有ECS? - Amazon Container Registry Only with ECS? 如何为在 AWS ECS 中运行的 Docker 容器配置“ulimits”? - How do I configure "ulimits" for a Docker container running in AWS ECS? Docker容器停止时停止AWS ECS Fargate任务 - Stopping AWS ECS Fargate task when docker container stops aws ecs优化AMI中的私有docker注册表身份验证不成功 - Private docker registry authentication in aws ecs optimized AMI is not successful 在 AWS ECS 中使用来自私有外部注册表的 docker 映像 - Use docker image from private external registry in AWS ECS 使用相同的 docker 图像在 Azure 上运行多个容器实例,就像 AWS Fargate 任务一样 - Run multiple container instances on Azure with the same docker image just like AWS Fargate tasks
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM