[英]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.