Kubernetes, Helm, & Odoo
Setting up Kubernetes and Helm on GKE with Odoo as a sample application.

Introduction
This is a practical introduction to setting up and using Kubernetes, which includes setting it up on Google Kubernetes Engine, installing Helm and Tiller with TLS, installing Nginx and Cert-Manager for TLS secured ingresses, and finally installing Odoo as an example application.
What This Tutorial Covers
What This Tutorial Covers
- Creating A Cluster On Google Kubernetes Engine
- Installing Helm and Tiller For Launching Applications On Kubernetes
- Installing Nginx and Cert-Manager For TLS Ingresses
- Installing Odoo As An Example
What You Need For This Tutorial
What You Need For This Tutorial
A Google Cloud Platform account
GKE: Google Kubernetes Engine
Google Kubernetes Engine makes launching clusters incredibly easy, but first you need to set up your computer to communicate with your Google Cloud Platform (GCP) account and Kubernetes. To communicate with Google, we'll install gcloud and to communicate with Kubernetes, we'll install kubectl.
Go here, and follow the instructions to install gcloud on your computer: https://cloud.google.com/sdk/install.
You can either install kubectl using gcloud, or using some other method, like a package manager or downloading a binary. All methods are listed here: https://kubernetes.io/docs/tasks/tools/install-kubectl/#install-kubectl. The command for using gcloud to install kubectl is:
gcloud components install kubectl
Run the command below to get credentials for accessing your GCP account.
gcloud auth application-default login
You need a Google project under which to create a cluster. You can do this using the GCP console online at https://console.cloud.google.com or using the command below. Btw, (maybe a duh moment, but...) you can always append
gcloud projects create ${PROJECT}
Now you need to set your default project and zone for gcloud. You can always override these in commands with the --project and --zone flags if you need. The zone is the geographic location of where you want your resources deployed (literally which Google server farm to use). You can get a list of available zones with: gcloud compute zones list.
gcloud config set project ${PROJECT}
gcloud config set compute/zone ${ZONE}
Okay, finally it's time to create a Kubernetes cluster. Again, you can either go to the GCP console, select "Kubernetes Engine", and create a cluster or you can enter the command below. You can also generate the command from the GCP console. I didn't see an option to enable autoscaling from the console, you may have to add the following arguments yourself: --enable-autoscaling --min-nodes 2 --max-nodes 5
The last thing to do is grab the credentials to send commands to your new cluster, as well as create a cluster role binding for your gcloud user to in your cluster.
gcloud container clusters get-credentials ${CLUSTER}
kubectl create clusterrolebinding cluster-admin-binding \
--clusterrole cluster-admin --user $(gcloud config get-value account)
Helm
Now we're going to install Helm, which we'll use to deploy applications on a cluster. If you come from the Docker world, Helm is basically the equivalent of Docker Compose. Since an application is often built up of multiple resources, like deployments, services, ingresses, etc., a Helm "chart" contains the definition of all those resources and deploys them together so you don't have to do it one by one.
Install the helm client on your computer with:
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get | bash
Create a service account and a cluster role binding for Tiller. Tiller is a service that deploys and manages your helm chart on your cluster. It's different from Helm, which is really just a command line tool for sending commands to Tiller.
kubectl create serviceaccount -n kube-system tiller
kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
It's really important to encrypt your helm charts with TLS when you send them to your cluster. To do that, we need to create a certificate authority and two certificates, one for Tiller and the other for Helm. I use the script to below to create my certificates. To use it, add it to a file named tls
, place the file somewhere in your $PATH, and make it executable.
Now you can run the following commands:
tls -p secrets/ca -n ca -d ${DOMAIN} -e 3650 -a
tls -p secrets/tiller -n tiller -d tiller.${DOMAIN} -e 3650 -c secrets/ca/ca
tls -p secrets/helm -n helm -d helm.${DOMAIN} -e 3650 -c secrets/ca/ca
Now we can initialize Tiller with the following command:
helm init \
--tiller-tls \
--tiller-tls-cert secrets/tiller/tiller.crt \
--tiller-tls-key secrets/tiller/tiller.key \
--tiller-tls-verify \
--tls-ca-cert secrets/ca/ca.crt \
--service-account tiller \
--upgrade
Check that Tiller is running and that you can connect with Helm:
kubectl get --all-namespaces pods -n kube-system
helm ls --tls \
--tls-ca-cert secrets/ca/ca.crt \
--tls-cert secrets/helm/helm.crt \
--tls-key secrets/helm/helm.key
So that we don't have to specify the location of our secrets all the time, copy them into your the home directory of Helm:
cp secrets/ca/ca.crt $(helm home)/ca.pem
cp secrets/helm/helm.crt $(helm home)/cert.pem
cp secrets/helm/helm.key $(helm home)/key.pem
Now you should be able to connect with just helm ls --tls. Finally, update your helm repos (this basically like the update command in most package managers):
helm repo update
Nginx
Nginx is a common and simple proxy server for directing web traffic to a service on your cluster. Installing it is now incredibly simple with Helm. We're going to add it to the namespace "odoo" since we're going to use it for that application.
helm install --tls \
--name nginx \
--namespace odoo \
stable/nginx-ingress
Cert-Manager
Cert-Manager is for creating TLS certificates that Nginx will use to enable HTTPS connections. Again, super simple to install with Helm. The first command is to create Custom Resource Definitions that Cert Manager uses.
kubectl apply -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.6/deploy/manifests/00-crds.yaml
helm install --tls \
--name cert-manager \
--namespace odoo \
stable/cert-manager
Now we need to create a Cluster Issuer, which is essentially a service that will create and manage our certificates. In order for the Cluster Issuer to verify that you have control over the domain names you want to create certificates for, we need to create a GCP IAM service account that can access our Cloud DNS. To do this, follow these steps:
- Go to the GCP cloud console and click "IAM", then "Service accounts".
- Click on "+ Create Service Account"
- On part 1, give it the name "kube-cert-sa"
- On part 2, when assigning permissions, give it the role of "DNS Administrator" under the "DNS" category.
- On part 3, choose "Create Key"
- Copy the contents of the key into a file named
kube-cert-sa.key.json
in a local folder calledsecrets
Now, create the following yml files. They define Cluster Issuers for Google Cloud Platform. Although we'll only use the staging Cluster Issuer for testing, I'm including the production version in case you need it. Make sure you add your own email and project name.
Now create them by applying the manifests:
kubectl apply -f clusterIssuerStaging.yml
kubectl apply -f clusterIssuerProduction.yml
With the Cluster Issuers installed, we won't have to create certificates manually. Instead, they'll watch for specific annotatations, and when they exist, they'll auto-generate your certificates.
Odoo
Odoo is an open source suite of business tools. For businesses wanting a low cost, self-hosted solution, you can launch Odoo on your own Kubernetes cluster. First create the following file with the name odoo.yml in a directory called odoo. Make sure you replace the variables in the file:
Now we'll create Odoo in our cluster using that configuration file:
helm install --tls \
--name odoo \
-f odoo/odoo.yml \
stable/odoo
It might take a little while for all of the Odoo services to deploy. The final step is to create an ingress to make Odoo accessible from the internet. Create the following file with the name odoo-Ingress.yml in your odoo directory. Make sure you add your own domain, the one you created a DNS entry for (probably odoo.${DOMAIN}). The "tls", "hosts" annotation should automatically be detected by Cert-Manager and it should create the appropriate TLS certificate for it.
And finally, create the ingress by applying it:
kubectl apply -f odoo/odoo-Ingress.yml
Important! You need to create a DNS entry that routes the domain you want to use to Odoo. So for instance, you need to create an A record that points odoo.${DOMAIN} to the IP address that is assigned to your Odoo ingress. You can figure that out through the GCP console or by using the kubectl describe command on your ingress.
Now when you go to your Odoo domain. You should see the log in screen. If you don't see it. You can check on the status of Odoo with the following command:
helm status --tls odoo
Done!
That's a quick run through of how to set up Kubernetes with Helm on GKE, along with an example of what launching applications looks like. In the near future, I'll be adding blog entries for the following topics:
- Writing your own Helm charts for you applications
- Basic administrative Odoo set up and usage
- A practical introduction to Istio on Kubernetes
- Running a self-hosted GitLab solution on Kubernetes
So keep in touch!