Deploying an HTTPS Website with Kubernetes, Istio, and cert-manager: Part 1

Andy
5 min readFeb 15, 2021

In this tutorial I’ll be walking you through you how to deploy an HTTPS microservice website using Kubernetes, Istio and Kubernetes cert-manager.

This is part 1 of a two-part series. The first part takes you through the Kubernetes cluster setup, installing and configuring Istio on that cluster, and deploying your first application on the cluster. In part 2 we’ll learn how to use Istio gateways, routes, and how to secure your website with Kubernetes cert-manager.

Kubernetes

Kubernetes is a program that makes multi-cluster deployments easy. It provides easy HA and redundancy. It’s the backbone of everything else here. In Kubernetes you’ll deploy “pods” which contain all the containers necessary to run the application or microservice.

Istio

Istio is a plugin to Kubernetes that makes networking simple. It provides a lot of features out of the box and is very simple to use and configure. When you install Istio, you’ll create a bunch of custom Kubernetes resources via “Custom Resource Definitions (CRD)”. More on this later.

Cert-Manager

Cert-Manager is another plugin for Kubernetes that automates the SSL/TLS certificate issuance process. Similar to Istio, it’s a CRD and we’ll discuss more about it later.

This tutorial assumes you already have kubectl installed on your local computer. If you do not, please follow these directions to install kubectl.

Getting Started

The first step to deploying a website is spinning up a Kubernetes cluster. In this tutorial we’ll be using Google Cloud Platform (GCP). First, download the google-cloud-sdk which will give you command line access to Google Cloud. Download it here.

Once installed, you’ll need to authenticate to your GCP account by running gcloud init and running through the setup process.

Your first cluster

To create your first Kubernetes cluster, simply run the following command in your terminal:

gcloud container clusters create "my-istio-https-cluster" \ 
--zone "us-central1-c" \
--num-nodes "3"

NOTE: If you receive an “ERROR: (gcloud.container.clusters.create) … should enable service:container.googleapis.com before generating a service account.” — You’ll need to log into the Google Cloud Console and enable the Kubernetes API for your project.

You should see some confirmation that your cluster is being created. This might take a few minutes.

$ gcloud container clusters create "my-istio-https-cluster" \ 
--zone "us-central1-c" \
--num-nodes "3"
Creating cluster my-istio-https-cluster in us-central1-c...
Cluster is being deployed...
Cluster is being health-checked...
Created [https://container.googleapis.com/v1/projects/my-istio-https-project/zones/us-central1-c/clusters/my-istio-https-cluster].
To inspect the contents of your cluster, go to: https://console.cloud.google.com/kubernetes/workload_/gcloud/us-central1-c/my-istio-https-cluster?project=my-istio-https-project
kubeconfig entry generated for my-istio-https-cluster.

Confirm you’ve set up your cluster by running the following command from your local terminal:

$ kubectl get pods --all-namespaces

You should see a bunch of kube-system pods running on the cluster.

Installing Istio on the cluster

Next, we need to install Istio to both your local computer and to the freshly created cluster. To do this, we’ll use helm. Helm is a package manager for Kubernetes - which means that you can run one simple command and Helm will install all the necessary Kubernetes resources for you.

First, download and install the helm binary for your system. Instructions here

While you’re downloading things, make sure to download and install Istio too. Instructions here (Just the “Download Istio” instructions for now!)

With Helm and Istio installed on your local computer, installing Istio to the cluster is as simple as running the following command:

$ istioctl install --set profile=demo

Be sure to use the demo profile otherwise Istio will not install due to pod system limitations.

$ istioctl install --set profile=demo ✔ Istio core installed 
✔ Istiod installed
✔ Egress gateways installed
✔ Ingress gateways installed
✔ Installation complete

Now, if you check the pods of the istio-system namespace, you'll see Istio has been installed

$ kubectl get pods -n istio-system

NAME READY STATUS RESTARTS AGE
istio-egressgateway-cd6b59579-mfkcd 1/1 Running
istio-ingressgateway-78f7794d66-sqttw 1/1 Running
istiod-574485bfdc-c9bkm 1/1 Running

There is one last gotcha that we need to take care of. Behind the scenes, Istio uses Envoy to route traffic. An Envoy container needs to be included with each of the pods that are deployed. To enable this, simply run the following command:

$ kubectl label namespace default istio-injection=enabled

Deploying your Application

In this demo, we’re going to be deploying the demo Bookinfo Application provided by Istio. This is a microservice application that shows off Istio’s ability to connect various services of an application.

Source: https://istio.io

To deploy this application, simply run

kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.9/samples/bookinfo/platform/kube/bookinfo.yaml

This will pull the chart from Istio’s Github and create a bunch of new Kubernetes services, service accounts, and deployments

$ kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.9/samples/bookinfo/platform/kube/bookinfo.yaml service/details created serviceaccount/bookinfo-details created 
deployment.apps/details-v1 created service/ratings created
serviceaccount/bookinfo-ratings created deployment.apps/ratings-v1
created service/reviews created serviceaccount/bookinfo-reviews created
deployment.apps/reviews-v1 created deployment.apps/reviews-v2 created
deployment.apps/reviews-v3 created service/productpage created
serviceaccount/bookinfo-productpage created
deployment.apps/productpage-v1 created

Confirm your pods are up and running ( Ready: 2/2) by running the kubectl get pods command:

$ kubectl get pods NAME READY STATUS RESTARTS AGE 
details-v1-5f449bdbb9-gfccz 2/2 Running 0 51s
productpage-v1-6f9df695b7-w7dq6 2/2 Running 0 50s
ratings-v1-857bb87c57-sltxd 2/2 Running 0 50s
reviews-v1-68f9c47f69-n6m2d 2/2 Running 0 50s
reviews-v2-5d56c488f5-tzgv7 2/2 Running 0 50s
reviews-v3-869ff44845-9h4mc 2/2 Running 0 50s

DNS

Before we end this part of the tutorial and get into Istio routing and gateways, we need to update our DNS records so that we can get a valid certificate later. You’ll need to provide an IP address to your DNS registrar to properly route your domain name to your istio-ingressgateway load balancer. You can get that address by running the following command and grabbing the EXTERNAL-IP address of the istio-ingressgateway:

$ kubectl get svc -n istio-system NAME                 TYPE         CLUSTER-IP    EXTERNAL-IP 
istio-egressgateway ClusterIP 10.7.254.232 <none>
istio-ingressgateway LoadBalancer 10.7.248.101 34.123.203.201
istiod ClusterIP 10.7.250.247 <none>

Then you’ll need to log into your DNS registrar website, and create a new A Record, pointing your domain to the external IP address listed above.

Conclusion

Well done! You’ve made it through the most difficult parts of this tutorial. The DNS propagation will take a few minutes to complete so feel free to step away, grab another cup of coffee and come back for Part 2 in a few minutes!

--

--

Andy

Web Developer, Marathon Runner, Coffee Drinker.