Getting Started with Helm and Azure Kubernetes Services (AKS)

The first blog post of the AKS series explains how to set up Azure Kubernetes Services (AKS) with Advanced Networking and Application Routing. This current blog post will explore Application Deployment and Packaging using Helm on Azure Kubernetes Services.

What is Helm?

Helm facilitates and helps to manage Kubernetes applications efficiently. Helm Charts help to define, package, install, upgrade, roll back, and delete the most complex Kubernetes applications. Helm is incubated and maintained by CNCF and, of course, backed up by big technology giants such as Microsoft, Google, Bitnami, etc. There are already many popular projects offering out-of-the-box Helm Charts; a GitHub repository (kubernetes/charts) would be a good starting point.

Architectural Notes

  • Helm has two-part solution Helm as Client Cli and Tiller as Kubernetes Deployment.
    • Helm runs on the client machine, CD/CI agents.
    • Tiller runs inside the Kubernetes Cluster, in case of *Azure Kubernetes Service the tiller application is hosted under kube-system namespace.
    • Helm Charts can be stored locally or fetched from public or private repository (i.e. git repository).
  • Helm refers kubeconfig for initialising connection with Kubernetes Server.
  • Realms of security should be considered when introducing Helm into the picture. RBAC policies for tiller and helm should be considered alongside users. I will try to focus the topic in a dedicated post. For advanced reading, please refer securing helm installation .

Microsoft Azure Kubernetes Service comes with a preinstalled Tiller.

Default deployment configuration,

{
  “kind”: “Deployment”,
  “apiVersion”: “extensions/v1beta1”,
  “metadata”: {
    “name”: “tiller-deploy”,
    “namespace”: “kube-system”,
    “selfLink”: “/apis/extensions/v1beta1/namespaces/kube-system/deployments/tiller-deploy”,
    “uid”: “b7c96214-6594-11e8-8c2d-0a58ac1f1714”,
    “resourceVersion”: “1112147”,
    “generation”: 2,
    “creationTimestamp”: “2018-06-01T12:10:04Z”,
    “labels”: {
      “app”: “helm”,
      “name”: “tiller”
    },
    “annotations”: {
      “deployment.kubernetes.io/revision”: “2”
    }
  },
  “spec”: {
    “replicas”: 1,
    “selector”: {
      “matchLabels”: {
        “app”: “helm”,
        “name”: “tiller”
      }
    },
    “template”: {
      “metadata”: {
        “creationTimestamp”: null,
        “labels”: {
          “app”: “helm”,
          “name”: “tiller”
        }
      },
      “spec”: {
        “containers”: [
          {
            “name”: “tiller”,
            “image”: “gcr.io/kubernetes-helm/tiller:v2.9.1”,
            “ports”: [
              {
                “name”: “tiller”,
                “containerPort”: 44134,
                “protocol”: “TCP”
              },
              {
                “name”: “http”,
                “containerPort”: 44135,
                “protocol”: “TCP”
              }
            ],
            “env”: [
              {
                “name”: “TILLER_NAMESPACE”,
                “value”: “kube-system”
              },
              {
                “name”: “TILLER_HISTORY_MAX”,
                “value”: “0”
              }
            ],
            “resources”: {},
            “livenessProbe”: {
              “httpGet”: {
                “path”: “/liveness”,
                “port”: 44135,
                “scheme”: “HTTP”
              },
              “initialDelaySeconds”: 1,
              “timeoutSeconds”: 1,
              “periodSeconds”: 10,
              “successThreshold”: 1,
              “failureThreshold”: 3
            },
            “readinessProbe”: {
              “httpGet”: {
                “path”: “/readiness”,
                “port”: 44135,
                “scheme”: “HTTP”
              },
              “initialDelaySeconds”: 1,
              “timeoutSeconds”: 1,
              “periodSeconds”: 10,
              “successThreshold”: 1,
              “failureThreshold”: 3
            },
            “terminationMessagePath”: “/dev/termination-log”,
            “terminationMessagePolicy”: “File”,
            “imagePullPolicy”: “IfNotPresent”
          }
        ],
        “restartPolicy”: “Always”,
        “terminationGracePeriodSeconds”: 30,
        “dnsPolicy”: “ClusterFirst”,
        “securityContext”: {},
        “schedulerName”: “default-scheduler”
      }
    },
    “strategy”: {
      “type”: “RollingUpdate”,
      “rollingUpdate”: {
        “maxUnavailable”: 1,
        “maxSurge”: 1
      }
    }
  },
  “status”: {
    “observedGeneration”: 2,
    “replicas”: 1,
    “updatedReplicas”: 1,
    “readyReplicas”: 1,
    “availableReplicas”: 1,
    “conditions”: [
      {
        “type”: “Available”,
        “status”: “True”,
        “lastUpdateTime”: “2018-06-01T12:10:04Z”,
        “lastTransitionTime”: “2018-06-01T12:10:04Z”,
        “reason”: “MinimumReplicasAvailable”,
        “message”: “Deployment has minimum availability.”
      }
    ]
  }
}

Install and Setup helm Client

  • For Windows users choco install kubernetes-helm or Mac users can run brew install kubernetes-helm. For more options refer installing helm  .
  • For a getting started guide, I opted for easy demonstration. Run the command if your kubeconfig not yet configured, az aks get-credentials --resource-group [[Your Resource Group]] --name [[AKS Cluster]].
  • Run helm init or helm init --kube-context [[name]].

There are multiple ways to initialize Helm; however, for learning and demonstration purposes, using kubeconfig is the fastest and easiest option.

Note:

Would recommend configuring tiller using Storage backends, the feature was added for additional security in protecting charts in conjunction with the release of secret encryption in Kubernetes. Enable tls with its certificate or tls key to verify trusted connection between helm client and tiller.

Deploying WordPress using helm chart

As mentioned earlier regarding the GitHub Repository (kubernetes/charts), we are utilizing the WordPress stable chart and deploying it to an Azure Kubernetes Cluster.

  • Run helm install --name my-release stable/wordpress--name switch gives named release. Release name is very important for almost every helm command.
  • Run helm upgrade [[release-name]] stable/wordpress to upgrade kubernetes deployment, in our case the release name is hello-worldpress.
  • Run helm delete [[release-name]] to delete the deployed chart.

The next installment in the series will take a deep dive into Helm and Helm Charts. Stay tuned and happy helming!

Disclaimer

The views expressed on this site are personal opinions only and have no affiliation. See full disclaimerterms & conditions, and privacy policy. No obligations assumed.