This post has been republished via RSS; it originally appeared at: Microsoft Tech Community - Latest Blogs - .
Introduction
is the package manager for the applications built for . Helm helps to manage complex Kubernetes applications with minimal effort. Helm packages are bundled as Charts which are easy to Create, Manage, Deploy and Rollback onto K8s clusters.
-
An overview of Helm chart and its components
-
An insight into the Architecture of Helm
-
A deep look at how Helm chart can be used to deploy Containerised applications onto K8s clusters
-
Anatomy of Helm chart templates and configurations
-
Some hands-on examples
-
A quick showcase of how Helm can work with Azure DevOps to automate application deployment
Chart.yaml
-
Contains information about the chart
-
Modify Description
-
Modify Chart Version
-
Modify App Version
apiVersionv2
nameratingsapi-chart
descriptionA Helm chart for Ratings API
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
typeapplication
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version0.0.1
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
appVersion1.0.0
values.yaml
-
Configuration values for the chart
deployment
nameratingsapi-deploy
namespaceaks-workshop-dev
labels
appratingsapi-deploy
selectorLabels
appratingsapi-pod
replicas2
strategyTypeRollingUpdate
maxSurge1
maxUnavailable1
nodeSelector
agentpoolaksapipool
containers
nameratingsapi-app
image<acr_name>/<image_name><tag>
imagePullPolicyIfNotPresent
readinessPort3000
readinessPath/healthz
livenessPort3000
livenessPath/healthz
memoryRequest"64Mi"
cpuRequest"100m"
memoryLimit"256Mi"
cpuLimit"200m"
containerPorts3000
env
nameMONGODB_URI
valueKeyMONGOCONNECTION
valueSecretaks-workshop-mongo-secret
service
nameratingsapi-service
namespaceaks-workshop-dev
selector
appratingsapi-pod
typeClusterIP
ports
protocolTCP
port80
targetPort3000
Chart Templates
-
Contains multiple Chart templates
-
All templates are deployed at once
-
Each Template contains the definition of a K8s object
-
Same format as original Deployment YAML file
-
Values are replaced by templated values
-
Filled up by corresponding values from file at runtime
-
Create Helm Chart
helm create <chart-name>
-
templates
-
Contains multiple template yamls
-
-
.helmignore
-
File containing entries that should NOT be included in the helm package
-
-
values-xxx.yaml
-
-
-
Chart.yaml
-
Contains information about the chart
-
Modify Description
-
Modify Chart Version
-
Modify App Version
-
-
Define a Chart Template
-
Conditions
-
Check existence of an item in yaml
if $ingress.annotations.rewriteTarget
nginx.ingress.kubernetes.io/rewrite-target $ingress.annotations.rewriteTarget
end
-
-
Loops
-
Repetitive entries in yaml
- range $host := $ingress.hosts
host $host.name
http
paths
- range $path := $host.paths
path $path.path
pathType $path.pathType
backend
service
name $path.service
port
number $path.port
- end
- end -
range denotes the start of the Loop block
-
{{- end }} denotes the end of the Loop block
-
Assign items in the Loop block in a variable
$host := $ingress.hosts
......
$path := $host.paths
-
-
Assign Single Key/Value pair
-
Single Value assignments are straight forward
pathType: {{ $path.pathType }}
-
-
Assign Multiple Key/Value pairs
-
Multiple Value assignments are performed using toYaml keyword
-
Indentation is for successful assignment
Note nindent value - 6
spec
selector
matchLabels
toYaml $deployment.selectorLabels | nindent 6 -
4 Blank Spaces from Left + 2 TAB Spaces (standard K8s object hierarchy)
-
Few More Examples
Note nindent value = 8
template
metadata
labels
toYaml $deployment.selectorLabels | nindent 8Note nindent value = 4
metadata
name $deployment.name
namespace $deployment.namespace
labels
toYaml $deployment.labels | nindent 4
-
-
Lookup
-
Format = lookup (apiVersion, kind, namespace, name)
-
apiVersion and kind are mandatory parameters
-
namespace parameter empty implies all k8s namespaces
-
name parameter empty implies all k8s resources of the specified kind
-
-
Deployment
$deployment := .Values.deployment
apiVersionapps/v1
kindDeployment
metadata
name $deployment.name
namespace $deployment.namespace
labels
toYaml $deployment.labels | nindent 4
spec
selector
matchLabels
toYaml $deployment.selectorLabels | nindent 6
replicas $deployment.replicas
strategy
type $deployment.strategyType
rollingUpdate
maxSurge $deployment.maxSurge
maxUnavailable $deployment.maxUnavailable
template
metadata
labels
toYaml $deployment.selectorLabels | nindent 8
spec
nodeSelector
toYaml $deployment.nodeSelector | nindent 8
if $deployment.imagePullSecrets
- range $secret := $deployment.imagePullSecrets
imagePullSecrets
name $secret.name
- end
end
containers
- range $container := $deployment.containers
name $container.name
image $container.image
imagePullPolicy $container.imagePullPolicy
resources
requests
memory $container.memoryRequest
cpu $container.cpuRequest
limits
memory $container.memoryLimit
cpu $container.cpuLimit
if and $container.readinessPort $container.readinessPath
readinessProbe
httpGet
port $container.readinessPort
path $container.readinessPath
end
if and $container.livenessPort $container.livenessPath
livenessProbe
httpGet
port $container.livenessPort
path $container.livenessPath
end
env
- range $env := $container.env
name $env.name
valueFrom
secretKeyRef
key $env.valueKey
name $env.valueSecret
- end
ports
- range $containerPort := $container.containerPorts
containerPort $containerPort
- end
- endService
$service := .Values.service
apiVersionv1
kindService
metadata
name $service.name
namespace $service.namespace
spec
selector
toYaml $service.selector | nindent 4
ports
range $port := $service.ports
protocol $port.protocol
port $port.port
targetPort $port.targetPort
end
typeClusterIPRBAC
apiVersionrbac.authorization.k8s.io/v1
kindRole
metadata
name .Values.developer.roleName
namespace .Values.developer.roleNamespace
rules
- range $rule := .Values.developer.rules
apiGroups $rule.apiGroups
resources $rule.resources
verbs $rule.verbs
- end
---
apiVersionrbac.authorization.k8s.io/v1
kindRoleBinding
metadata
name .Values.developer.bindingName
namespace .Values.developer.bindingNamespace
roleRef
apiGrouprbac.authorization.k8s.io
kindRole
name .Values.developer.roleName
subjects
- range $subject := .Values.developer.subjects
apiGrouprbac.authorization.k8s.io
name $subject.name
kind $subject.kind
- endapiVersionrbac.authorization.k8s.io/v1
kindRole
metadata
name .Values.manager.roleName
namespace .Values.manager.roleNamespace
rules
- range $rule := .Values.developer.rules
apiGroups $rule.apiGroups
resources $rule.resources
verbs $rule.verbs
- end
---
apiVersionrbac.authorization.k8s.io/v1
kindRoleBinding
metadata
name .Values.manager.bindingName
namespace .Values.manager.bindingNamespace
roleRef
apiGrouprbac.authorization.k8s.io
kindRole
name .Values.manager.roleName
subjects
- range $subject := .Values.manager.subjects
apiGrouprbac.authorization.k8s.io
name $subject.name
kind $subject.kind
- end# Check for existence of the ClusterRoleBinding resource with the name - aks-workshop-cluster-admin-bindings in all k8s namespaces
if not (lookup "rbac.authorization.k8s.io/v1" "ClusterRoleBinding" "" "aks-workshop-cluster-admin-bindings")
apiVersionrbac.authorization.k8s.io/v1
kindClusterRoleBinding
metadata
name .Values.clusteradmin.name
roleRef
apiGrouprbac.authorization.k8s.io
kindClusterRole
name .Values.clusteradmin.roleName
subjects
apiGrouprbac.authorization.k8s.io
name (index .Values.clusteradmin.subjects 0).name
kind (index .Values.clusteradmin.subjects 0).kind
endIngress
$ingress := .Values.ingress
apiVersionnetworking.k8s.io/v1
kindIngress
metadata
name $ingress.name
namespace $ingress.namespace
annotations
kubernetes.io/ingress.class $ingress.annotations.ingressClass
if $ingress.annotations.rewriteTarget
nginx.ingress.kubernetes.io/rewrite-target $ingress.annotations.rewriteTarget
end
if $ingress.annotations.enableCors
nginx.ingress.kubernetes.io/enable-cors $ingress.annotations.enableCors | quote
end
if $ingress.annotations.proxyBodySize
nginx.ingress.kubernetes.io/proxy-body-size $ingress.annotations.proxyBodySize
end
if $ingress.annotations.backendProtocol
nginx.ingress.kubernetes.io/backend-protocol $ingress.annotations.backendProtocol
end
if $ingress.annotations.sslpassThrough
nginx.ingress.kubernetes.io/ssl-passthrough $ingress.annotations.sslpassThrough | quote
end
spec
rules
- range $host := $ingress.hosts
host $host.name
http
paths
- range $path := $host.paths
path $path.path
pathType $path.pathType
backend
service
name $path.service
port
number $path.port
- end
- end
if $ingress.tls
tls
- range $tls := $ingress.tls
hosts
- range $tlsHost := $tls.hosts
$tlsHost | quote
- end
secretName $tls.secretName
- end
end
Values for the Chart
Examples
Deployment
deployment
nameratingsapi-deploy
namespaceaks-workshop-dev
labels
appratingsapi-deploy
selectorLabels
appratingsapi-pod
replicas2
strategyTypeRollingUpdate
maxSurge1
maxUnavailable1
nodeSelector
agentpoolaksapipool
containers
nameratingsapi-app
image<acrName>.azurecr.io/ratings-apiv1.0.0
imagePullPolicyIfNotPresent
readinessPort3000
readinessPath/healthz
livenessPort3000
livenessPath/healthz
memoryRequest"64Mi"
cpuRequest"100m"
memoryLimit"256Mi"
cpuLimit"200m"
containerPorts3000
env
nameMONGODB_URI
valueKeyMONGOCONNECTION
valueSecretaks-workshop-mongo-secret
Service
service
nameratingsapi-service
namespaceaks-workshop-dev
selector
appratingsapi-pod
typeClusterIP
ports
protocolTCP
port80
targetPort3000
RBAC
clusteradmin
nameaks-workshop-cluster-admin-bindings
roleNamecluster-admin
subjects
name<>
kindUser
developer
roleNameaks-workshop-developer-roles
roleNamespaceaks-workshop-dev
rules
apiGroups"" "apps" "networking.k8s.io"
resources"configmaps" "pods" "pods/exec" "pods/log" "deployments" "services" "events" "ingresses"
verbs"create" "delete" "deletecollection" "get" "list" "patch" "update" "watch"
bindingNameaks-workshop-developer-rb
bindingNamespaceaks-workshop-dev
subjects
name<AzureAD_Group_Name>
kindGroup
manager
roleNameaks-workshop-manager-roles
roleNamespaceaks-workshop-dev
rules
apiGroups"" "apiextensions.k8s.io" "apps" "autoscaling" "batch" "events.k8s.io" "networking.k8s.io" "policy" "rbac.authorization.k8s.io" "scheduling.k8s.io"
resources"configmaps" "endpoints" "events" "limitranges" "persistentvolumeclaims" "pods" "resourcequotas" "serviceaccounts" "namespaces" "services" "customresourcedefinitions" "daemonsets" "deployments" "replicasets" "statefulsets" "horizontalpodautoscalers" "cronjobs" "jobs" "events" "ingresses" "networkpolicies" "poddisruptionbudgets" "rolebindings" "roles" "priorityclasses"
verbs"create" "delete" "deletecollection" "get" "list" "patch" "update" "watch"
apiGroups"metrics.k8s.io"
resources"nodes" "pods"
verbs"get" "list"
bindingNameaks-workshop-manager-rb
bindingNamespaceaks-workshop-dev
subjects
name<AzureAD_Group_Name>
kindGroup
Ingress
ingress
nameaks-workshop-ingress
namespaceaks-workshop-dev
annotations
ingressClassnginx
proxyBodySize"10m"
enableCors"true"
rewriteTarget/$1
hosts
name<dns-server>
paths
path/?(.*)
pathTypePrefix
serviceratingsweb-service
port80
Install/Upgrade the Chart
helm install <chart-name> -n aks-workshop-dev ./<chart-name>/ -f ./<chart-name>/values-dev.yaml
helm upgrade <chart-name> -n aks-workshop-dev ./<chart-name>/ -f ./<chart-name>/values-dev.yaml
UnInstall the Chart
helm uninstall <chart-name>
Integration with Azure DevOps
deployment Task in Azure DevOps
