terraform输出Google Kubernetes集群入口负载均衡器ip

时间:2018-07-24 19:26:36

标签: kubernetes google-cloud-platform kubernetes-ingress

我设法使用terraform自动化kubernetes集群部署。启用集群后,terraform还使用预配置(使用local-exec运行.sh脚本)将我的应用程序部署到集群。我还在集群中添加了入口,一旦创建,我就需要获取入口负载均衡器IP。更好的选择是terraform输出。 我现在得到的方式是在脚本末尾运行这部分代码

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}"
}

3 个答案:

答案 0 :(得分:0)

一个漫长的星期六之后,我终于找到了解决该问题的方法。我遇到了几乎相同的问题,因此这是我的解决方案,肯定可以改进。

我分为两个部分:

1.-我将使用local-exec运行脚本,以解决在负载LoadBalancer中等待有效IP的问题   2 .- Terraform ,使用外部数据源调用以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}'

希望有帮助。至少我已经解决了我的问题。 enter image description here

答案 1 :(得分:0)

这可以做到,仅以这种方式使用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}"
}

答案 2 :(得分:0)

我已经设法以完全声明的方式获取外部入口ip。它基于包括azurerm,kubernetes,helm在内的不同提供程序。我的目标是Azure Kubernetes Service,但该解决方案与云无关。

解决方案说明:

创建入口后,使用kubernetes提供程序连接集群。 Kubernetes提供的功能允许读取服务数据,例如外部ip。

提供商概述:

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

简短代码段

data <- read.table(text = 'my data', sep = ";")
dim(data)
library(tm)
documents <- Corpus(VectorSource(data$V2))
inspect(documents)

lapply(documents[1],as.character)
inspect(documents)

set.seed(1234)

tdm <- TermDocumentMatrix(documents)
m <- as.matrix(tdm)
v <- sort(rowSums(m),decreasing=TRUE)
d <- data.frame(word = names(v), freq = v)
d$word=rownames(d)

library("wordcloud2")
wordcloud2(d)

完整代码段

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
}