Deploy Istio and Kiali on Kubernetes using Terraform
In this post, we will deploy Istio and Kiali on Kubernetes using Terraform. We will use the official Helm charts for Istio and Kiali. This post isn’t intended to be a deep dive into Istio or Kiali, but rather a quick guide to get you started with Istio and Kiali on Kubernetes using Terraform.
Prerequisites
- A Kubernetes cluster
- Helm v3
- Terraform >v1.0.0
- kubectl
- A working instance of Prometheus and Grafana
Setup
Create a namespace for Istio
resource "kubernetes_namespace" "istio-system" {
metadata {
name = var.namespace
labels = {
istio-injection = "enabled"
}
}
}
First chart: istio-base
This first chart can be deployed as is. It will install the base components of Istio.
resource "helm_release" "istio-base" {
name = "istio-base"
namespace = var.namespace
create_namespace = false
repository = "https://istio-release.storage.googleapis.com/charts"
chart = "base"
version = "1.22.2"
depends_on = [kubernetes_namespace.istio-system]
}
Second chart: istiod
This chart requires some configuration:
- We need to set the futur uri of the zipkin endpoint of our Jaeger instance.
- If needed, we can define the number of proxies before the traffic will reach our istio gateway.
- We can configure some extra options to the sidecar that will intercept our Pods traffic.
- We can configure the behavior of traffic aimed at external resources.
- And more.
locals {
istiod_values_yaml = <<EOF
meshConfig:
defaultConfig:
tracing:
zipkin:
address: "jaeger-collector.istio-system:9411"
# address: "zipkin.istio-system:9411"
sampling: 100.0
gatewayTopology:
proxyProtocol: {}
numTrustedProxies: 2
proxyMetadata:
# Enable basic DNS proxying
ISTIO_META_DNS_CAPTURE: "true"
# Enable automatic address allocation, optional
ISTIO_META_DNS_AUTO_ALLOCATE: "true"
outboundTrafficPolicy:
mode: REGISTRY_ONLY
EOF
}
resource "helm_release" "istio-istiod" {
name = "istio-istiod"
namespace = var.namespace
create_namespace = false
repository = "https://istio-release.storage.googleapis.com/charts"
chart = "istiod"
version = "1.22.2"
values = [local.istiod_values_yaml]
depends_on = [helm_release.istio-base]
}
Third chart: istio-ingress
This chart will deploy the Istio Ingress Gateway. We can configure the annotations that will be applied to our LoadBalancer resources, the Pods annotations (for monitoring by example) as well as the protocol to use (PROXY2 in my case). Labels are also set: they will be used by Istio and Kiali later to find our resources.
locals {
istio_ingress_values_yaml = <<EOF
name: istio-ingressgateway
service:
annotations:
service.beta.kubernetes.io/scw-loadbalancer-use-hostname: "true"
service.beta.kubernetes.io/scw-loadbalancer-proxy-protocol-v2: "true"
podAnnotations:
# Keep original labels
prometheus.io/port: "15020"
prometheus.io/scrape: "true"
prometheus.io/path: "/stats/prometheus"
inject.istio.io/templates: "gateway"
sidecar.istio.io/inject: "true"
# Needed for PROXY v2 protocol
proxy.istio.io/config: '{"gatewayTopology" : { "proxyProtocol": {} }}'
labels:
app: istio-ingressgateway
istio: ingressgateway
EOF
}
resource "helm_release" "istio-ingress" {
name = "istio-ingress"
namespace = var.namespace
create_namespace = false
repository = "https://istio-release.storage.googleapis.com/charts"
chart = "gateway"
version = "1.22.2"
values = [local.istio_ingress_values_yaml]
depends_on = [helm_release.istio-base, helm_release.istio-istiod]
}
Fourth chart: jaeger
to coller network traces
locals {
jaeger_values_yaml = <<EOF
provisionDataStore:
cassandra: false
allInOne:
enabled: true
storage:
type: memory
agent:
enabled: false
collector:
enabled: false
query:
enabled: false
EOF
}
resource "helm_release" "jaeger" {
name = "jaeger"
namespace = var.namespace
create_namespace = true
repository = "https://jaegertracing.github.io/helm-charts"
chart = "jaeger"
version = "3.1.0"
values = [local.jaeger_values_yaml]
}
Last chart: kiali
resource "helm_release" "istio-kiali" {
name = "kiali-server"
namespace = var.namespace
create_namespace = true
repository = "https://kiali.org/helm-charts"
chart = "kiali-server"
version = "1.85.0"
# set {
# name = "auth.strategy"
# value = "anonymous"
# }
# set {
# name = "deployment.view_only_mode"
# value = true
# }
set {
name = "external_services.istio.root_namespace"
value = "istio-system"
}
# Prometheus
set {
name = "external_services.prometheus.url"
value = "http://prometheus-operated.prometheus:9090"
}
# Grafana
set {
name = "external_services.grafana.enabled"
value = true
}
set {
name = "external_services.grafana.in_cluster_url"
value = "http://prometheus-grafana.prometheus"
}
set {
name = "external_services.grafana.url"
value = "https://metrics.delta.home-labs.fr/"
}
# Tracing w/ Jaeger
set {
name = "external_services.tracing.enabled"
value = true
}
set {
name = "external_services.tracing.in_cluster_url"
value = "http://jaeger-query.istio-system.svc.cluster.local:16685/jaeger"
}
set {
name = "external_services.tracing.use_grpc"
value = true
}
# Labels
set {
name = "istio_labels.app_label_name"
value = "app.kubernetes.io/instance"
}
set {
name = "istio_labels.version_label_name"
value = "app.kubernetes.io/version"
}
depends_on = [helm_release.istio-base, helm_release.istio-istiod]
}
Conclusion
This is a simple way to deploy Istio and Kiali on Kubernetes using Terraform and a good starting point to get you up and running with Istio and Kiali on Kubernetes for testing and validation. You can now explore the features of Istio and Kiali and start using them in your projects.