[英]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个步骤:
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 secrets
和Plaintext
- 然后将您的私有注册表凭据填写为 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.