繁体   English   中英

terraform output Google Kubernetes 集群入口负载均衡器 Z957B527BCFBAD3E380F58ZD2068

[英]terraform output Google Kubernetes cluster inggress load balancer ip

我已经设法使用 terraform 自动化 kubernetes 集群部署。 在启动集群 terraform 后,还使用配置(running.sh 脚本与 local-exec)将我的应用程序部署到集群。 我还在向集群添加入口,我需要在创建入口负载均衡器 IP 后获取它。 首选选项是 terraform output。 我现在得到它的方式是在我的脚本末尾运行这部分代码

IP="$(kubectl get ingress appname --no-headers | awk '{print $3}')"
echo "Load Balancer IP $IP"

但是这个有它的问题,我需要在运行这个命令之前添加睡眠,以确保 IP 已经分配。 而且我不能确定增加的睡眠时间是否足够。 实际上需要这样的东西,但对于我的入口负载均衡器 IP

output "google_container_cluster_endpoint" {
  value = "${google_container_cluster.k8s.endpoint}"
}

output "google_container_cluster_master_version" {
  value = "${google_container_cluster.k8s.master_version}"
}

我已经设法以完全声明的方式获得外部入口 ip。 它基于不同的提供者,包括 azurerm、kubernetes、helm。 我的目标是 Azure Kubernetes 服务,但解决方案与云无关。

解决方案说明:

Ingress 创建后,使用 kubernetes provider 连接集群。 Kubernetes 提供允许读取外部 ip 等服务数据。

供应商概览:

  • azurerm 提供程序用于 Azure 通信
    • 可以通过不同的提供者创建 Kubernetes(K8s),
  • helm provider 用于入口安装,
    • 可以使用不同的方法创建入口,
  • kubernetes provider 允许我查询负载均衡器服务

短片

provider "kubernetes" { }

provider "helm" { }

resource "helm_release" "nginx-ingress" {
  name             = "nginx-ingress"
  namespace        = "nginx-ingress"
  create_namespace = true
  repository       = "https://kubernetes-charts.storage.googleapis.com"
  chart            = "nginx-ingress"

  set {
    name  = "controller.replicaCount"
    value = "2"
  }
}

data "kubernetes_service" "service_ingress" {
  metadata {
    name      = "nginx-ingress-controller"
    namespace = "nginx-ingress"
  }

  depends_on = [ helm_release.nginx-ingress ] 
}

output "ip" {
  value = data.kubernetes_service.service_ingress.load_balancer_ingress.0.ip
}

完整片段

variable "subscription_id" {
  type = string
}

variable "client_id" {
  type = string
}

variable "client_secret" {
  type = string
}

variable "tenant_id" {
  type = string
}

variable "resource_location"{
  type = string
}

terraform {
  required_providers {
    azurerm = {
      source = "hashicorp/azurerm"
      version = "2.29.0"
    }

    kubernetes = {
      source = "hashicorp/kubernetes"
      version = "1.13.2"
    }

    helm = {
      source = "hashicorp/helm"
      version = "1.3.1"
    }
  }
}

provider "azurerm" {
  subscription_id = var.subscription_id
  client_id       = var.client_id
  client_secret   = var.client_secret
  tenant_id       = var.tenant_id
  features {}
}

provider "kubernetes" {
  load_config_file       = "false"
  host                   = azurerm_kubernetes_cluster.aks.kube_config.0.host
  client_certificate     = base64decode(azurerm_kubernetes_cluster.aks.kube_config.0.client_certificate)
  client_key             = base64decode(azurerm_kubernetes_cluster.aks.kube_config.0.client_key)
  cluster_ca_certificate = base64decode(azurerm_kubernetes_cluster.aks.kube_config.0.cluster_ca_certificate)
}

provider "helm" {
  kubernetes {
    load_config_file       = "false"
    host                   = azurerm_kubernetes_cluster.aks.kube_config.0.host
    client_certificate     = base64decode(azurerm_kubernetes_cluster.aks.kube_config.0.client_certificate)
    client_key             = base64decode(azurerm_kubernetes_cluster.aks.kube_config.0.client_key)
    cluster_ca_certificate = base64decode(azurerm_kubernetes_cluster.aks.kube_config.0.cluster_ca_certificate)
  }
}

data "kubernetes_service" "service_ingress" {
  metadata {
    name      = "nginx-ingress-controller"
    namespace = "nginx-ingress"
  }

  depends_on = [ helm_release.nginx-ingress ] 
}

resource "azurerm_resource_group" "rg" {
  name     = "myapp"
  location = var.resource_location
}

resource "azurerm_kubernetes_cluster" "aks" {
  name                = "myapp"
  location            = var.resource_location
  resource_group_name = azurerm_resource_group.rg.name
  dns_prefix          = "myapp"
  kubernetes_version  = "1.17.11"

  default_node_pool {
    name            = "default"
    node_count      = 2
    vm_size         = "Standard_B2s"
    os_disk_size_gb = 30
    type = "VirtualMachineScaleSets"
    enable_auto_scaling = false
  }

  service_principal {
    client_id     = var.client_id
    client_secret = var.client_secret
  }

  role_based_access_control {
    enabled = true
  }
}

