Last active
October 30, 2021 10:21
-
-
Save amcginlay/69533288eb2868e366eac0483a88f054 to your computer and use it in GitHub Desktop.
You can reference this file from https://bit.ly/amcginlay-helm3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
####################################################################### | |
# 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