Getting Started with Helm and Azure Kubernetes Services (AKS)

Posted by Nilay Parikh and last modified on Tue Jun 12, 2018.

First blog post of the AKS series explains to setting up Azure Kubernetes Services (AKS) with Advanced Networking & Application Routing. This current blog post would be exploring Application Deployment and Packaging using Helm on Azure Kubernetes Services.

What is Helm?

Helm faciliate and helps to manage Kubernetes applications efficiantly. Helm Charts helps to define, package, install, upgrade, roll-back, delete most complex Kubernetes applications. Helm is incubated and maitained by CNCF and ofcoursed 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

  1. Helm has two-part solution Helm as Client Cli and Tiller (gcr.io/kubernetes-helm/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).
  2. Helm refers kubeconfig for initialising connection with Kubernetes Server.

  3. 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 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

  1. For Windows users choco install kubernetes-helm or Mac users can run brew install kubernetes-helm. For more options refer installing helm .

  2. 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]].

  3. Run helm init or helm init --kube-context [[name]].

There are multiple ways to initialise helm, however for learning & demonstration purpose using kubeconfig is the fastest and easiest option.

For Production Use

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

Described before about GitHub Repository (kubernetes/charts) , we are using Wordpress stable chart and deploying to Azure Kubernetes Cluster.

  1. Run helm install --name my-release stable/wordpress, --name switch gives named release. Release name is very important for almost every helm command.

  2. Run helm upgrade [[release-name]] stable/wordpress to upgrade kubernetes deployment, in our case the release name is hello-worldpress.

  3. Run helm delete [[release-name]] to delete the deployed chart.

Next part in the series takes a deep dive into Helm and Helm Charts. Stay tuned and happy helming.

Disclaimer

Any views or opinions expressed are solely those of the author and do not represent any other person or organisation. THE ARTICLE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND. IN NO EVENT SHALL THE AUTHOR(S) OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY.

References