resource "helm_release" "nginx-ingress" {
  name             = "nginx-ingress"
  namespace        = "nginx-ingress"
  create_namespace = true
  repository       = "https://kubernetes-charts.storage.googleapis.com"
  chart            = "nginx-ingress"

  set {
    name  = "controller.replicaCount"
    value = "2"
  }

  set {
    name  = "controller.nodeSelector.kubernetes\\.io/os"
    value = "linux"
  }

  set {
    name  = "defaultBackend.nodeSelector.kubernetes\\.io/os"
    value = "linux"
  }
}

output "ip" {
  value = data.kubernetes_service.service_ingress.load_balancer_ingress.0.ip
}

经过一个漫长的星期六,我终于找到了问题的解决方案。 我遇到了几乎相同的问题,所以这是我的解决方案,肯定可以改进。

我分为两部分:

1.- 我将使用 local-exec 来运行一个脚本来解决在加载 LoadBalancer 2.- Terraform中等待有效 IP 的问题,使用外部数据源调用一个以 json 格式回答的“程序”。 我的“程序”是一个获取 IP 的 bash 脚本。 结果,我在一个变量中有我想要的数据。

我这样做是因为我不知道如何使用外部数据源调试问题,而且我正在遭受“陌生人的事情”

首先,我运行代码以等待有效的 IP。 Terraform 调用local-exec


provisioner "local-exec" {
  command = "./public-ip.sh"
  interpreter = ["/bin/bash", "-c"]
}

这是我用过的脚本


#!/bin/bash
#public-ip.sh
#!/bin/bash
# Exit if any of the intermediate steps fail
set -e

function valid_ip()
{
    local  ip=$1
    local  stat=1

    if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
        OIFS=$IFS
        IFS='.'
        ip=($ip)
        IFS=$OIFS
        [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
            && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
        stat=$?
    fi
    return $stat
}

########################
# Grab the Public IP   #
#######################
WaitingTime=0
HaveIP=NO

echo "Let's check that LoadBalancer IP..."
MyPublicIP=$(kubectl get services --all-namespaces| grep LoadBalancer | awk '{print $5}')
valid_ip $MyPublicIP && HaveIP="OK"

until [ "$HaveIP" = "OK" -o "$WaitingTime" -ge 30 ]; do
    echo "sleeeping...."
    sleep 10
    echo "Play it again Sam..."
    MyPublicIP=$(kubectl get services --all-namespaces| grep LoadBalancer | awk '{print $5}')
    #if valid_ip $MyPublicIP; then echo "We got the IP"; HaveIP=YES ;else stat='Still without IP'; fi
    #if valid_ip $MyPublicIP; then HaveIP="OK" ; fi
    valid_ip $MyPublicIP && HaveIP="OK"
    #if valid_ip $MyPublicIP; then HaveIP="OK" ; fi
    WaitingTime=$((WaitingTime+1))
    echo $WaitingTime
done
if [ "$HaveIP" = "OK" ]; then echo  An the public IP is... $MyPublicIP; else echo "WT_ has happened now!!!"; fi

在我知道我准备好 IP 之后。 我只需要抓住它。 请注意depends_on ,它控制着我将在我的资源(google_container_cluster.tests)创建后获取我的数据,而不是他想要的任何时候。 测试一下。 这很棘手...


data "external" "insights-public-ip" {
  program = ["sh", "test-jq.sh" ]
  depends_on = ["google_container_cluster.tests"]
}

output "insights-public-ip" {
  value = "${data.external.insights-public-ip.result}"
}

这是test-jq.sh (测试原因是我第一次使用 :S),我调用的脚本以 json 格式打印数据。


#!/bin/bash
#test-jq.sh
set -e
MyPublicIP=$(kubectl get services --all-namespaces | grep insights | grep LoadBalancer | awk '{print $5}')
jq -n --arg foobaz "$MyPublicIP" '{"extvar":$foobaz}'

希望能帮助到你。 至少我已经解决了我的事情。 在此处输入图片说明

这可以做到,只使用 kubectl 以这种方式:

#!/bin/bash

while true;
do
  kubectl get svc -n istio-system istio-ingressgateway -o jsonpath='{"{\"ip\": "}{"\""}{.status.loadBalancer.ingress[0].ip}{"\"}"}' | grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}" >/dev/null

  if [[ $? -eq 0 ]]; then
      kubectl get svc -n istio-system istio-ingressgateway -o jsonpath='{"{\"ip\": "}{"\""}{.status.loadBalancer.ingress[0].ip}{"\"}"}'
      exit 0
  fi
done

现在您可以编写外部数据资源的脚本,如下所示:

data "external" "external-public-ip" {
  program = ["sh", "get-ip.sh" ]
  depends_on = [kubernetes_service.foo]
}

output "external-public-ip" {
  value = "${data.external.external-public-ip.result}"
}

上面已经回答的稍微修改的版本 -

创建服务:

resource "kubernetes_service" "service" {
  metadata {
    name      = var.service_name
    namespace = var.deployment_namespace
  }
   ...
}

创建的服务的数据源:

data "kubernetes_service" "service_ingress" {
  metadata {
    name      = var.service_name
    namespace = var.deployment_namespace
  }
  depends_on = [kubernetes_service.service]
}

Output IP:

output "gke_deployment_lb_ip" {
  value       = data.kubernetes_service.service_ingress.status[0].load_balancer[0].ingress[0].ip
  description = "Deployment ALB IP"
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM