我有一个 Terraform 配置(以及其他资源),可以在 Google Cloud 上创建 Google Kubernetes Engine 集群。我使用
kubectl
提供程序为 ManagedCertificate 和 FrontendConfig 添加 YAML 清单,因为这些不是 kubernetes 或 google 提供程序的一部分。
从本地计算机应用 Terraform 配置时,这可以按预期工作,但是当我尝试在 CI 管道中执行它时,两个 kubectl_manifest
资源都出现以下错误:
Error: failed to create kubernetes rest client for read of resource: Get "http://localhost/api?timeout=32s": dial tcp 127.0.0.1:80: connect: connection refused
由于我只在 CI 期间遇到这个问题,所以我的第一个猜测是服务帐户缺少正确的范围,但据我所知,所有范围都存在。非常感谢任何建议和想法!
通过将
load_config_file = false
添加到 kubectl
提供程序配置来解决此问题。我的提供商配置现在如下所示:
data "google_client_config" "default" {}
provider "kubernetes" {
host = "https://${endpoint from GKE}"
token = data.google_client_config.default.access_token
cluster_ca_certificate = base64decode(CA certificate from GKE)
}
provider "kubectl" {
host = "https://${endpoint from GKE}"
token = data.google_client_config.default.access_token
cluster_ca_certificate = base64decode(CA certificate from GKE)
load_config_file = false
}
提供商尝试与
localhost
连接,这意味着您需要提供正确的 kube-config
文件或在 terraform 中动态设置它。
虽然你没有提到如何设置身份验证,但这里有两种方法
糟糕的方式
resource "null_resource" "deploy-app" {
provisioner "local-exec" {
interpreter = ["/bin/bash", "-c"]
command = <<EOT
kubectl apply -f myapp.yaml ./temp/kube-config.yaml;
EOT
}
# will run always, its bad
triggers = {
always_run = "${timestamp()}"
}
depends_on = [
local_file.kube_config
]
}
resource "local_file" "kube_config" {
content = var.my_kube_config # pass the config file from ci variable
filename = "${path.module}/temp/kube-config.yaml"
}
正确的方法
data "google_container_cluster" "cluster" {
name = "your_cluster_name"
}
data "google_client_config" "current" {
}
provider "kubernetes" {
host = data.google_container_cluster.cluster.endpoint
token = data.google_client_config.current.access_token
cluster_ca_certificate = base64decode(
data.google_container_cluster.cluster.master_auth[0].cluster_ca_certificate
)
}
data "kubectl_file_documents" "app_yaml" {
content = file("myapp.yaml")
}
resource "kubectl_manifest" "app_installer" {
for_each = data.kubectl_file_documents.app_yaml.manifests
yaml_body = each.value
}
如果集群在同一个模块中,那么provider应该是
provider "kubernetes" {
load_config_file = "false"
host = google_container_cluster.my_cluster.endpoint
client_certificate = google_container_cluster.my_cluster.master_auth.0.client_certificate
client_key = google_container_cluster.my_cluster.master_auth.0.client_key
cluster_ca_certificate = google_container_cluster.my_cluster.master_auth.0.cluster_ca_certificate
}