Terraform 无法创建入口(无法找到请求的资源 ingresses.extensions)

Terraform fails to create ingress (could not find the requested resource ingresses.extensions)

我在本地使用 minikube。 以下是我用来创建 kubernetes 集群的 .tf 文件:

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

resource "kubernetes_namespace" "tfs" {
  metadata {
    name = "tfs" # terraform-sandbox
  }
}

resource "kubernetes_deployment" "golang_webapp" {
  metadata {
    name      = "golang-webapp"
    namespace = "tfs"
    labels = {
      app = "webapp"
    }
  }
  spec {
    replicas = 3
    selector {
      match_labels = {
        app = "webapp"
      }
    }
    template {
      metadata {
        labels = {
          app = "webapp"
        }
      }
      spec {
        container {
          image             = "golang-docker-example"
          name              = "golang-webapp"
          image_pull_policy = "Never" # this is set so that kuberenetes wont try to download the image but use the localy built one
          liveness_probe {
            http_get {
              path = "/"
              port = 8080
            }
            initial_delay_seconds = 15
            period_seconds        = 15
          }

          readiness_probe {
            http_get {
              path = "/"
              port = 8080
            }
            initial_delay_seconds = 3
            period_seconds        = 3
          }
        }
      }
    }
  }
}


resource "kubernetes_service" "golang_webapp" {
  metadata {
    name      = "golang-webapp"
    namespace = "tfs"
    labels = {
      app = "webapp_ingress"
    }
  }
  spec {
    selector = {
      app = kubernetes_deployment.golang_webapp.metadata.0.labels.app
    }
    port {
      port        = 8080
      target_port = 8080
      protocol    = "TCP"
    }
    # type = "ClusterIP"
    type = "NodePort"
  }
}

resource "kubernetes_ingress" "main_ingress" {
  metadata {
    name      = "main-ingress"
    namespace = "tfs"
  }

  spec {
    rule {
      http {
        path {
          backend {
            service_name = "golang-webapp"
            service_port = 8080
          }
          path = "/golang-webapp"
        }
      }
    }
  }
}

执行 terraform apply 时,我能够成功创建除入口之外的所有资源。

错误是:

Error: Failed to create Ingress 'tfs/main-ingress' because: the server could not find the requested resource (post ingresses.extensions)

with kubernetes_ingress.main_ingress,
   on main.tf line 86, in resource "kubernetes_ingress" "main_ingress":
   86: resource "kubernetes_ingress" "main_ingress" {

当我尝试使用与上面相同的配置(仅在 .yaml 中并使用 kubectl apply 命令)使用 kubectl 创建入口服务时,它起作用了,所以看起来 kubectl & minikube 能够创建这种类型的入口,但 terraform 出于某种原因不能...

在此先感谢您的帮助!

编辑 1:

添加我能够创建入口的 .yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: tfs
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: golang-webapp
                port:
                  number: 8080

我认为这个问题可能与入口类名有关。可能您需要在 .tf 中明确提供它:

metadata {
    name = "example"
    annotations = {
      "kubernetes.io/ingress.class" = "nginx or your classname"
    }

或者您的集群中可能不存在 ingresses.extensions。你能提供正确执行的.yaml吗?

kubernetes_ingress 资源生成一个带有 apiVersion 的入口,您的 kubernetes 集群不支持该入口。您必须使用 [kubernetes_ingress_v1][1] 资源,它看起来类似于 kubernetes_ingress 资源,但有一些差异。对于您的示例,它将是这样的:

resource "kubernetes_ingress_v1" "jenkins-ingress" {
   metadata {
      name        = "example-ingress"
      namespace   = "tfs"
      annotations = {
        "nginx.ingress.kubernetes.io/rewrite-target" = "/"
      }
   }
   spec {
      rule {
        http {
         path {
           path = "/"
           backend {
             service {
               name = "golang-webapp"
               port {
                 number = 8080
               }
             }
           }
        }
      }
    }
  }
}

这样的东西应该有助于使用 kubernetes_ingress_v1

locals{
  ingress_rules = [
    {
      service_path = "/"
      service_name = "golang-webapp"
      service_port = 8080
    }
}

resource "kubernetes_ingress_v1" "jenkins-ingress" {

  metadata {
    annotations = var.ingress_annotations
    name        = "example-ingress"
    namespace   = "tfs"
    labels      = var.labels
  }
  spec {
    ingress_class_name = var.ingress_class_name
    rule {
      http {
        dynamic "path" {
          for_each = local.ingress_rules
          content {
            backend {
              service {
                name = path.value.service_name
                port {
                  number = path.value.service_port
                }
              }
            }
            path = path.value.service_path
          }
        }
      }
    }
    tls {
      secret_name = "tls-secret"
    }
  }
}