Deploying an HTTPS Website with Kubernetes, Istio, and cert-manager: Part 1
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 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 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 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.
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" \
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...
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.
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
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
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
$ 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 22.214.171.124
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.
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!