如何在 Fargate 容器中启动 rails 控制台
How to launch a rails console in a Fargate container
我想在 Fargate 容器中打开一个 Rails 控制台来与我的生产安装进行交互
然而,在网上搜索并在 AWS 论坛上发帖后,我找不到这个问题的答案
有人知道我该怎么做吗?这似乎是在任何生产环境中都必须具备的东西,并且没有简单的方法来做到这一点对于像 AWS 这样受人尊敬的云提供商来说有点令人惊讶
谢谢
我没有在 Fargate 上试过这个,但是你应该可以创建一个 fargate task,其中的命令是 rails console
.
那么如果您 configure the task as interactive
,您应该能够启动交互式容器并通过标准输入访问控制台。
当您使用 ECS 的 Fargate 执行类型时,您无法通过 ssh 连接到底层主机。这意味着您不能 docker 执行到 运行 容器中。
在尝试了很多东西之后,我找到了一种方法来打开一个指向我的生产环境的 Rails 控制台,所以我会 post 它在这里以防有人遇到同样的问题
总而言之,我添加了一个 rails 应用程序,该应用程序部署在连接到 RDS postgres 数据库的 Fargate 上
我所做的是为托管我的 Rails 应用程序和我的 RDS 数据库的 VPC 创建一个 VPN 客户端端点
然后在连接到此 VPN 后,我只需 运行 我的 rails 生产容器(具有相同的环境变量)覆盖容器命令到 运行 控制台启动脚本( bundle exec rails c production
)
在我的本地机器上 运行 我通常可以将 TTY 附加到这个容器并访问我的生产控制台
我认为这个解决方案很好,因为它允许任何从事该项目的开发人员打开控制台而不产生任何费用,并且 AWS 端完善的安全策略确保控制台访问是安全的,而且您不不必在 VPC 之外公开您的数据库
希望这对某人有所帮助
做任何类型的 docker exec
对 ECS 和 Fargate 来说都是一场噩梦。这使得 shell 或迁移之类的事情变得非常困难。
幸运的是,ECS 上的 Fargate 任务实际上只是一个 AWS 服务器 运行 一些超级定制的 docker run
命令。因此,如果您在 EC2 或本地计算机上有 docker
、jq
和 AWS CLI,您可以自己伪造其中一些 docker run
命令并输入 bash shell。我为 Django 这样做,所以我可以 运行 迁移并输入 python shell,但我假设它对于 rails(或您需要的任何其他容器)是相同的bash 中)
请注意,这仅在您一次只关心任务定义中阐明的 1 个容器时才有效 运行ning,尽管我想您可以轻松地偷工减料一些更复杂的东西。
为此,需要使用与您的 fargate 任务相同的 IAM 权限登录 AWS CLI。您可以在本地执行此操作,方法是使用 aws configure
并为具有正确 IAM 权限的用户提供凭据,或者启动一个 EC2 实例,该实例具有具有相同权限的角色,或者(为了简单起见)你的 fargate 任务是 运行ning 和一个具有相同访问权限的安全组(加上允许你通过 SSH 进入堡垒主机的规则。)我喜欢 EC2 路由,因为通过 public 互联网和一个VPN 很慢。此外,您始终保证拥有与您的任务相同的 IAM 访问权限。
您还需要与您的 fargate 任务位于同一子网上,这通常可以通过 VPN 完成,或者通过 运行在您内部的堡垒 EC2 主机上使用此代码私有子网。
在我的例子中,我将我的配置参数作为 SecureStrings 存储在 AWS Systems Manager Parameter Store 中,并使用 ECS 任务定义将它们传递进来。这些可以很容易地获取并使用
设置为本地环境变量
export DATABASE_URL=$(aws ssm get-parameter --region $REGION \
--with-decryption --name parameter.name.database_url \
| jq '.Parameter["Value"]' -r)
我将容器存储在 ECR 上,因此我需要将本地 docker 容器登录到 ECR
eval $(aws ecr get-login --no-include-email --region $REGION)
那么这只是 运行 一个交互式 docker 容器的情况,它传入 DATABASE_URL,从 ECR 中提取正确的图像,然后输入 bash。我还公开了端口 8000,这样我就可以 运行 shell 内的网络服务器,但这是可选的。
docker run -i -t \
-e DATABASE_URL \
-p 8000:8000 \
$ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$DOCKER_REPO_NAME:$TAG \
/bin/bash
一旦你 运行 你应该看到你的副本 docker 从你的容器存储库下载图像然后将你启动到 bash (假设 bash 安装在里面你的容器。)Docker 有一个非常可靠的缓存,所以第一次下载和启动需要一些时间,但之后应该会很快。
这是我的完整脚本
#!/bin/bash
REGION=${REGION:-us-west-2}
ENVIRONMENT=${ENVIRONMENT:-staging}
DOCKER_REPO_NAME=${DOCKER_REPO_NAME:-reponame}
TAG=${TAG:-latest}
ACCOUNT_ID=$(aws sts get-caller-identity | jq -r ".Account")
export DATABASE_URL=$(aws ssm get-parameter --region $REGION \
--with-decryption --name projectname.$ENVIRONMENT.database_url \
| jq '.Parameter["Value"]' -r)
eval $(aws ecr get-login --no-include-email --region $REGION)
IMAGE=$ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$DOCKER_REPO_NAME:$TAG
docker run -i -t \
-e DATABASE_URL \
-p 8000:8000 \
$IMAGE \
/bin/bash
好的,所以我最终做的事情有点不同。我没有尝试 运行 Fargate 上的控制台,而是 运行 我本地主机上的一个控制台,但将其配置为使用 RAILS_ENV='production'
并让它使用我的 RDS 实例。
当然,要使这项工作正常进行,您必须通过安全组中的出口规则公开您的 RDS 实例。明智的做法是将其配置为仅允许您的本地 IP,以使其更加安全。
docker-compose.yml 看起来像这样:
version: '3'
web:
stdin_open: true
tty: true
build: .
volumes:
- ./rails/.:/your-app
ports:
- "3000:3000"
environment: &env_vars
RAILS_ENV: 'production'
PORT: '8080'
RAILS_LOG_TO_STDOUT: 'true'
RAILS_SERVE_STATIC_FILES: 'true'
DATABASE_URL: 'postgresql://username:password@yours-aws-rds-instance:5432/your-db'
当您然后 运行 docker-compose run web rails c
它使用您的本地 Rails 代码库,但对您的 RDS 数据库进行实时更改(您想要访问 rails 控制台)。
[2021 年更新]:现在可以 运行 与 AWS Fargate 交互模式下的命令!
运行的命令是:
aws ecs execute-command \
--cluster cluster-name \
--task task-id \
--container container-name \ # optional
--interactive \
--command "rails c"
疑难解答:
查看 AWS 文档以获得 IAM 权限:https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-exec.html#ecs-exec-prerequisites
我想在 Fargate 容器中打开一个 Rails 控制台来与我的生产安装进行交互
然而,在网上搜索并在 AWS 论坛上发帖后,我找不到这个问题的答案
有人知道我该怎么做吗?这似乎是在任何生产环境中都必须具备的东西,并且没有简单的方法来做到这一点对于像 AWS 这样受人尊敬的云提供商来说有点令人惊讶
谢谢
我没有在 Fargate 上试过这个,但是你应该可以创建一个 fargate task,其中的命令是 rails console
.
那么如果您 configure the task as interactive
,您应该能够启动交互式容器并通过标准输入访问控制台。
当您使用 ECS 的 Fargate 执行类型时,您无法通过 ssh 连接到底层主机。这意味着您不能 docker 执行到 运行 容器中。
在尝试了很多东西之后,我找到了一种方法来打开一个指向我的生产环境的 Rails 控制台,所以我会 post 它在这里以防有人遇到同样的问题
总而言之,我添加了一个 rails 应用程序,该应用程序部署在连接到 RDS postgres 数据库的 Fargate 上
我所做的是为托管我的 Rails 应用程序和我的 RDS 数据库的 VPC 创建一个 VPN 客户端端点
然后在连接到此 VPN 后,我只需 运行 我的 rails 生产容器(具有相同的环境变量)覆盖容器命令到 运行 控制台启动脚本( bundle exec rails c production
)
在我的本地机器上 运行 我通常可以将 TTY 附加到这个容器并访问我的生产控制台
我认为这个解决方案很好,因为它允许任何从事该项目的开发人员打开控制台而不产生任何费用,并且 AWS 端完善的安全策略确保控制台访问是安全的,而且您不不必在 VPC 之外公开您的数据库
希望这对某人有所帮助
做任何类型的 docker exec
对 ECS 和 Fargate 来说都是一场噩梦。这使得 shell 或迁移之类的事情变得非常困难。
幸运的是,ECS 上的 Fargate 任务实际上只是一个 AWS 服务器 运行 一些超级定制的 docker run
命令。因此,如果您在 EC2 或本地计算机上有 docker
、jq
和 AWS CLI,您可以自己伪造其中一些 docker run
命令并输入 bash shell。我为 Django 这样做,所以我可以 运行 迁移并输入 python shell,但我假设它对于 rails(或您需要的任何其他容器)是相同的bash 中)
请注意,这仅在您一次只关心任务定义中阐明的 1 个容器时才有效 运行ning,尽管我想您可以轻松地偷工减料一些更复杂的东西。
为此,需要使用与您的 fargate 任务相同的 IAM 权限登录 AWS CLI。您可以在本地执行此操作,方法是使用 aws configure
并为具有正确 IAM 权限的用户提供凭据,或者启动一个 EC2 实例,该实例具有具有相同权限的角色,或者(为了简单起见)你的 fargate 任务是 运行ning 和一个具有相同访问权限的安全组(加上允许你通过 SSH 进入堡垒主机的规则。)我喜欢 EC2 路由,因为通过 public 互联网和一个VPN 很慢。此外,您始终保证拥有与您的任务相同的 IAM 访问权限。
您还需要与您的 fargate 任务位于同一子网上,这通常可以通过 VPN 完成,或者通过 运行在您内部的堡垒 EC2 主机上使用此代码私有子网。
在我的例子中,我将我的配置参数作为 SecureStrings 存储在 AWS Systems Manager Parameter Store 中,并使用 ECS 任务定义将它们传递进来。这些可以很容易地获取并使用
设置为本地环境变量export DATABASE_URL=$(aws ssm get-parameter --region $REGION \
--with-decryption --name parameter.name.database_url \
| jq '.Parameter["Value"]' -r)
我将容器存储在 ECR 上,因此我需要将本地 docker 容器登录到 ECR
eval $(aws ecr get-login --no-include-email --region $REGION)
那么这只是 运行 一个交互式 docker 容器的情况,它传入 DATABASE_URL,从 ECR 中提取正确的图像,然后输入 bash。我还公开了端口 8000,这样我就可以 运行 shell 内的网络服务器,但这是可选的。
docker run -i -t \
-e DATABASE_URL \
-p 8000:8000 \
$ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$DOCKER_REPO_NAME:$TAG \
/bin/bash
一旦你 运行 你应该看到你的副本 docker 从你的容器存储库下载图像然后将你启动到 bash (假设 bash 安装在里面你的容器。)Docker 有一个非常可靠的缓存,所以第一次下载和启动需要一些时间,但之后应该会很快。
这是我的完整脚本
#!/bin/bash
REGION=${REGION:-us-west-2}
ENVIRONMENT=${ENVIRONMENT:-staging}
DOCKER_REPO_NAME=${DOCKER_REPO_NAME:-reponame}
TAG=${TAG:-latest}
ACCOUNT_ID=$(aws sts get-caller-identity | jq -r ".Account")
export DATABASE_URL=$(aws ssm get-parameter --region $REGION \
--with-decryption --name projectname.$ENVIRONMENT.database_url \
| jq '.Parameter["Value"]' -r)
eval $(aws ecr get-login --no-include-email --region $REGION)
IMAGE=$ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$DOCKER_REPO_NAME:$TAG
docker run -i -t \
-e DATABASE_URL \
-p 8000:8000 \
$IMAGE \
/bin/bash
好的,所以我最终做的事情有点不同。我没有尝试 运行 Fargate 上的控制台,而是 运行 我本地主机上的一个控制台,但将其配置为使用 RAILS_ENV='production'
并让它使用我的 RDS 实例。
当然,要使这项工作正常进行,您必须通过安全组中的出口规则公开您的 RDS 实例。明智的做法是将其配置为仅允许您的本地 IP,以使其更加安全。
docker-compose.yml 看起来像这样:
version: '3'
web:
stdin_open: true
tty: true
build: .
volumes:
- ./rails/.:/your-app
ports:
- "3000:3000"
environment: &env_vars
RAILS_ENV: 'production'
PORT: '8080'
RAILS_LOG_TO_STDOUT: 'true'
RAILS_SERVE_STATIC_FILES: 'true'
DATABASE_URL: 'postgresql://username:password@yours-aws-rds-instance:5432/your-db'
当您然后 运行 docker-compose run web rails c
它使用您的本地 Rails 代码库,但对您的 RDS 数据库进行实时更改(您想要访问 rails 控制台)。
[2021 年更新]:现在可以 运行 与 AWS Fargate 交互模式下的命令!
运行的命令是:
aws ecs execute-command \
--cluster cluster-name \
--task task-id \
--container container-name \ # optional
--interactive \
--command "rails c"
疑难解答:
查看 AWS 文档以获得 IAM 权限:https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-exec.html#ecs-exec-prerequisites