Wilson Mar bio photo

Wilson Mar

Hello. Hire me!

Email me Calendar Skype call 310 320-7878

LinkedIn Twitter Gitter Instagram Youtube

Github Stackoverflow Pinterest

Integrated DevSecOps from Thoughtworks

Español (Spanish)   Français (French)   Deutsch (German)   Italiano   Português   Cyrillic Russian   中文 (简体) Chinese (Simplified)   日本語 Japanese   한국어 Korean

Overview

This article is a hands-on introduction about using a Helm Chart to group multiple Kubernetes objects into one unit used to stand up Kubernetes clusters.

helm.sh says helm is a package manager for Kubernets like Brew on macOS, Chocolately on Windows, apt on Debian/Ubuntu, yum on Red Hat, etc. Helm is is a cloud industry consortium composed of Google, Microsoft, Bitnami, and others.

Helm has become popular with cloud developers largely because it simplifies Kubernetes application management, the roll out of updates, and options to share applications. Package management features make it easier to:

  • search available packages -
  • provide information on packages
  • download and install packages, along with dependencies, creation of folders, and insertion of those folders in the system’s PATH variable
  • list installed packages
  • lint installed packages
  • update existing installed packages
  • delete packages

Helm works with “Charts” which are a set of files defined as curated applications for Kubernetes.

Helm is made of two components:

  1. Tiller server running inside your Kubernetes cluster to manage (install, upgrade, query, and remove) Kubernetes resources via calls to the Kubernetes API server.
  2. helm CLI client running on your local machine. It sends requests to Tiller. A CLI client is needed because operations such as rollback, running chart tests, etc. are done from the helm CLI client.

https://github.com/helm/helm/blob/master/docs/charts.md


Let’s begin with the client CLI:

  1. On any folder, see about Kubernetes minikube CLI client for macOS:

    brew info minikube

    Response at time of writing:

    Found a cask named "minikube" instead.
    minikube: 1.3.0
    https://github.com/kubernetes/minikube
    Not installed
    From: https://github.com/Homebrew/homebrew-cask/blob/master/Casks/minikube.rb
    
  2. Install Kubernetes minikube CLI client for macOS:

    brew cask install minikube

    You may need to:

    brew link --overwrite kubernetes-cli

    response:

    Linking /usr/local/Cellar/kubernetes-cli/1.15.2... 229 symlinks created
  3. Verify:

    minikube version

    Example response:

    minikube version: v1.3.0
    commit: 43969594266d77b555a207b0f3e9b3fa1dc92b1f
    
  4. Get started:

    minikube start

    On Windows, add <pre>–vm-driver hyperkit</pre>

    Example response:

    😄  minikube v1.3.0 on Darwin 10.14.6
    👍  Upgrading from Kubernetes 1.10.0 to 1.15.2
    💿  Downloading VM boot image ...
     minikube-v1.3.0.iso.sha256: 65 B / 65 B [=====================] 100.00% 0s
    ...
    
  5. Get the status:

    minikube service list

    Sample response:

    Get https://192.168.99.106:8443/api/v1/services: dial tcp 192.168.99.106:8443: getsockopt: no route to host
    Check that minikube is running and that you have specified the correct namespace (-n flag) if required.
    
  6. Get the status:

    minikube status

    If you get “💣 Error getting host status: state: exit status 126”

    The expected response is like this:

    minikube: Running
    cluster: Running
    kubectl: Correctly Configured: pointing to minikube-vm at 192.168.99.100
    

    PROTIP: IP address 192.168.99.100 is used by docker-machine.

    See https://www.jhipster.tech/tips/020_tip_using_docker_containers_as_localhost_on_mac_and_windows.html

    docker-machine stop default

    ???

  7. Verify:

    kubectl version

    Example response:

    Client Version: version.Info{Major:"1", Minor:"15", GitVersion:"v1.15.2", GitCommit:"f6278300bebbb750328ac16ee6dd3aa7d3549568", GitTreeState:"clean", BuildDate:"2019-08-05T16:54:35Z", GoVersion:"go1.12.7", Compiler:"gc", Platform:"darwin/amd64"}
    

    If you see “Unable to connect to the server: dial tcp 192.168.99.100:8443: i/o timeout” ???

  8. On any folder, install Helm CLI client on MacOS:

  9. Confirm the helm release installed:

    helm version

    Response:

    # Client: &version.Version{SemVer:"v2.14.3", 
    # GitCommit:"0e7f3b6637f7af8fcfddb3d2941fcc7cbebb0085", GitTreeState:"clean"}
    
  10. Set the IP randomly:

    minikube update-context

  11. Establish the context:

    kubectl config current-context

    On macOS the response is a single-node Kubernetes cluster running locally:

    minikube

    See https://kubernetes.io/docs/setup/learning-environment/minikube/

    NOTE: The Helm RBAC guide at https://github.com/helm/helm/blob/master/docs/rbac.md has more secure and advanced RBAC configurations.

    Alternately, on Google, Azure, AWS ….

    Tip: eksctl is a useful CLI for setting up Kubernetes clusters on Amazon EKS

    Once minikube is installed, start minikube with the kubeadm bootstrapper. The kubeadm toolkit helps to easily bootstrap a cluster so that appropriate privileges are granted for performing read-write operations on Kubernetes authentication and authorization (RBAC) resources.

    minikube start --vm-driver=virtualbox --bootstrapper=kubeadm --memory 4096
  12. Optionally, enable Ingress on minikube with this command

    minikube addons enable ingress
  13. Be in a folder where the sample can be created.

    • Navigate to or create a folder to create a repo.
    • Remove the previous folder “hellos” to begin new.
    • Create folder “hellos”.
  14. Verify whether the Kubernetes cluster is running and accessible through kubectl for Helm to use:

    kubectl cluster-info

    This can take several minutes and return:

    To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
    Unable to connect to the server: dial tcp 192.168.99.100:8443: i/o timeout
    kubectl get nodes
  15. Verify the Kubernetes cluster is empty.

    kubectl get deployments,pods,services

    Helm init

  16. install tiller with the helm init command of the CLI tool: ??? *

    kubectl config use-context docker-for-desktop
  17. Initialize helm by installing a Tiller deployment to Kubernetes clusters and communicates via gRPC:

    helm init

    Response:

    $HELM_HOME has been configured at /Users/wilsonmar/.helm.

    PROTIP: v2 of Helm gives full administrative rights to Tiller - which is a risk if somebody gets unauthorized access to the cluster. V3 of Helm is tillerless. See https://rimusz.net/tillerless-helm about the “Tillerless” Helm v2 plugin for helm tiller start

    Search throu Helm repos

    As of this writing, 2,307 contributors submitted Charts into the community-curated repository at https://github.com/helm/charts.

    Charts there are stored in one of two folders. Charts begin under incubator and get moved to stable.

    Examples in the stable folder:

    • https://github.com/helm/charts/tree/master/stable/distributed-jmeter
    • https://github.com/helm/charts/tree/master/stable/influxdb
    • https://github.com/helm/charts/tree/master/stable/jenkins
    • https://github.com/helm/charts/tree/master/stable/magento
    • https://github.com/helm/charts/tree/master/stable/mariadb

    Other Helm Charts repositories include:

    But the Helm Workspace is the default:

  18. Search for ???

    helm search xxxx

    The default scope is only the stable folder.

  19. Add charts in the incubator folder for your local client, run helm repo add:

    helm repo add incubator https://kubernetes-charts-incubator.storage.googleapis.com/

    Response: “incubator” has been added to your repositories

    https://docs.gocd.org/current/gocd_on_kubernetes/setup_and_configuration.html

  20. Create a simple built-in helm Chart:

    helm create xxxx
    cd xxxx

    Alternately, a real one would be like:

    helm install stable/hello --name hello1 --namespace hellos

    https://www.youtube.com/watch?v=9cwjtN3gkD4 https://matthewpalmer.net/kubernetes-app-developer/ 105 pages

  21. Lint it:

    helm lint ./hello-world
    
  22. Look inside:

    cd hello-world
  23. List folders and files created:

    tree
     |-- Chart.yaml
     |-- charts
     |-- templates
     |   |-- NOTES.txt
     |   |-- _helpers.tpl
     |   |-- deployment.yaml
     |   |-- ingress.yaml
     |   |-- service.yaml
     |   `-- tests
     |       `-- test-connection.yaml
     `-- values.yaml
     
    4 directories, 8 files
    

    NOTE: Folders and file names must be names shown.

    Chart.yaml - contains metadata about folders and files in the Chart, such as its name, version, keywords. Notice the file name begins with a capital C.

    PROTIP: A running instance of a Chart with a specific config is called a release.

    templates directory where Kubernetes resources are defined, as templates which contain variables defined in Go template format.

    values.yaml contains keys and default values used to generate the release in your Cluster. These values are replaced in resource manifests.

    • https://helm.sh/docs/chart_template_guide/#built-in-objects
    • https://helm.sh/docs/chart_template_guide/#variables

    configMap.yaml contains database configuration.

    secrets.yaml stores database passwords as secrets.

    charts is an optional directory. It may contain sub-charts.

    .helmignore defines patterns to ignore when packaging (like .gitignore)

  24. Add a README.md file for attributions, version info, and such.

  25. Look in the template directory for sample templates for common Kubernetes resources:

    • deployment.yaml
    • service.yaml
    • ingress.yaml

  26. Render the template locally:

    helm template ./hello-world
  27. Check if the server is available:

    kubectl get deployments --namespace hellos

    https://hub.kubeapps.com/charts/stable/gocd (managed by Bitnami) provides a

gocd-helm-648x257 [5]

A. Install GoCD as a Kubernetes native application with an officially supported helm chart B. Scale GoCD agents seamlessly with the new ElasticAgent plugin that spins up agents on the fly in response to build workload C. Design Docker-based build workflows as Docker in Docker

kubectl config current-context
   # "minikube" on macOS or "my-cluster"
helm init
   # $HELM_HOME has been configured at /Users/$($username)/.helm.
kubectl get pods --namespace kube-system --selector=app=helm
   # Error: error installing: Post https://192.168.99.100:8443/apis/extensions/v1beta1/namespaces/kube-system/deployments: 
   # dial tcp 192.168.99.100:8443: i/o timeout

   # tiller-deploy STATUS Running
helm search gocd  # in hub.helm
   # stable/gocd
helm install stable/gocd --name gocd-live-demo --namespace gocd-live-demo
helm list
helm status gocd  # pre-baked
   # From post-install instructions:
echo "GoCD server public IP: http://$(kubectl get ingress gocd-server --namespace=gocd -0 jasonpath='{.status.loadBalancer ingress [0].ip}')"
 
   

References and Learning Resources

[1] In the Kubernetes Blog: Helm Charts: making it simple to package and deploy common applications on Kubernetes October 10, 2016

https://www.katacoda.com/courses/kubernetes/helm-package-manager Helm Package Manager

curl -LO https://storage.googleapis.com/kubernetes-helm/helm-v2.8.2-linux-amd64.tar.gz pwd = /root helm init helm repo update helm search redis helm inspect stable/redis helm install stable/redis

To get your password run:

export REDIS_PASSWORD=$(kubectl get secret --namespace default alliterating-lightningbug-redis -o jsonpath="{.data.redis-password}" | base64 --decode)

To connect to your Redis server:

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

    kubectl run –namespace default alliterating-lightningbug-redis-client –rm –tty -i –restart=’Never’ \ –env REDIS_PASSWORD=$REDIS_PASSWORD \ –image docker.io/bitnami/redis:5.0.5-debian-9-r95 – bash

  2. Connect using the Redis CLI: redis-cli -h alliterating-lightningbug-redis-master -a $REDIS_PASSWORD redis-cli -h alliterating-lightningbug-redis-slave -a $REDIS_PASSWORD

To connect to your database from outside the cluster execute the following commands:

kubectl port-forward --namespace default svc/alliterating-lightningbug-redis 6379:6379&
redis-cli -h 127.0.0.1 -p 6379 -a $REDIS_PASSWORD

helm ls # If you receive an error that Helm could not find a ready tiller pod, it means that helm is still deploying. Wait a few moments for the tiller Docker Image to finish downloading.

  1. Find out what was deployed: kubectl get all

  2. Wait until a Persistent Volume is available: kubectl apply -f pv.yaml # statefulset.apps/illmannered-grizzly-redis-master 0/1 94s # statefulset.apps/illmannered-grizzly-redis-slave 0/2 94s # persistentvolume/pv-volume1 created
  3. Give Redis permissions to write: chmod 777 -R /mnt/data*
  4. Provide helm with a more friendly name, such as: helm install –name my-release stable/redis

[8] Continuous Delivery with Docker and Kubernetes Aug 20, 2018 [10:36] by Ken Mugrage

https://www.digitalocean.com/community/tutorials/an-introduction-to-helm-the-package-manager-for-kubernetes An Introduction to Helm, the Package Manager for Kubernetes</a> August 6, 2018 by Brian Boucheron

https://medium.com/google-cloud/kubernetes-and-helm-create-your-own-helm-chart-5f54aed894c2

“Helm Package Manager” on Qwiklabs covers installation and configure a Chart (based in MySQL) on GCP.

gcloud container clusters create my-cluster –scopes “https://www.googleapis.com/auth/projecthosting,storage-rw”

kubectl config current-context # gke_qwiklabs-gcp-0286d80b4438f082_us-central1-f_my-cluster

  1. For some more detailed information about the cluster: kubectl cluster-info

https://www.katacoda.com/courses/docker-production/vault-secrets

Helmsman Desired State Configurator

Open-sourced at https://github.com/Praqma/helmsman, Helmsman from Praqma (by SAMI ALAJRAMI and others) provides an “autopilot” for Kubernetes clusters which automates the lifecycle management of Helm Charts using declarative (desired state) configuration files (DSF) to create, delete, upgrade, and move Kubernetes objects to different namespaces. This approach makes it easier to replicate a CI pipeline. This also takes care of secrets passing (from environment variables to Charts).

https://hub.docker.com/r/praqma/helmsman/

The desired state approach achieves idempotentcy - executing Helmsman several times gets the same result, and continues from failures.

Others

[3] CNCF Webinar Series – Getting Helm to be Enterprise-ready Apr 3, 2018


More on DevOps

This is one of a series on DevOps:

  1. DevOps_2.0
  2. ci-cd (Continuous Integration and Continuous Delivery)
  3. User Stories for DevOps

  4. Git and GitHub vs File Archival
  5. Git Commands and Statuses
  6. Git Commit, Tag, Push
  7. Git Utilities
  8. Data Security GitHub
  9. GitHub API
  10. TFS vs. GitHub

  11. Choices for DevOps Technologies
  12. Java DevOps Workflow
  13. AWS DevOps (CodeCommit, CodePipeline, CodeDeploy)
  14. AWS server deployment options

  15. Cloud services comparisons (across vendors)
  16. Cloud regions (across vendors)
  17. AWS Virtual Private Cloud

  18. Azure Cloud Onramp
  19. Azure Cloud
  20. Azure Cloud Powershell
  21. Bash Windows using Microsoft’s WSL (Windows Subystem for Linux)

  22. Digital Ocean
  23. Cloud Foundry

  24. Packer automation to build Vagrant images
  25. Terraform multi-cloud provisioning automation
  26. Hashicorp Vault and Consul to generate and hold secrets

  27. Powershell Ecosystem
  28. Powershell on MacOS
  29. Powershell Desired System Configuration

  30. Jenkins Server Setup
  31. Jenkins Plug-ins
  32. Jenkins Freestyle jobs
  33. Jenkins2 Pipeline jobs using Groovy code in Jenkinsfile

  34. Docker (Glossary, Ecosystem, Certification)
  35. Docker Setup
  36. Dockerize apps

  37. Maven on MacOSX

  38. Ansible

  39. MySQL Setup

  40. SonarQube static code scan

  41. API Management Microsoft
  42. API Management Amazon

  43. Scenarios for load