Skip to content

Instantly share code, notes, and snippets.

@Slach
Last active November 17, 2023 06:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Slach/c9b44384db494c93119360bbd740df45 to your computer and use it in GitHub Desktop.
Save Slach/c9b44384db494c93119360bbd740df45 to your computer and use it in GitHub Desktop.
try to upgrade statefulset image without restart all clusters
#!/usr/bin/env bash
# RUN UNDER LINUX only
set -eo pipefail
CUR_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
pushd "${CUR_DIR}"
CONTEXT=$1
kubectl config use-context "${CONTEXT}"
CHI=$2
CLICKHOUSE_BACKUP_IMAGE=$3
CLICKHOUSE_BACKUP_IMAGE_ESCAPED=$(echo "$3" | sed 's/\//\\\//g')
NAMESPACE=$(kubectl get chi --all-namespaces -o json | jq -M -c -r ".items[] | select(.metadata.name == \"${CHI}\") | .metadata.namespace")
STS_NAMES=$(kubectl get sts -n "${NAMESPACE}" -l "clickhouse.altinity.com/chi=${CHI},clickhouse.altinity.com/app!=zookeeper" -o name | sed 's/statefulset\.apps\///')
echo ${STS_NAMES} | while read STS; do
STS_FILE="${CONTEXT}.${NAMESPACE}.${STS}"
POD_FILE="${STS_FILE}-0.pod"
kubectl get sts -n "${NAMESPACE}" "${STS}" -o yaml > "$STS_FILE.orig.yaml"
kubectl get pod -n "${NAMESPACE}" "${STS}-0" -o yaml > "$POD_FILE.orig.yaml"
sed -E "s/image:.+clickhouse\-backup.+/image: ${CLICKHOUSE_BACKUP_IMAGE_ESCAPED}/g" "$STS_FILE.orig.yaml" > "$STS_FILE.patched.yaml"
sed -E "s/image:.+clickhouse\-backup.+/image: ${CLICKHOUSE_BACKUP_IMAGE_ESCAPED}/g" "$POD_FILE.orig.yaml" > "$POD_FILE.patched.yaml"
# diff -u "$STS_FILE.orig.yaml" "$STS_FILE.patched.yaml" | delta --side-by-side
kubectl delete sts --cascade=orphan -n "${NAMESPACE}" "${STS}"
OWNER_REFERENCES=$(yq -M -o json -e '.metadata.ownerReferences' "$POD_FILE.orig.yaml" | jq -M -r -c)
kubectl patch pod -n "${NAMESPACE}" "${STS}-0" --type="json" -p='[{"op": "replace", "path": "/spec/containers/1/image", "value": "'${CLICKHOUSE_BACKUP_IMAGE}'"}]'
sleep 5
# kubectl describe pod -n "${NAMESPACE}" "${STS}-0"
# after patch ownerReference pod terminated
# kubectl patch pod -n "${NAMESPACE}" "${STS}-0" --type="json" -p='[{"op": "replace", "path": "/metadata/ownerReferences", "value": '${OWNER_REFERENCES}'}]'
# sleep 20
kubectl get pods -n "${NAMESPACE}" -l "clickhouse.altinity.com/chi=${CHI},clickhouse.altinity.com/app!=zookeeper"
# kubectl describe pod -n "${NAMESPACE}" "${STS}-0"
kubectl get pod -n "${NAMESPACE}" "${STS}-0" -o yaml > "$POD_FILE.patched2.yaml"
# kubectl get pods -n "${NAMESPACE}" -l "clickhouse.altinity.com/chi=${CHI},clickhouse.altinity.com/app!=zookeeper"
# after return statefulset with new image pod will terminated
kubectl apply --cascade=orphan --validate=false -n ${NAMESPACE} -f "$STS_FILE.patched.yaml"
sleep 1
UPDATE_REVISION=$(kubectl get sts -n "${NAMESPACE}" "${STS}" -o jsonpath='{.status.updateRevision}')
kubectl patch pod -n "${NAMESPACE}" "${STS}-0" --type="json" -p='[{"op": "replace", "path": "/metadata/labels/controller-revision-hash", "value": "'${UPDATE_REVISION}'"}]'
for i in {1..5}; do
kubectl get pods -n "${NAMESPACE}" -l "clickhouse.altinity.com/chi=${CHI},clickhouse.altinity.com/app!=zookeeper"
sleep 1
done
kubectl get pod -n "${NAMESPACE}" "${STS}-0" -o yaml > "$POD_FILE.patched3.yaml"
diff -u "$STS_FILE.orig.yaml" "$STS_FILE.patched.yaml" | delta --side-by-side || true
diff -u "$POD_FILE.patched.yaml" "$POD_FILE.patched2.yaml" | delta --side-by-side || true
diff -u "$POD_FILE.patched2.yaml" "$POD_FILE.patched3.yaml" | delta --side-by-side || true
done
popd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment