Skip to content

Instantly share code, notes, and snippets.

@amcginlay
Last active October 30, 2021 10:21
Show Gist options
  • Save amcginlay/69533288eb2868e366eac0483a88f054 to your computer and use it in GitHub Desktop.
Save amcginlay/69533288eb2868e366eac0483a88f054 to your computer and use it in GitHub Desktop.
You can reference this file from https://bit.ly/amcginlay-helm3
#######################################################################
# HELM - the k8s package manager
#######################################################################
# install utils
sudo yum install -y tree
# install helm (https://helm.sh/docs/intro/install/)
curl -sSL https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
# install the kubectl neat add-on (https://krew.sigs.k8s.io/docs/user-guide/setup/install/ | https://github.com/itaysk/kubectl-neat)
(
set -x; cd "$(mktemp -d)" &&
OS="$(uname | tr '[:upper:]' '[:lower:]')" &&
ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')" &&
KREW="krew-${OS}_${ARCH}" &&
curl -fsSLO "https://github.com/kubernetes-sigs/krew/releases/latest/download/${KREW}.tar.gz" &&
tar zxvf "${KREW}.tar.gz" &&
./"${KREW}" install krew
)
echo 'export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
kubectl krew install neat
# start by showing how to install and uninstall a published helm chart/package (apache)
helm repo add bitnami https://charts.bitnami.com/bitnami
helm search repo bitnami/apache
helm upgrade -i apache bitnami/apache
helm list
kubectl get all
helm uninstall apache
# see how helm can be used to build a skeleton of a new chart, then discard it (we'll build the file structure manually)
helm create dummy-app
tree -a dummy-app
rm -rf ./dummy-app
#######################################################################
# That's the preamble over, let's build a chart for NGINX
#######################################################################
# prepare the chart location
chart_version=1.0.0
app_name=nginx
app_version=1.19.5
mkdir -p ./helm-charts/${app_name}/templates
# build the Chart file
cat > ./helm-charts/${app_name}/Chart.yaml << EOF
apiVersion: v2
name: ${app_name}
version: ${chart_version}
EOF
# build the values file
cat > ./helm-charts/${app_name}/values.yaml << EOF
image: ${app_name}
version: ${app_version}
replicas: 3
EOF
# use kubectl dry-runs to build the deployment and service manifests
kubectl create deployment ${app_name} --image IMAGE:VERSION -o yaml --dry-run=client | \
kubectl neat | \
sed "s/replicas: 1/replicas: {{ .Values.replicas }}/g" | \
sed "s/IMAGE/{{ .Values.image }}/g" | \
sed "s/VERSION/{{ .Values.version }}/g" \
> ./helm-charts/${app_name}/templates/deployment.yaml
kubectl create service loadbalancer ${app_name} --tcp=80 -o yaml --dry-run=client | \
kubectl neat \
> ./helm-charts/${app_name}/templates/service.yaml
# deploy this Helm chart
tree -a ./helm-charts/${app_name} # inspect the package
kubectl create namespace ${app_name}
helm -n ${app_name} upgrade -i --dry-run ${app_name} ./helm-charts/${app_name} # kick the tyres, look for errors
helm -n ${app_name} upgrade -i ${app_name} ./helm-charts/${app_name} # bon vovage!
# NOTE at any point in time, we can check the deployment info in helm (NOTE stored in k8s secrets)
helm -n ${app_name} list
helm -n ${app_name} status ${app_name}
helm -n ${app_name} history ${app_name}
# check what we've done
kubectl -n ${app_name} get deployment,service ${app_name}
# in a SEPARATE terminal window ...
# set the app_name variable as appropriate, then grab the load balancer DNS name,
# loop for a response (which may take 2-3 mins)
app_name=nginx
lb_dnsname=$(kubectl -n ${app_name} get service -l app=${app_name} -o jsonpath='{.items[0].status.loadBalancer.ingress[0].hostname}')
echo "${app_name:-NO_APP} -> ${lb_dnsname:-NO_LB}" # if NO_LB, we were too quick ... try again.
while true; do curl http://${lb_dnsname}; sleep 0.5; done # !!! keep the window open and polling the endpoint !!!
# back in the FIRST terminal window ...
# to aid this demo, make the following update so a custom index.html is surfaced inside the nginx container
# this uses a volume mount in the deployment which uses a file-based configmap entry to represent the new homepage
# we can now easily see the nginx version number without needing to build a custom container image
kubectl create configmap ${app_name} --from-file=index.html=<(echo {{ .Values.version }}) -o yaml --dry-run=client | \
kubectl neat \
> ./helm-charts/${app_name}/templates/configmap.yaml
cat >> ./helm-charts/${app_name}/templates/deployment.yaml << EOF
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
volumes:
- name: html
configMap:
name: ${app_name}
EOF
# inspect your work then "upgrade" the package whilst watching the looped curl request in the alternate terminal window
tree -a ./helm-charts/${app_name}
cat ./helm-charts/${app_name}/templates/configmap.yaml
cat ./helm-charts/${app_name}/templates/deployment.yaml
helm -n ${app_name} upgrade -i ${app_name} ./helm-charts/${app_name}
# now upgrade the version of NGINX in our Chart/values files and "helm upgrade" it (keep an eye on the looped curl request)
old_chart_version=${chart_version}
chart_version=1.0.1
old_app_version=${app_version}
app_version=1.19.6
sed -i "s/${old_chart_version}/${chart_version}/g" ./helm-charts/${app_name}/Chart.yaml
sed -i "s/${old_app_version}/${app_version}/g" ./helm-charts/${app_name}/values.yaml
helm -n ${app_name} upgrade -i ${app_name} ./helm-charts/${app_name}
# rollback to first version (keep an eye on the looped curl request)
helm -n ${app_name} rollback ${app_name}
# do it again to undo the undo (keep an eye on the looped curl request)
helm -n ${app_name} rollback ${app_name}
# review the information in helm now
helm -n ${app_name} list
helm -n ${app_name} status ${app_name}
helm -n ${app_name} history ${app_name}
#############
# NEXT STEPS
#############
# package the helm chart: https://medium.com/containerum/how-to-make-and-share-your-own-helm-package-50ae40f6c221
# here's a good exmaple of how it could be done: https://github.com/komljen/helm-charts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment