Fedex sucks – badly

I’ve got a delivery from the US.

I wasn’t at home when it arrived. There wasn’t a card but according to the tracking number, it was supposed to be delivered the next day by 6pm.

I stayed in all day. I was pretty sure it wouldn’t arrive.

By 4pm I was sure and called and asked. They said it was on the van.

By 5pm their phone lines stopped answering.

By 6:40pm no parcel and the website said their office hours were 9am to 6pm.

I rang the US International office. They said they’d have to put me through to the UK office. I explained that this would be shut. But they gave me the UK International number anyway.

Which turned out to be wrong. It was an 0845 number and I had to redial with 0345. Finally I got through to reach an answering maching which said they were shut.

And they disconnected.

Why was I so sure it wouldn’t arrive?

‘cos this happened exactly the same last time.


Tech is like compost

You get unbelievable amounts chucked about.

Not surprisingly it’s pretty unpalatable to most people.

But every now and then some genius takes a seed, plants it in this mountain of compost being thrown out in all directions, waits, sells the result to the public and becomes a billionaire.

The problem is: no-one can believe it’s that easy.


E.g. look at the crappy UI of old phones.

Then along came the iPhone.


Or the crappy UI of old computers.

Then along came the Mac courtesy of Xerox Parc.


Or the crappy interface of git.

Or the crappy interfaces for any modern technology such as:

  • Ansible
  • Kubernetes
  • Terraform
  • AWS
  • Apache
  • HTML
  • CSS

Helm Charts

Charts describe a set of Kubernetes resources – e.g. a full web app stack with HTTP servers, databases, caches, etc.

requirements.yamldefines dependencies using:

  • name
  • version
  • repository

Tags: like Ansible

Condition: enabled / disabled – always override tags.



Manage charts with helm:

  • create – creates chart
  • package – packages
  • lint – checks formatting


Getting started with Helm:

1. check kubectl config – i.e. using local minikube

kubectl config view | grep current

2. start helm

helm init


Installing MySQL as a Helm Chart

Running helm install stable/mysql

(which uses: )

helm install stable/mysql

NAME:   queenly-seahorse
LAST DEPLOYED: Mon Nov  5 11:22:13 2018
NAMESPACE: default

==> v1/Secret
NAME                    AGE
queenly-seahorse-mysql  0s

==> v1/ConfigMap
queenly-seahorse-mysql-test  0s

==> v1/PersistentVolumeClaim
queenly-seahorse-mysql  0s

==> v1/Service
queenly-seahorse-mysql  0s

==> v1beta1/Deployment
queenly-seahorse-mysql  0s

==> v1/Pod(related)

NAME                                     READY  STATUS   RESTARTS  AGE
queenly-seahorse-mysql-6dc964999c-h4w54  0/1    Pending  0         0s

MySQL can be accessed via port 3306 on the following DNS name from within your cluster:

To get your root password run:

    MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace default queenly-seahorse-mysql -o jsonpath="{.data.mysql-root-password}" | base64 --decode; echo)

To connect to your database:

1. Run an Ubuntu pod that you can use as a client:

    kubectl run -i --tty ubuntu --image=ubuntu:16.04 --restart=Never -- bash -il

2. Install the mysql client:

    $ apt-get update && apt-get install mysql-client -y

3. Connect using the mysql cli, then provide your password:
    $ mysql -h queenly-seahorse-mysql -p

To connect to your database directly from outside the K8s cluster:

    # Execute the following command to route the connection:
    kubectl port-forward svc/queenly-seahorse-mysql 3306

    mysql -h ${MYSQL_HOST} -P${MYSQL_PORT} -u root -p${MYSQL_ROOT_PASSWORD}

Let’s test we can connect to MySQL.

From the output, let’s get the MySQL password:

kubectl get secret --namespace default queenly-seahorse-mysql -o jsonpath="{.data.mysql-root-password}" | base64 --decode; echo


Note: you could have got the pod name with:

kubectl get pods

Now exec into MySQL with:

kubectl exec -it queenly-seahorse-mysql-6dc964999c-h4w54 bash

Install MySQL client:

apt-get update && apt-get install mysql-client -y --force-yes

and connect with:

mysql -h localhost -p



More on:

  • kubectl commands here: Kubernetes: kubectl
  • MySQL Notes here:

Installing WordPress as a Helm Chart

helm install --name my-release stable/wordpress

List with

helm list

and delete with

helm delete my-release



Error: no available release name found



Error: Get!D(MISSING)TILLER: dial tcp i/o timeout

When you do a helm list



kubectl delete the tiller service and deployment.)

$ kubectl create serviceaccount --namespace kube-system tiller
$ kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
$ helm init --service-account tiller

So: kubectl delete tiller-deploy-6fd8d857bc-fp5s2
error: resource(s) were provided, but no name, label selector, or –all flag specified

kubectl list
Error: unknown command “list” for “kubectl”

This suggests deleting tiller using

helm reset

but this gives:

helm reset
Error: Get!D(MISSING)TILLER: dial tcp i/o timeout

and helm ls

Error: Get!D(MISSING)TILLER: dial tcp i/o timeout

Another, not very helpful, issue on why you can’t delete tiller:

Checking tiller:

kubectl get deploy -n kube-system

coredns                1         1         1            1           12d
kube-dns               1         1         1            0           71d
kubernetes-dashboard   1         1         1            0           71d
tiller-deploy          1         1         1            1           8d


To see pods in kube-system

kubectl get pods –namespace kube-system


tiller-deploy-6fd8d857bc-fp5s2 1/1 Running 7 8d



Tiller namespaces and RBAC

Namespaces are for different environments. E.g. production, staging.

RBAC and Service Accounts:


Further reading

Use ksonnet to generate Kubernetes configurations from Helm Charts