In my previous post I shared how to setup a Kubernetes cluster using Kubespray. Now that it is up and running, how do we run and manage applications on it?
Deploying an application in Kubernetes can involve creating multiple resources such pods, deployments and services with each requiring a handcrafted YAML manifest file. This is no fun and wasn't really maintanable in the long term.
This post illustrates how to setup and configure Helm to easily perform key operations for managing applications such as install, upgrade or delete onto a Kubernetes cluster.
Install and Configure Helm
Helm is comprised of two components: helm (client) and tiller (server). Let's go through the steps to install and configure them.
Install helm
curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get > get_helm.sh
chmod 700 get_helm.sh
./get_helm.sh
Helm v2.12.1 is available. Changing from version v2.7.2.
Downloading https://kubernetes-helm.storage.googleapis.com/helm-v2.12.1-darwin-amd64.tar.gz
Preparing to install helm and tiller into /usr/local/bin
Password:
helm installed into /usr/local/bin/helm
tiller installed into /usr/local/bin/tiller
Run 'helm init' to configure helm.
Initialize helm
and tiller
$ helm init
$HELM_HOME has been configured at /Users/ron/.helm.
Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster.
Please note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy.
To prevent this, run `helm init` with the --tiller-tls-verify flag.
For more information on securing your installation see: https://docs.helm.sh/using_helm/#securing-your-helm-installation
Happy Helming!
To confirm helm is installed correctly, run helm version
.
Deploy a Chart
Let's first make sure we have the latest list of charts.
$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Skip local chart repository
...Successfully got an update from the "stable" chart repository
Update Complete. ⎈ Happy Helming!⎈
Install the Ghost chart
$ helm install --name myghost stable/ghost
NAME: myghost
LAST DEPLOYED: Thu Jan 25 00:25:09 2018
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/Service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
myghost-mariadb ClusterIP 10.108.78.96 <none> 3306/TCP 1s
myghost LoadBalancer 10.98.84.189 <pending> 80:32234/TCP 1s
==> v1beta1/StatefulSet
NAME DESIRED CURRENT AGE
myghost-mariadb 1 1 1s
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
myghost-mariadb-0 0/1 Pending 0 0s
==> v1/Secret
NAME TYPE DATA AGE
myghost-mariadb Opaque 2 1s
myghost Opaque 1 1s
==> v1/ConfigMap
NAME DATA AGE
myghost-mariadb 1 1s
myghost-mariadb-tests 1 1s
==> v1/PersistentVolumeClaim
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
myghost Bound pvc-fcf13dfa-1411-11e9-a7fd-080027d05461 8Gi RWO standard 1s
NOTES:
###############################################################################
### ERROR: You did not provide an external host in your 'helm install' call ###
###############################################################################
This deployment will be incomplete until you configure Ghost with a resolvable
host. To configure Ghost with the URL of your service:
1. Get the Ghost URL by running:
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
Watch the status with: 'kubectl get svc --namespace default -w myghost'
export APP_HOST=$(kubectl get svc --namespace default myghost --template "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}")
export APP_PASSWORD=$(kubectl get secret --namespace default myghost -o jsonpath="{.data.ghost-password}" | base64 --decode)
export APP_DATABASE_PASSWORD=$(kubectl get secret --namespace default myghost-mariadb -o jsonpath="{.data.mariadb-password}" | base64 --decode)
2. Complete your Ghost deployment by running:
helm upgrade myghost stable/ghost\
--set service.type=LoadBalancer,ghostHost=$APP_HOST,ghostPassword=$APP_PASSWORD,mariadb.db.password=$APP_DATABASE_PASSWORD
Releases
A release is created each time a chart is installed.
Display existing releases
$ helm ls
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
myghost 1 Thu Jan 25 00:25:09 2018 DEPLOYED ghost-6.2.0 2.9.1 default
Upgrade an existing release
$ helm upgrade myghost stable/ghost
Release "myghost" has been upgraded. Happy Helming!
LAST DEPLOYED: Thu Jan 25 00:28:19 2018
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/Secret
NAME TYPE DATA AGE
myghost-mariadb Opaque 2 3m10s
myghost Opaque 1 3m10s
==> v1/ConfigMap
NAME DATA AGE
myghost-mariadb 1 3m10s
myghost-mariadb-tests 1 3m10s
==> v1/PersistentVolumeClaim
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
myghost Bound pvc-fcf13dfa-1411-11e9-a7fd-080027d05461 8Gi RWO standard 3m10s
==> v1/Service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
myghost-mariadb ClusterIP 10.108.78.96 <none> 3306/TCP 3m10s
myghost LoadBalancer 10.98.84.189 <pending> 80:32234/TCP 3m10s
==> v1beta1/StatefulSet
NAME DESIRED CURRENT AGE
myghost-mariadb 1 1 3m10s
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
myghost-mariadb-0 1/1 Running 0 3m9s
NOTES:
###############################################################################
### ERROR: You did not provide an external host in your 'helm install' call ###
###############################################################################
This deployment will be incomplete until you configure Ghost with a resolvable
host. To configure Ghost with the URL of your service:
1. Get the Ghost URL by running:
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
Watch the status with: 'kubectl get svc --namespace default -w myghost'
export APP_HOST=$(kubectl get svc --namespace default myghost --template "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}")
export APP_PASSWORD=$(kubectl get secret --namespace default myghost -o jsonpath="{.data.ghost-password}" | base64 --decode)
export APP_DATABASE_PASSWORD=$(kubectl get secret --namespace default myghost-mariadb -o jsonpath="{.data.mariadb-password}" | base64 --decode)
2. Complete your Ghost deployment by running:
helm upgrade myghost stable/ghost\
--set service.type=LoadBalancer,ghostHost=$APP_HOST,ghostPassword=$APP_PASSWORD,mariadb.db.password=$APP_DATABASE_PASSWORD
$ helm ls
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
myghost 2 Thu Jan 25 00:28:19 2018 DEPLOYED ghost-6.2.0 2.9.1 default
Uninstall a release
$ helm delete myghost
release "myghost" deleted