Kubernetes Provider 使用指南 #

Provider 配置 #

基本配置 #

hcl
terraform {
  required_providers {
    kubernetes = {
      source  = "hashicorp/kubernetes"
      version = "~> 2.0"
    }
  }
}

provider "kubernetes" {
  config_path = "~/.kube/config"
}

使用 EKS #

hcl
provider "aws" {
  region = "us-east-1"
}

data "aws_eks_cluster" "cluster" {
  name = var.cluster_name
}

data "aws_eks_cluster_auth" "cluster" {
  name = var.cluster_name
}

provider "kubernetes" {
  host                   = data.aws_eks_cluster.cluster.endpoint
  cluster_ca_certificate = base64decode(data.aws_eks_cluster.cluster.certificate_authority[0].data)
  token                  = data.aws_eks_cluster_auth.cluster.token
}

使用 AKS #

hcl
provider "azurerm" {
  features {}
}

data "azurerm_kubernetes_cluster" "cluster" {
  name                = var.cluster_name
  resource_group_name = var.resource_group_name
}

provider "kubernetes" {
  host = data.azurerm_kubernetes_cluster.cluster.kube_config[0].host
  
  client_certificate     = base64decode(data.azurerm_kubernetes_cluster.cluster.kube_config[0].client_certificate)
  client_key             = base64decode(data.azurerm_kubernetes_cluster.cluster.kube_config[0].client_key)
  cluster_ca_certificate = base64decode(data.azurerm_kubernetes_cluster.cluster.kube_config[0].cluster_ca_certificate)
}

使用 GKE #

hcl
provider "google" {
  project = var.project_id
  region  = var.region
}

data "google_container_cluster" "cluster" {
  name     = var.cluster_name
  location = var.location
}

data "google_client_config" "current" {}

provider "kubernetes" {
  host  = "https://${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
  )
}

常用资源 #

Namespace #

hcl
resource "kubernetes_namespace" "example" {
  metadata {
    name = "example-namespace"
    
    labels = {
      environment = "production"
    }
  }
}

Deployment #

hcl
resource "kubernetes_deployment" "nginx" {
  metadata {
    name      = "nginx-deployment"
    namespace = kubernetes_namespace.example.metadata[0].name
    
    labels = {
      app = "nginx"
    }
  }
  
  spec {
    replicas = 3
    
    selector {
      match_labels = {
        app = "nginx"
      }
    }
    
    template {
      metadata {
        labels = {
          app = "nginx"
        }
      }
      
      spec {
        container {
          image = "nginx:latest"
          name  = "nginx"
          
          port {
            container_port = 80
          }
          
          resources {
            limits = {
              cpu    = "500m"
              memory = "512Mi"
            }
            requests = {
              cpu    = "250m"
              memory = "256Mi"
            }
          }
          
          liveness_probe {
            http_get {
              path = "/"
              port = 80
            }
            
            initial_delay_seconds = 3
            period_seconds        = 3
          }
        }
      }
    }
  }
}

Service #

hcl
resource "kubernetes_service" "nginx" {
  metadata {
    name      = "nginx-service"
    namespace = kubernetes_namespace.example.metadata[0].name
  }
  
  spec {
    selector = {
      app = "nginx"
    }
    
    port {
      port        = 80
      target_port = 80
    }
    
    type = "LoadBalancer"
  }
}

ConfigMap #

hcl
resource "kubernetes_config_map" "example" {
  metadata {
    name      = "example-config"
    namespace = kubernetes_namespace.example.metadata[0].name
  }
  
  data = {
    "config.yaml" = <<-YAML
      apiVersion: v1
      kind: Config
      preferences: {}
      clusters:
      - cluster:
          server: https://example.com
        name: example
    YAML
  }
}

Secret #

hcl
resource "kubernetes_secret" "example" {
  metadata {
    name      = "example-secret"
    namespace = kubernetes_namespace.example.metadata[0].name
  }
  
  data = {
    username = base64encode("admin")
    password = base64encode(var.db_password)
  }
  
  type = "Opaque"
}

Ingress #

