我设法使用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}"
}
答案 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}'
答案 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。
提供商概述:
简短代码段
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
}