1

我正在努力寻找将秘密配置数据传递给我的 Node.Js 应用程序的最佳方式。

问题是我需要它在我的本地机器上运行,在 CI 环境中进行测试和登台,以及在生产 (AWS) 上运行。

我正在考虑使用此处描述的 docker 机密: https ://medium.com/better-programming/how-to-handle-docker-secrets-in-node-js-3aa04d5bf46e

问题在于,它仅在您将 Docker 作为服务(通过 Swarm)运行时才有效,我可以在本地执行此操作,但不能在 AWS ECS 和 CI 上执行。(或者我在那里遗漏了什么?)

然后我也可以使用 Amazon 机密,但我如何在我的 CI 环境和本地环境中获取它们?或者如果我没有互联网?

有没有一种方法可以制作一个单独的文件或者我可以在每个环境中使用的东西,无论它是我的本地文件docker run还是CI一个或AWS ECS一个?

4

2 回答 2

1

有没有办法制作一个单独的文件或者我可以用于每个环境的东西,无论它是通过 docker run 运行的本地文件还是 CI 文件或 AWS ECS 文件?或者如果我没有互联网?

无互联网为目标的 N-Environment很难在 AWS 服务上进行中继以保密,例如存储参数等。

我可以建议的是使用dot env这将是环境独立的,所有你需要处理来自不同来源的不同环境,例如

  • 在 AWS 上的暂存和生产上运行时从 s3 拉取
  • 在开发机器上工作时绑定本地 .env 以处理无互联网情况
  • 从 s3 拉取或为 CI 生成动态点环境

因此,处理这个每个环境都会消耗适当的 Dot ENV 文件,您可以在Docker 入口点添加逻辑。

#!/bin/sh

if [ "${NODE_ENV}" == "production" ];then
   # in production we are in aws and we can pull dot env file from s3
   aws s3 cp s3://mybucket/production/.env /app/.env
elif [ "${NODE_ENV}" == "staging" ];then
   # in staging we also assume that we are in aws and we can pull dot env file from s3
   aws s3 cp s3://mybucket/staging/.env /app/.env
elif [ "${NODE_ENV}" == "ci" ];then 
   # generate dynamic ENV or pull from s3
   aws s3 cp s3://mybucket/ci/.env
else 
   echo "running against local env, please dot env file like docker run -it $PWD/.env:/app/.env ..."
fi
echo "Startin node application"
exec node "$@

在 s3 上启用加密,加上只有生产环境应该能够提取生产环境文件,更强大的策略将导致更安全的机制。

对于本地设置,您可以尝试

docker run -it -e NODE_ENV="local" --rm $PWD/.env:/app/.env myapp
于 2020-07-08T11:57:28.097 回答
0

将环境特定配置传递给在 Docker 容器中运行的应用程序的最常见方法是使用环境变量,正如Twelve-Factor Apps 的第三个因素所提出的那样。

有了这个,您的应用程序应该从环境变量中读取所有配置,包括秘密。

如果您在本地和 Docker 容器外部运行,您可以手动设置这些环境变量,运行将它们导出到 shell 的脚本或使用您的语言的样式助手,该助手将自动从环境文件加载环境变量并将它们公开为环境变量到您的应用程序,以便您可以使用 、 获取它们,或者您的应用程序的语言访问环境变量。dotenv process.env.FOOos.environ["FOO"]ENV['HOSTNAME']

在本地 Docker 容器中运行时,您可以避免将.env文件打包到映像中,而只需使用--env-fileto 参数docker run从环境文件中注入环境变量,或者只需手动使用--env.

当这些只是在本地访问时,您只需要确保您没有在源代码管理中存储任何机密,以便将您的.env文件或等效文件添加到您的.gitignore.

在 CI 中运行时,您需要让 CI 系统安全地存储这些秘密变量,然后在运行时注入它们。例如,在Gitlab CI中,您将在项目 CI/CD 设置中创建变量,然后将这些变量加密存储在数据库中,然后在运行时以纯文本形式透明地注入容器作为环境变量。

对于部署到 ECS,您可以将非机密配置直接存储为任务定义中的环境变量。这使得对您的 AWS 账户具有只读访问权限的任何人都可以读取环境变量,这可能不是您想要的秘密。相反,您可以在SSM Parameter StoreSecrets Manager中创建这些,然后在secrets任务定义的参数中引用这些:

AWS 文档包含这个从 Secrets Manager 获取机密的任务定义的小示例:

{
  "requiresCompatibilities": [
    "EC2"
  ],
  "networkMode": "awsvpc",
  "containerDefinitions": [
    {
      "name": "web",
      "image": "httpd",
      "memory": 128,
      "essential": true,
      "portMappings": [
        {
          "containerPort": 80,
          "protocol": "tcp"
        }
      ],
      "logConfiguration": {
        "logDriver": "splunk",
        "options": {
          "splunk-url": "https://sample.splunk.com:8080"
        },
        "secretOptions": [
          {
            "name": "splunk-token",
            "valueFrom": "arn:aws:secretsmanager:us-east-1:awsExampleAccountID:secret:awsExampleParameter"
          }
        ]
      },
      "secrets": [
        {
          "name": "DATABASE_PASSWORD",
          "valueFrom": "arn:aws:ssm:us-east-1:awsExampleAccountID:parameter/awsExampleParameter"
        }
      ]
    }
  ],
  "executionRoleArn": "arn:aws:iam::awsExampleAccountID:role/awsExampleRoleName"
}
于 2020-07-08T13:29:09.453 回答