Skip to content

Instantly share code, notes, and snippets.

@ademidoff
Last active November 27, 2025 23:22
Show Gist options
  • Select an option

  • Save ademidoff/041c114c860ae241c7996e2453bdd65d to your computer and use it in GitHub Desktop.

Select an option

Save ademidoff/041c114c860ae241c7996e2453bdd65d to your computer and use it in GitHub Desktop.
k8s-pmm
#!/bin/bash
set -e
# eksctl utils describe-stacks --region=us-east-2 --cluster=pmm-ha
# ClickHouse
#
# for i in {0..2}; do echo "pmm-ha-pmmdb-0-$i-0"; \
# kubectl exec "pmm-ha-pmmdb-0-$i-0" -n pmmha -- \
# clickhouse client --user=chuser --password=chpass --query "SHOW CREATE TABLE pmm.schema_migrations;"; \
# done
# for i in {0..2}; do echo "pmm-ha-pmmdb-0-$i-0"; \
# kubectl exec "pmm-ha-pmmdb-0-$i-0" -n pmmha -- \
# clickhouse client --user=chuser --password=chpass --query "SELECT * FROM pmm.schema_migrations;"; \
# done
# PMM Servers
# for i in {0..2}; do echo "pmm-ha-$i"; kubectl exec "pmm-ha-$i" -n pmmha -c pmm-ha -- cat /etc/secrets/key; done && echo
declare action="start"
declare unattended=0
declare step=1
usage() {
cat <<EOF
Usage: $0 [OPTIONS]
-s|--start Start the cluster
-k|--stop Stop the cluster
EOF
}
prompt_confirm() {
echo ""
echo "$1..."
step=$((step + 1))
if [ "$unattended" -eq 1 ]; then
return 0
fi
while true; do
echo
read -n 1 -r -p "$1 [Y/n/x]: " answer
echo
case $answer in
[Yy]*) return 0 ;;
[Nn]*) return 1 ;;
[Xx]*) exit 0 ;;
*) echo "Please answer yes or no.";;
esac
done
}
cluster_start() {
if [ -d pmm-ha ]; then
cd pmm-ha
fi
if [ ! -f values.yaml ]; then
echo "Error: values.yaml not found in the current directory, exiting..."
return 1
fi
if prompt_confirm "Step $step: Create a namespace"; then
kubectl create namespace pmmha
fi
# if prompt_confirm "Step 2: Configure the storage class"; then
# cat <<EOF | kubectl create -f -
# apiVersion: storage.k8s.io/v1
# kind: StorageClass
# metadata:
# name: auto-ebs-sc
# annotations:
# storageclass.kubernetes.io/is-default-class: "true"
# provisioner: ebs.csi.eks.amazonaws.com
# volumeBindingMode: WaitForFirstConsumer
# parameters:
# type: gp3
# encrypted: "true"
# EOF
# fi
if prompt_confirm "Step $step: Add PostgreSQL users"; then
cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Secret
metadata:
name: pmm-secret
namespace: pmmha
labels:
app.kubernetes.io/name: pmm
type: Opaque
data:
PMM_ADMIN_PASSWORD: YWRtaW4=
PMM_POSTGRES_USERNAME: cG1tdXNlcg==
PMM_POSTGRES_DBPASSWORD: cG1tcGFzcw==
GF_USERNAME: Z2Z1c2Vy
GF_PASSWORD: Z2ZwYXNz
VMAGENT_remoteWrite_basicAuth_username: dm11c2Vy
VMAGENT_remoteWrite_basicAuth_password: dm1wYXNz
PMM_CLICKHOUSE_USER: Y2h1c2Vy
PMM_CLICKHOUSE_PASSWORD: Y2hwYXNz
EOF
fi
if prompt_confirm "Step $step: Add a configmap to create PG database users"; then
cat <<EOF | kubectl create -f -
apiVersion: v1
kind: ConfigMap
metadata:
name: cluster1-init-sql
namespace: pmmha
data:
init.sql: |
CREATE DATABASE grafana;
CREATE DATABASE "pmm-managed";
CREATE USER pmmuser WITH SUPERUSER ENCRYPTED PASSWORD 'pmmpass';
CREATE USER gfuser WITH SUPERUSER ENCRYPTED PASSWORD 'gfpass';
GRANT ALL PRIVILEGES ON DATABASE "pmm-managed" TO pmmuser;
GRANT ALL PRIVILEGES ON DATABASE grafana TO gfuser;
\\c pmm-managed
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
EOF
fi
if ! test -f "pmm.key" && prompt_confirm "Step $step: Create certificates for HAProxy"; then
openssl genrsa -out pmm.key 2048
openssl req -new -x509 -key pmm.key -out pmm.crt -days 365 -subj "/C=US/ST=State/L=City/O=Organization/CN=pmmha"
cat pmm.crt pmm.key > pmm.pem
fi
if ! kubectl get secret -n pmmha | grep -q "haproxy-tls-secret"; then
kubectl create secret generic haproxy-tls-secret --from-file=pmm.pem -n pmmha
kubectl label secret haproxy-tls-secret -n pmmha app.kubernetes.io/managed-by=Helm
kubectl annotate secret haproxy-tls-secret -n pmmha meta.helm.sh/release-name=pmm-ha
kubectl annotate secret haproxy-tls-secret -n pmmha meta.helm.sh/release-namespace=pmmha
rm pmm.{crt,key,pem}
fi
if prompt_confirm "Step $step: Install PMM HA Helm Chart"; then
helm install pmm-ha . -n pmmha
fi
# if prompt_confirm "Step 7: Wait until everything is running and healthy"; then
# echo "Please check the status of your pods and wait until everything is healthy."
# fi
# if prompt_confirm "Step 8: Port forward the PMM dashboard endpoint"; then
# kubectl port-forward --namespace pmmha svc/pmm-ha-haproxy 3000:443 &
# echo "Port forwarding started. You can access the PMM dashboard at https://127.0.0.1:3000"
# echo "Endpoint for pmm-clients: https://pmm-ha-haproxy.pmmha.svc.cluster.local:443"
# echo "You can access the PMM dashboard via the LoadBalancer or Ingress you have configured."
# echo ""
# else
echo "Run the following command to port-forward PMM UI: kubectl port-forward --namespace pmmha svc/pmm-ha-haproxy 3000:443 &"
echo ""
# fi
}
cluster_stop() {
if prompt_confirm "Step $step: Uninstall the helm chart"; then
helm uninstall pmm-ha -n pmmha
fi
if prompt_confirm "Step $step: Delete finalizers"; then
kubectl delete job pre-delete-check-pg-clusters -n pmmha --ignore-not-found
kubectl patch clickhouseinstallation pmm-ha -n pmmha -p '{"metadata":{"finalizers":[]}}' --type=merge || :
# kubectl delete clickhouseinstallation pmm-ha -n pmmha || :
kubectl patch perconapgclusters.pgv2.percona.com pmm-ha-pg-db -n pmmha -p '{"metadata":{"finalizers":[]}}' --type=merge || :
kubectl patch postgrescluster.postgres-operator.crunchydata.com pmm-ha-pg-db -n pmmha -p '{"metadata":{"finalizers":[]}}' --type=merge || :
fi
if prompt_confirm "Step $step: Delete all secrets, configmaps and other resources"; then
kubectl delete secret --all -n pmmha
kubectl delete configmap --all -n pmmha
# kubectl delete statefulset --all -n pmmha --ignore-not-found
kubectl delete job --all -n pmmha --ignore-not-found
# kubectl delete clusterrolebinding --all -n pmmha --ignore-not-found
# kubectl delete clusterrole --all -n pmmha --ignore-not-found
kubectl delete serviceaccount --all -n pmmha --ignore-not-found
kubectl delete all --all -n pmmha
fi
if prompt_confirm "Step $step: Delete all PVCs"; then
kubectl delete pvc --all -n pmmha
fi
# if prompt_confirm "Step 5: Delete the storage class"; then
# kubectl delete storageclass auto-ebs-sc
# fi
if prompt_confirm "Step $step: Delete the namespace"; then
kubectl delete namespace pmmha --grace-period=5
fi
if test -f pmm.key && prompt_confirm "Step $step: Delete the temporary certificates"; then
rm -f pmm.{crt,key,pem}
echo "Temporary certificates deleted."
fi
}
while [ $# -ne 0 ]; do
case "$1" in
-y|--yes)
unattended=1
;;
-s|--start)
action="start"
;;
-k|--stop)
action="stop"
;;
-h|--help)
usage
exit 0
;;
*)
echo "Unknown option: $1"
usage
exit 1
;;
esac
shift
done
if [ "$action" = "start" ]; then
cluster_start
elif [ "$action" = "stop" ]; then
cluster_stop
else
usage
exit 1
fi
echo
echo "All steps completed."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment