带有 ALB 入口控制器的 Terraform AWS Kubernetes EKS 资源不会创建负载均衡器

Posted

技术标签:

【中文标题】带有 ALB 入口控制器的 Terraform AWS Kubernetes EKS 资源不会创建负载均衡器【英文标题】:Terraform AWS Kubernetes EKS resources with ALB Ingress Controller won't create load balancer 【发布时间】:2020-09-27 07:01:21 【问题描述】:

我一直在尝试使用 Terraform 在 AWS 上创建一个具有自我管理节点的 EKS 集群,但我无法让我的 Kubernetes Ingress 创建负载均衡器。没有错误,但没有创建负载均衡器,只是超时。

我确实首先在我的帐户中手动创建了一个负载平衡器,并验证了负载平衡器角色是否存在。当我的 Terraform 代码运行时,将访问策略 AWSElasticLoadBalancingServiceRolePolicy

我非常依赖this tutorial

tfvars:

aws_region     = "ap-southeast-1"
domain         = "*.mydomain.com"
cluster_name   = "my-tf-eks-cluster"
vpc_id         = "vpc-0d7700e26db6b3e21"
app_subnet_ids = "subnet-03c1e8c57110c92e0, subnet-0413e8bf24cb32595, subnet-047dcce0b810f0fbd"
// gateway subnet IDs

地形代码:

terraform 


provider "aws" 
 region  = var.aws_region
 version = "~> 2.8"


data "aws_acm_certificate" "default" 
  domain   = var.domain
  statuses = ["ISSUED"]


resource "kubernetes_service_account" "alb-ingress" 
  metadata 
    name = "alb-ingress-controller"
    namespace = "kube-system"
    labels = 
      "app.kubernetes.io/name" = "alb-ingress-controller"
    
  

  automount_service_account_token = true


resource "kubernetes_cluster_role" "alb-ingress" 
  metadata 
    name = "alb-ingress-controller"
    labels = 
      "app.kubernetes.io/name" = "alb-ingress-controller"
    
  

  rule 
    api_groups = ["", "extensions"]
    resources  = ["configmaps", "endpoints", "events", "ingresses", "ingresses/status", "services"]
    verbs      = ["create", "get", "list", "update", "watch", "patch"]
  

  rule 
    api_groups = ["", "extensions"]
    resources  = ["nodes", "pods", "secrets", "services", "namespaces"]
    verbs      = ["get", "list", "watch"]
  


resource "kubernetes_cluster_role_binding" "alb-ingress" 
  metadata 
    name = "alb-ingress-controller"
    labels = 
      "app.kubernetes.io/name" = "alb-ingress-controller"
    
  

  role_ref 
    api_group = "rbac.authorization.k8s.io"
    kind      = "ClusterRole"
    name      = "alb-ingress-controller"
  

  subject 
    kind      = "ServiceAccount"
    name      = "alb-ingress-controller"
    namespace = "kube-system"
  




resource "kubernetes_deployment" "alb-ingress" 
  metadata 
    name = "alb-ingress-controller"
    labels = 
      "app.kubernetes.io/name" = "alb-ingress-controller"
    
    namespace = "kube-system"
  

  spec 
    selector 
      match_labels = 
        "app.kubernetes.io/name" = "alb-ingress-controller"
      
    

    template 
      metadata 
        labels = 
          "app.kubernetes.io/name" = "alb-ingress-controller"
        
      
      spec 
        volume 
          name = kubernetes_service_account.alb-ingress.default_secret_name
          secret 
            secret_name = kubernetes_service_account.alb-ingress.default_secret_name
          
        
        container 
          # This is where you change the version when Amazon comes out with a new version of the ingress controller
          image = "docker.io/amazon/aws-alb-ingress-controller:v1.1.8"
          name  = "alb-ingress-controller"
          args = [
            "--ingress-class=alb",
            "--cluster-name=$var.cluster_name",
            "--aws-vpc-id=$var.vpc_id",
            "--aws-region=$var.aws_region"
          ]
          volume_mount 
            name       = kubernetes_service_account.alb-ingress.default_secret_name
            mount_path = "/var/run/secrets/kubernetes.io/serviceaccount"
            read_only  = true
          
        

        service_account_name = "alb-ingress-controller"

      
    
  



resource "kubernetes_ingress" "main" 
  metadata 
    name = "main-ingress"
    annotations = 
      "alb.ingress.kubernetes.io/scheme" = "internet-facing"
      "kubernetes.io/ingress.class" = "alb"
      "alb.ingress.kubernetes.io/subnets" = "$var.app_subnet_ids"
      "alb.ingress.kubernetes.io/certificate-arn" = "$data.aws_acm_certificate.default.arn"
      "alb.ingress.kubernetes.io/listen-ports" = <<JSON
[
  "HTTP": 80,
  "HTTPS": 443
]
JSON
      "alb.ingress.kubernetes.io/actions.ssl-redirect" = <<JSON

  "Type": "redirect",
  "RedirectConfig": 
    "Protocol": "HTTPS",
    "Port": "443",
    "StatusCode": "HTTP_301"
  

JSON
    
  

  spec 
    rule 
      host = "app.xactpos.com"
      http 
        path 
          backend 
            service_name = "ssl-redirect"
            service_port = "use-annotation"
          
          path = "/*"
        
        path 
          backend 
            service_name = "app-service1"
            service_port = 80
          
          path = "/service1"
        
        path 
          backend 
            service_name = "app-service2"
            service_port = 80
          
          path = "/service2"
        
      
    

    rule 
      host = "api.xactpos.com"
      http 
        path 
          backend 
            service_name = "ssl-redirect"
            service_port = "use-annotation"
          
          path = "/*"
        
        path 
          backend 
            service_name = "api-service1"
            service_port = 80
          
          path = "/service3"
        
        path 
          backend 
            service_name = "api-service2"
            service_port = 80
          
          path = "/service4"
        
      
    
  

  wait_for_load_balancer = true

【问题讨论】:

节点上是否存在`"beta.kubernetes.io/os" = "linux"`标签? 不,我会删除它并尝试它。 有更新吗? 您的“教程”链接是无效链接。你能展示你的 Ingress 配置吗? 【参考方案1】:

我绝不是 K8s 专家,但我浏览了 Terraform 代码,我认为唯一可以帮助您调试的选项似乎是 kubernetes_ingress 中的 wait_for_load_balancer 选项资源。来自documentation:

Terraform will wait for the load balancer to have at least 1 endpoint before considering the resource created.

也许在这种情况下输出会更清晰(如果由于某种原因创建失败),或者您可能会发现它为什么没有创建 LB。

【讨论】:

这个设置只会导致 ingress 创建超时,但仍然有用。 我的代码现在终于创建了负载均衡器。拥有wait_for_load_balancer = true 导致 terraform 运行永远不会完成,因为我猜它没有收到通知。【参考方案2】:

我让 kubernetes 入口指向应用程序子网而不是网关子网。我认为这是问题所在。

【讨论】:

以上是关于带有 ALB 入口控制器的 Terraform AWS Kubernetes EKS 资源不会创建负载均衡器的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Terraform 配置 EKS ALB

基于 ALB 入口控制器路径的路由

如何从 terraform 中的 EC2 实例列表中提取 ID 以在 ALB 中使用?

如何使用 kubernetes_ingress terraform 资源创建 AWS ALB?

aws_alb_listener 的 Terraform 如何在 type="forward" 的默认操作中添加多个 target_group_arn

Terraform 和 AWS:ACM 证书从未经过验证