Tsuru in Production with Kubernetes

Guilherme B. Rezende
tsurupaas
Published in
3 min readJul 1, 2019

--

This post will teach how to install Tsuru in Kubernetes and how to add the cluster to be used by Tsuru.

This how-to was made using Digitalocean Kubernetes. We will update the article when tested with other kubernetes like (AKS, GKE, EKS…).

Here we assume that you have a kubernetes cluster running and the kubectl context properly configured.

Installing Helm/Tiller

First install helm: https://github.com/helm/helm/blob/master/docs/install.md

With helm installed, lets install tiller. (it’s just one way to install tiller, you can see other ways at: https://github.com/helm/helm/blob/240e539cec44e2b746b3541529d41f4ba01e77df/docs/rbac.md

$ cat rbac-tiller-config.yamlapiVersion: v1
kind: ServiceAccount
metadata:
name: tiller
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: tiller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: tiller
namespace: kube-system
$ kubectl create -f rbac-tiller-config.yaml

Now lets install tiller:

helm init --service-account tiller

Great! now you can install cert-manager and tsuru using helm charts :)

Prepare cluster to install Cert-manager

We will use cert-manager to manage tls certificates with letsencrypt.

You can get the steps from https://docs.cert-manager.io/en/latest/getting-started/install/kubernetes.html#steps, but tsuru charts will install cert-manager as a dependency, so you only need to do the follow steps:

Create the custom-resource:

kubectl apply -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.8/deploy/manifests/00-crds.yaml

And label the namespace that we will install cert-manager (without this label cert-manager-webhook will fail to validate certificates)

Create the namespace and the label:

kubectl create namespace tsuru-managerkubectl label namespace tsuru-manager certmanager.k8s.io/disable-validation=true

Installing Tsuru

To install Tsuru and its dependencies we will use a helm chart (thanks for gfleury who created the chart).

First clone the chart:

git clone https://github.com/tsuru/tsuru-helm-chart && cd tsuru-helm-chart

Install dependencies:

helm dep up .

Install the chart with ingress disabled (we will enable it later):

helm install --name tsuru --namespace tsuru-manager . \
--set ingress.enabled=false

Create the letsencrypt issuer (change the email field!!):

$ cat letsencrypt-prod.yamlapiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
namespace: tsuru-manager
spec:
acme:
# You must replace this email address with your own.
# Let's Encrypt will use this to contact you about expiring
# certificates, and issues related to your account.
email: YOUR_EMAIL@gmail.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
# Secret resource used to store the account's private key.
name: letsencrypt-prod-pk
# Add a single challenge solver, HTTP01 using nginx
solvers:
- http01:
ingress:
class: nginx
$ kubectl apply -f letsencrypt-prod.yaml

Now you need to get the ingress-controller loadbalancer IP:

export LB_HOSTNAME=$(kubectl -n tsuru-manager get services tsuru-nginx-ingress-controller -o jsonpath="{.status.loadBalancer.ingress[0].ip}")echo $LB_HOSTNAME

If you have a domain, it’s time to point the dns to LB_HOSTNAME.

In order to use with kube-router, you need to add a wildcard domain pointing to the LB_HOSTNAME.

If you don’t have or don’t want to use a domain now, you can use nip.io.

Changing hostnames in tsuru installation:

$ HOSTNAME="cloud.$LB_HOSTNAME.nip.io" # or your own domainhelm upgrade tsuru --namespace tsuru-manager . \
--set ingress.enabled=true \
--set ingress.domain=$HOSTNAME \
--set ingress.tls[0].hosts[0]=tsuru.$HOSTNAME \
--set docker-registry.ingress.hosts[0]=registry.$HOSTNAME \
--set docker-registry.ingress.tls[0].hosts[0]=registry.$HOSTNAME \
--set ingress.tls[0].secretName=tsuru-api \
--set docker-registry.ingress.tls[0].secretName=registry-tls \
--set registry.enabled=true \
--set registry.url=registry.$HOSTNAME

Now you have tsuru installed with tls!!

Configuring Tsuru

Create the admin user on tsuru:

export POD_NAME=$(kubectl -n tsuru-manager get pods -l “app=tsuru,release=tsuru” -o jsonpath=”{.items[0].metadata.name}”)kubectl -n tsuru-manager exec -it $POD_NAME tsurud root-user-create admin@example.com # CHANGE IT TO YOUR ADMIN USER #

Create the tsuru-target and log in:

tsuru target-add -s default https://$HOSTNAMEtsuru login

Create pool, and add kubernetes cluster to be managed by tsuru:

tsuru pool-add mypool -p -d --provisioner kubernetesexport SA_NAME=$(kubectl -n tsuru-manager get sa -l "app=tsuru-tsuru-api,release=tsuru"  -o jsonpath="{.items[0].secrets[0].name}")

export K8S_TOKEN=$(kubectl -n tsuru-manager get secret $SA_NAME -o jsonpath="{.data.token}" | base64 -d)
kubectl -n tsuru-manager get secret $SA_NAME -o jsonpath="{.data.ca\.crt}" | base64 -d > ca.crttsuru cluster-add kube-prod kubernetes \
--addr=https://kubernetes.default.svc.cluster.local \
--cacert ca.crt \
--custom token=$K8S_TOKEN \
--default

We need to update nodes to add pool:

tsuru node list -q | xargs -I{} sh -c "tsuru node-update {} pool=mypool"

Create one team:

tsuru team-create admin

Create and Deploy tsuru-dashboard app:

tsuru app-create dashboard --router-opts tls-acme=truetsuru app-deploy -a dashboard -i tsuru/dashboard

Build Platforms:

tsuru platform-add pythontsuru platform-add go

Create an app to test:

mkdir example-go && cd example-gowget https://raw.githubusercontent.com/tsuru/platforms/master/examples/go/tsuru.ymlwget https://raw.githubusercontent.com/tsuru/platforms/master/examples/go/web.gotsuru app-create example-go go tsuru app-deploy -a example-go .

Check the app info and get the url:

tsuru app-info -a example-go

Please leave us a comment telling if everything went well, if you had any problems or if you needed an extra step, etc …

--

--