hcl
resource "kubernetes_ingress_v1" "example" {
  metadata {
    name      = "example-ingress"
    namespace = kubernetes_namespace.example.metadata[0].name
    
    annotations = {
      "kubernetes.io/ingress.class" = "nginx"
    }
  }
  
  spec {
    rule {
      host = "example.com"
      
      http {
        path {
          backend {
            service {
              name = kubernetes_service.nginx.metadata[0].name
              port {
                number = 80
              }
            }
          }
          
          path = "/"
          path_type = "Prefix"
        }
      }
    }
    
    tls {
      hosts       = ["example.com"]
      secret_name = "example-tls"
    }
  }
}

PersistentVolumeClaim #

hcl
resource "kubernetes_persistent_volume_claim" "example" {
  metadata {
    name      = "example-pvc"
    namespace = kubernetes_namespace.example.metadata[0].name
  }
  
  spec {
    access_modes = ["ReadWriteOnce"]
    
    resources {
      requests = {
        storage = "10Gi"
      }
    }
    
    storage_class_name = "standard"
  }
}

ServiceAccount #

hcl
resource "kubernetes_service_account" "example" {
  metadata {
    name      = "example-sa"
    namespace = kubernetes_namespace.example.metadata[0].name
  }
  
  automount_service_account_token = true
}

resource "kubernetes_role" "example" {
  metadata {
    name      = "example-role"
    namespace = kubernetes_namespace.example.metadata[0].name
  }
  
  rule {
    api_groups = [""]
    resources  = ["pods"]
    verbs      = ["get", "list", "watch"]
  }
}

resource "kubernetes_role_binding" "example" {
  metadata {
    name      = "example-role-binding"
    namespace = kubernetes_namespace.example.metadata[0].name
  }
  
  role_ref {
    api_group = "rbac.authorization.k8s.io"
    kind      = "Role"
    name      = kubernetes_role.example.metadata[0].name
  }
  
  subject {
    kind      = "ServiceAccount"
    name      = kubernetes_service_account.example.metadata[0].name
    namespace = kubernetes_namespace.example.metadata[0].name
  }
}

Helm Provider 集成 #

安装 Helm Provider #

hcl
terraform {
  required_providers {
    helm = {
      source  = "hashicorp/helm"
      version = "~> 2.0"
    }
  }
}

provider "helm" {
  kubernetes {
    config_path = "~/.kube/config"
  }
}

部署 Helm Chart #

hcl
resource "helm_release" "nginx_ingress" {
  name       = "nginx-ingress"
  repository = "https://kubernetes.github.io/ingress-nginx"
  chart      = "ingress-nginx"
  namespace  = "ingress-nginx"
  
  create_namespace = true
  
  set {
    name  = "controller.service.type"
    value = "LoadBalancer"
  }
  
  set {
    name  = "controller.replicaCount"
    value = "2"
  }
}

使用 values 文件 #

hcl
resource "helm_release" "prometheus" {
  name       = "prometheus"
  repository = "https://prometheus-community.github.io/helm-charts"
  chart      = "prometheus"
  namespace  = "monitoring"
  
  create_namespace = true
  
  values = [
    file("${path.module}/values/prometheus.yaml")
  ]
}

最佳实践 #

1. 使用模块 #

hcl
module "nginx" {
  source = "./modules/nginx"
  
  namespace   = kubernetes_namespace.example.metadata[0].name
  replicas    = 3
  image       = "nginx:latest"
  port        = 80
}

2. 资源依赖 #

hcl
resource "kubernetes_namespace" "example" {
  metadata {
    name = "example"
  }
}

resource "kubernetes_deployment" "nginx" {
  depends_on = [kubernetes_namespace.example]
  
  metadata {
    name      = "nginx"
    namespace = kubernetes_namespace.example.metadata[0].name
  }
}

3. 使用 locals 简化配置 #

hcl
locals {
  namespace = "production"
  
  labels = {
    environment = "production"
    managed_by  = "terraform"
  }
}

resource "kubernetes_namespace" "production" {
  metadata {
    name   = local.namespace
    labels = local.labels
  }
}

4. 敏感信息管理 #

hcl
resource "kubernetes_secret" "db_credentials" {
  metadata {
    name      = "db-credentials"
    namespace = kubernetes_namespace.example.metadata[0].name
  }
  
  data = {
    username = base64encode(var.db_username)
    password = base64encode(var.db_password)
  }
  
  type = "Opaque"
}

下一步 #

掌握了 Kubernetes Provider 后,接下来学习 项目结构,了解如何组织 Terraform 项目!

最后更新:2026-03-29