簡體   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