[英]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 等服務數據。
供應商概覽:
短片
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.