繁体   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?

我正在使用 Pulumi 进行 AWS Fargate 集群设置,我当前的程序已经成功创建了一个集群,包括。 运行可公开访问的容器映像的 Fargate 任务。 我的图像基于 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;

一切都按预期工作,但现在我需要使用私有容器映像ghcr.io/jonashackt/microservice-api-spring-boot-private:latest 切换我的代码以使用新映像,我的 Fargate 集群服务不断停止和启动新的任务/容器。 查看我的 Fargate 集群的“服务” Task选项卡并切换到“已Stopped任务”状态,我看到很多STOPPED (CannotPull...类似这样的错误:

在此处输入图像描述

如果我单击其中一个已停止的任务,我会看到以下已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

那么如何使用 Pulumi 配置对私有 Container Registry(此处为 GitHub Container Registry)的访问?

在 AWS 文档中有一个关于如何授予 ECS EC2 和 Fargate 启动类型 Tasks 访问私有 Registries的详细指南。 由此推导出有4个步骤:

  1. 获取 Token 或凭证以访问私有 Container Registry
  2. 为私有注册表创建包含令牌/凭据的 AWS Secrets Manager Secret
  3. 制作任务执行角色(使用 aws.iam.Role),其中包含用于私有 Container Registry 访问的 inlinePolicy
  4. 增强 awsx.ecs.FargateService 以在 repositoryCredentials 中使用我们的任务执行角色和秘密 ARN

0.获取Token或凭证访问私有Container Registry

如果您还没有它们,则需要在我们的私有注册表中创建访问令牌或凭据,以便外部服务能够访问它。 以 GitHub 容器注册表为例,我们需要使用read:packages scope 创建一个个人访问令牌( 请参阅此处的文档):

在此处输入图像描述


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

现在前往位于https://console.aws.amazon.com/secretsmanager/ 的 AWS Secrets Manager 控制台,并通过Store a new secret按钮创建一个新 Secret。 在 GUI 中选择Other type of secretsPlaintext - 然后将您的私有注册表凭据填写为 JSON:

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

Select Next并提供一个秘密名称,如githubContainerRegistryAccess 再次点击下一步并将Disable automatic rotation保留为默认值。 再次点击Store以创建 Secret。 最后将秘密 ARN(如arn:aws:secretsmanager:awsRegionHere:yourAccountIdHere:secret:githubContainerRegistryAccess-randomNumberHere到您的记事本或编辑器以供以后参考。


2. 制作包含用于私有容器注册表访问的 inlinePolicy 的任务执行角色(使用 aws.iam.Role)

正如文档告诉我们的那样,我们需要将访问 Secrets Manager Secret 作为内联策略的权限添加到 Fargate 任务执行角色。 现在由于new awsx.ecs.FargateService自动创建了这样一个任务执行角色,但是我们之后真的无法访问它,我们需要自己创建整个东西。 要创建aws.iam.Role ,我们可以查看有关它的 Pulumi 文档 一个 Pulumi aws.iam.Role由多个组件组成,我们需要其中 3 个:

  • assumeRolePolicy :我真的不想自己定义它,但是没有它就无法创建aws.iam.Role 选择"sts:AssumeRole"作为Action ,选择"ecs-tasks.amazonaws.com"作为服务主体至关重要。
  • inlinePolicies :该数组将采用我们的 InlinePolicy,Task 需要它来访问 Secrets Manager Secret(也就是此处创建此角色的全部要点)。 与 AWS 文档中描述的完全相同- 真正关注Resources中正确的arn名称。 两者之一正是我们的 Secrets Manager Secret ARN!
  • managedPolicyArns包含 Pulumi 附加到 Fargate 任务的默认策略(我只是查看了 AWS 控制台以找到它们的 arn)。

这是正确定义 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. 增强 awsx.ecs.FargateService 以在 repositoryCredentials 中使用我们的任务执行角色和秘密 ARN

现在这是最后一步。 我们需要使用我们创建的任务执行角色并使用executionRole参数将其附加到我们的awsx.ecs.FargateService 我们还需要将 Secrets Manager Secret ARN(再次)作为repositoryCredentials:credentialsParameter提供给我们的awsx.ecs.FargateService 这看起来像这样:

// 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,
});

现在pulumi up应该会按预期启动您的 Fargate 任务,因为它们现在能够从私有 GitHub 容器注册表中提取容器映像。 在 AWS ECS 集群视图中,您应该看到正在运行的任务:

在此处输入图像描述

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM