在Kubernetes中注入来自Terraform的配置而不硬编码

106次阅读
没有评论

问题描述

有一个相对简单的架构:
– 使用Terraform管理的AWS DocumentDB
– 在EKS上运行的容器,由Flux (GitOps)存储库管理

容器需要访问DocumentDB,因此需要将连接字符串、凭据和CA证书传递给容器。用户的目标是在不硬编码任何“魔术字符串”的情况下实现这一点。例如,可以在Terraform中创建一个名为docdb-creds的K8s secret,并在容器中使用该secret。但这样一来,就需要在Flux存储库中知道secret的名称。而且,如果名称变了,容器在启动时会失败,而不是在“计划”阶段。

用户考虑在Terraform中管理所有的Kubernetes资源,包括部署清单,然后使用Terraform的变量系统设置环境变量。但用户读过并听说过使用Terraform来管理Kubernetes资源可能不是一个好主意,因为Kubernetes已经有了复杂的状态管理系统。用户会因方便引用变量值而在Kubernetes资源上再加一层Terraform状态管理。

还有一个想法是使用Terraform的输出模板来创建资源清单,但这样一来就需要设置一些管道来将这些文件提交到Flux存储库。

用户想知道是否有其他方法来实现这一目标?或者对于上述提出的方法,哪个是“最不邪恶”的,是否有一种更好的方式?

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1:使用Kubernetes的Secret

在Kubernetes中,Secrets是一种用于存储敏感数据的资源类型,如密码、Token、凭据等。用户可以使用Kubernetes的Secret来安全地传递连接字符串、凭据和CA证书给容器。下面是具体的步骤:

  1. 使用Terraform创建一个K8s Secret,将需要传递给容器的敏感信息存储在该Secret中。这个Secret可以包含连接字符串、凭据和CA证书。
  2. 在容器的部署清单中引用这个Secret,将Secret中的数据注入到容器的环境变量或挂载到容器的文件系统。

下面是一个示例Terraform代码,演示如何创建一个K8s Secret并在Flux存储库中使用它:

resource "kubernetes_secret" "docdb_creds" {
  metadata {
    name = "docdb-creds"
  }
  data = {
    connection_string = base64encode("your_connection_string")
    credentials = base64encode("your_credentials")
    ca_cert = base64encode("your_ca_cert")
  }
}

# 在Flux存储库中使用这个Secret
# 将该Secret注入到容器的环境变量或挂载到文件系统

使用Kubernetes的Secret可以保持敏感数据的安全性,并且在Flux存储库中只需要引用Secret的名称,不需要暴露实际的连接字符串、凭据和CA证书。

方案2:使用Terraform的输出模板和GitOps流程

另一种方法是使用Terraform的输出模板功能,将生成的资源清单文件提交到Flux存储库。这样,不需要硬编码连接字符串、凭据和CA证书,而是在Terraform中生成资源清单文件,并通过GitOps流程自动同步到Kubernetes集群。下面是具体的步骤:

  1. 在Terraform中定义资源(如Deployment、ConfigMap等)和需要注入的变量。
  2. 使用Terraform的输出模板功能,将生成的资源清单文件输出为YAML文件。
  3. 将生成的YAML文件提交到Flux存储库,并配置GitOps流程来同步这些资源到Kubernetes集群。

这样做的好处是可以将资源清单的生成和同步过程与GitOps流程集成,确保资源清单与实际部署保持一致。

综合考虑,使用Kubernetes的Secret是一个较为安全且可维护的方式,可以满足用户的需求。使用Terraform的输出模板和GitOps流程也是一个不错的选择,但需要额外的流程和工具来管理资源清单的生成和同步。具体选择取决于用户的偏好和项目要求。

请注意,无论选择哪种方案,都需要在实际环境中测试以确保配置的正确性和安全性。

正文完