Skip to content

Instantly share code, notes, and snippets.

@Vertiwell
Created August 25, 2022 01:35
Show Gist options
  • Save Vertiwell/8c225651e4d9a7d06530f203a325e473 to your computer and use it in GitHub Desktop.
Save Vertiwell/8c225651e4d9a7d06530f203a325e473 to your computer and use it in GitHub Desktop.
Bash Install on Ubuntu 22.04 for TopoLVM
#!/bin/bash
### Deploying Topolvm on Kubernetes for Debian/Ubuntu based OS
## Baseline Guide: https://github.com/topolvm/topolvm/tree/main/charts/topolvm
# Type of Deployment: Helm
#
### Minimum Requirements ###
## Three Worker Node Cluster
## Each worker node must have a blank drive to consume, if you need to wipe said drives, use: dd if=/dev/zero of=/dev/sdc bs=1M
#
#
## The following base packages are required:
# Helm, Package Manager
# curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 && \
# chmod 700 get_helm.sh && \
# ./get_helm.sh && \
#
## Bring in the variables from the main configuration file
source /root/repo/deployment_config
#
## Set Variables
#
# Chart Repo
CHART=topolvm/topolvm
# Application
APPLICATION=topolvm
# Chart Version: helm repo update && helm search repo topolvm/topolvm --versions
CHARTVERSION=9.0.0
# Set directory as a variable
FILEDIR=/root/helm/${APPLICATION}
# Namespace for this application
NAMESPACE=topolvm-system
#
### Installation
#
# Set a directory to store files generated by this script (used for upgrades later)
mkdir -p /root/helm/${APPLICATION}
# Create Namespace
cat <<EOF >${FILEDIR}/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: ${NAMESPACE}
EOF
# Apply namespace
kubectl apply -f ${FILEDIR}/namespace.yaml
#
# Create and mount disks to the mount points (This assumes each worker node has a blank disk at /dev/sdc) and blacklist the disks from Multipath daemon
cat <<EOF >${FILEDIR}/add-disks.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: topolvm-disk-installation
namespace: ${NAMESPACE}
labels:
app: topolvm-disk-installation
annotations:
command: &cmd mkdir -p /etc/multipath/conf.d/; printf "blacklist {\n devnode \"^sd[a-z0-9]+\"\n}\n" > /etc/multipath/conf.d/sd.conf; printf "blacklist {\n devnode \"^vd[a-z0-9]+\"\n}\n" > /etc/multipath/conf.d/vd.conf; if [ -e "/dev/sdb" ]; then pvcreate /dev/sdb; vgcreate myvg1 /dev/sdb; else pvcreate /dev/vdb; vgcreate myvg1 /dev/vdb; fi
spec:
selector:
matchLabels:
app: topolvm-disk-installation
template:
metadata:
labels:
app: topolvm-disk-installation
spec:
hostNetwork: true
hostPID: true
initContainers:
- name: disk-installation
command:
- nsenter
- --mount=/proc/1/ns/mnt
- --
- bash
- -c
- *cmd
image: alpine:3.12
securityContext:
privileged: true
containers:
- name: sleep
image: k8s.gcr.io/pause:3.1
updateStrategy:
type: RollingUpdate
EOF
# Apply the DaemonSet
kubectl apply -f ${FILEDIR}/add-disks.yaml
# Wait a short time for these applications to be installed
echo "Installing Virtual Group Disks, Consuming /dev/sdb on Worker Nodes" && sleep 15 && \
# Wait for deployment
kubectl rollout status -w --timeout=300s daemonset/topolvm-disk-installation -n ${NAMESPACE}
# Get the kubelet directory
# node.kubeletWorkDirectory -- Specify the work directory of kubelet on the host, currently pulled from the /root/k*s directory
# microk8s: /var/snap/microk8s/common/var/lib/kubelet
# k0s: /var/lib/k0s/kubelet
# k3s and k8s: /var/lib/kubelet
KXS=$(ls -d /root/k* | sed 's/\/root\///')
if [ "${KXS}" == "k0s" ]; then
KUBELETPATH="/var/lib/k0s/kubelet"
fi
if [ "${KXS}" == "k3s" ]; then
KUBELETPATH="/var/lib/kubelet"
fi
if [ "${KXS}" == "k8s" ]; then
KUBELETPATH="/var/lib/kubelet"
fi
# Add the Helm Chart
helm repo add topolvm https://topolvm.github.io/topolvm && helm repo update && \
# Create custom values file
# Helm Chart Values: https://github.com/topolvm/topolvm/blob/main/charts/topolvm/values.yaml
cat <<EOF >${FILEDIR}/custom-values.yaml
lvmd:
managed: true
socketName: /run/topolvm/lvmd.sock
deviceClasses:
- name: ssd
volume-group: myvg1
default: true
spare-gb: 5
node:
kubeletWorkDirectory: ${KUBELETPATH}
controller:
storageCapacityTracking:
enabled: true
scheduler:
enabled: false
webhook:
existingCertManagerIssuer:
group: cert-manager.io
kind: ClusterIssuer
name: ca-issuer
podMutatingWebhook:
enabled: false
pvcMutatingWebhook:
enabled: true
EOF
# Deploy the chart
helm upgrade ${APPLICATION} ${CHART} --install -n ${NAMESPACE} -f ${FILEDIR}/custom-values.yaml --version ${CHARTVERSION} --wait
# Wait for rollout
ROLLOUT_STATUS_CMD="kubectl rollout status -w --timeout=300s daemonset/topolvm-lvmd-0 -n topolvm-system"
until $ROLLOUT_STATUS_CMD || [ $n -eq 300 ]; do
$ROLLOUT_STATUS_CMD
n=$((n + 1))
sleep 5
done
sleep 15
ROLLOUT_STATUS_CMD="kubectl rollout status -w --timeout=300s daemonset/topolvm-node -n topolvm-system"
until $ROLLOUT_STATUS_CMD || [ $n -eq 300 ]; do
$ROLLOUT_STATUS_CMD
n=$((n + 1))
sleep 5
done
sleep 15
ROLLOUT_STATUS_CMD="kubectl rollout status -w --timeout=300s deployment/topolvm-controller -n topolvm-system"
until $ROLLOUT_STATUS_CMD || [ $n -eq 300 ]; do
$ROLLOUT_STATUS_CMD
n=$((n + 1))
sleep 5
done
###
#
### Upgrade Helm Chart
#
# Create Helm Chart Check Version Script
cat <<EOF >${FILEDIR}/helm_update_script.sh
#!/bin/bash
CHART=${CHART}
NAMESPACE=${NAMESPACE}
APPLICATION=${APPLICATION}
LOCALVERSION=\$(helm list -n \${NAMESPACE} | awk -F ' ' '{print \$9}' | awk '{if(NR>1)print}' | awk -F"-" '{print (NF>1)? \$NF : ""}')
LOCAL=\$(echo \${LOCALVERSION} | sed 's/[.]//g')
REMOTEVERSION=\$(helm search repo \${CHART} | awk -F ' ' '{print \$2}' | awk '{if(NR>1)print}' | tr -d '\n')
REMOTE=\$(echo \${REMOTEVERSION} | sed 's/[.]//g')
if [ "\${REMOTE}" -gt "\${LOCAL}" ]; then
curl -X POST -H 'Content-type: application/json' --data '
{
"blocks": [
{
"type": "divider"
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "There is a Helm Chart Update for: \${APPLICATION}\nCurrent Version: \${LOCALVERSION}\nNew Version Available: \${REMOTEVERSION}\n\nTo install it, run the following command: helm upgrade \${APPLICATION} \${CHART} -n \${NAMESPACE} -f /root/helm/\${APPLICATION}/custom-values.yaml --version \${REMOTEVERSION}"
}
},
{
"type": "divider"
}
]
}' ${SLACKURL}
else
echo "Nothing to do"
fi
EOF
# Make script executable
chmod +x ${FILEDIR}/helm_update_script.sh
# Install Cron Task To Run Script Every Day
echo '0 9 * * * root ${FILEDIR}/helm_update_script.sh' >> /etc/crontab
###
# Cleanup
kubectl delete -f ${FILEDIR}/add-disks.yaml
# Wipe everything: helm uninstall topolvm -n topolvm-system; kubectl delete ns topolvm-system; rm -r /root/helm/topolvm
## Tests: dd if=/dev/zero of=/tmp/laptop.bin bs=1G count=1 oflag=direct
# M.2 Drive: 156 MB/s
# USB-C 3.1: 682 MB/s
# USB-A 3.1: 682 MB/s
# USB-A 3.0: 325/MB/s
# NVme PCI 4.0 Direct: 589 MB/s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment