[Infrastructure as Code (IaC) Pulumi] Use Pulumi kubernetes (K8S) Helm Chart to deploy Istio

Istio

Istio is the simplify observability, traffic management, security, and policy with the leading service mesh

Istio addresses the challenges developers and operators face with a distributed or microservices architecture. Whether you’re building from scratch or migrating existing applications to cloud native, Istio can help.

This article is about how to use Pulumi, kubernetes (K8S) provider, Helm Chart and TypeScript SDK to deploy Istio within Kubernetes (K8S).

Prerequisites

Usage

Pulumi New

Create the workspace directory.

1
2
3
$ mkdir -p col-example-pulumi-typescript-istio

$ cd col-example-pulumi-typescript-istio

Pulumi login into local file system.

1
2
3
$ pulumi login file://.
Logged in to cloudolife as cloudolife (file://.)
or visit https://pulumi.com/docs/reference/install/ for manual instructions and release notes.

Pulumi new a project with kubernetes-typescript SDK.

1
$ pulumi new kubernetes-typescript

The above command will create some files within the current directory.

1
2
3
4
5
6
7
8
tree . -L 1
.
├── node_modules/
├── package.json
├── package.json.lock
├── Pulumi.dev.yaml
├── Pulumi.yaml
└── main.ts

Install js-yaml package to load and parse yaml file.

1
$ npm i js-yaml

Pulumi Configuration

Configure Kubernetes

By default, Pulumi will look for a kubeconfig file in the following locations, just like kubectl:

  • The environment variable: $KUBECONFIG,

  • Or in current user’s default kubeconfig directory: ~/.kube/config

If the kubeconfig file is not in either of these locations, Pulumi will not find it, and it will fail to authenticate against the cluster. Set one of these locations to a valid kubeconfig file, if you have not done so already.

istio/base

See and modify istio-base/main.ts file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// istio-base/index.tsmain.ts

import * as pulumi from "@pulumi/pulumi";

import * as k8s from "@pulumi/kubernetes";

const yaml = require('js-yaml');
const fs = require('fs');

const nameIstio = "istio-system"

const namespaceIstio = new k8s.core.v1.Namespace(nameIstio, {
metadata: {
name: nameIstio,
},
})

const charNameIstioBase = "istio"

const charIstio = new k8s.helm.v3.Chart(charNameIstioBase, {
chart: charNameIstioBase,
version: "1.12.1",
fetchOpts:{
repo: "https://istio-release.storage.googleapis.com/charts",
},
namespace: namespaceIstio.metadata.name,
});

istio/ingress

See and modify istio-ingress/main.ts file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// istio-ingress/index.tsmain.ts

import * as pulumi from "@pulumi/pulumi";

import * as k8s from "@pulumi/kubernetes";

const yaml = require('js-yaml');
const fs = require('fs');

const nameIstio = "istio-system"

const charNameIngress = "ingress"

const charIstio = new k8s.helm.v3.Chart(charNameIngress, {
chart: charNameIngress,
version: "1.12.1",
fetchOpts:{
repo: "https://istio-release.storage.googleapis.com/charts",
},
namespace: nameIstio,
});

values.yaml

Edit istio-ingress/values.yaml and replace content within {{ }}.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# istio-ingress/values.yaml

# istio/values.yaml at master · istio/istio
# https://github.com/istio/istio/blob/master/manifests/charts/gateway/values.yaml

name: istio-ingress-gateway # Override the name to match existing resources
labels:
# app: "" # Unset default app selector label

# Step 2: Update the Knative gateway | Configuring Knative Serving CRDs - Knative
# https://knative.dev/docs/install/operator/configuring-serving-cr/#step-2-update-the-knative-gateway
istio: istio-ingress-gateway # override default istio selector label
# foo: bar # Add the existing custom selector label

service:
loadBalancerIP: {{ .Values.service.loadBalancerIP }}

istio/istiod

See and modify istio-istiod/main.ts file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// istio-istiod/index.tsmain.ts

import * as pulumi from "@pulumi/pulumi";

import * as k8s from "@pulumi/kubernetes";

const yaml = require('js-yaml');
const fs = require('fs');

const nameIstio = "istio-system"

const charNameIstiod = "istiod"

const charIstio = new k8s.helm.v3.Chart(charNameIstiod, {
chart: charNameIstiod,
version: "1.12.1",
fetchOpts:{
repo: "https://istio-release.storage.googleapis.com/charts",
},
namespace: nameIstio,
});

Istio Stack

main.ts

Edit ./main.ts

1
2
3
4
5
6
7
// main.ts

import * from "./base";

import * from "./ingress";

import * from "./istiod";

Check all files.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
tree . -L 1
.
├── base
│ └── index.ts
├── ingress
│ ├── index.ts
│ └── values
│ └── values.yaml
├── istiod
│ └── index.ts
├── package.json
├── package.json.lock
├── Pulumi.dev.yaml
├── Pulumi.yaml
└── main.ts

Pulumi Up

Run pulumi up to create the namespace and pods.

1
$ pulumi up

See pods about istio.

1
2
3
4
5
6
7
8
$ kubectl get pods -n istio-system
NAME READY STATUS RESTARTS AGE
istiod-6cf96f5669-ptbrz 1/1 Running 1 (9h ago) 19h
kiali-7846c465b6-5j4r5 1/1 Running 0 114m

$ kubectl get pods -n istio-ingress
NAME READY STATUS RESTARTS AGE
istio-ingress-gateway-6756cd7dd8-4vt8n 1/1 Running 1 (9h ago) 19h

Assume you have determined that your environment has an external load balancer 192.168.100.120.

1
2
3
4
kubectl get svc -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.233.14.112 192.168.100.120 15021:32391/TCP,80:31770/TCP,443:31311/TCP 18h
istiod ClusterIP 10.233.54.109 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 18h 118m

Pulumi Destroy

Destroy all resources created by Pulumi.

1
$ pulumi destroy

References

[1] istio/istio: Connect, secure, control, and observe services. - https://github.com/istio/istio

[2] Istio - https://istio.io/latest/

[3] Istio / Install with Helm - https://istio.io/latest/docs/setup/install/helm/

[4] Istio / Getting Started - https://istio.io/latest/docs/setup/getting-started/

[5] Istio / Install with Istioctl - https://istio.io/latest/docs/setup/install/istioctl/

[6] Kubernetes Getting Started | Pulumi - https://www.pulumi.com/docs/get-started/kubernetes/

[7] Pulumi - Modern Infrastructure as Code - https://www.pulumi.com/

[8] Kubernetes - https://kubernetes.io/

[9] TypeScript: Typed JavaScript at Any Scale. - https://www.typescriptlang.org/

[10] Helm - https://helm.sh/