Skip to content

Procedure for shutting down a VKS cluster and sample scripts - #16

Merged
jswolf-vmware merged 6 commits into
vmware:mainfrom
dsu-igeek:topic/dsu/vks-shutdown-procedure-and-scripts-10-02-2026
Oct 8, 2026
Merged

jswolf-vmware merged 6 commits into
vmware:mainfrom
dsu-igeek:topic/dsu/vks-shutdown-procedure-and-scripts-10-02-2026

Conversation

@dsu-igeek

Copy link
Copy Markdown
Contributor

Documents the procedure for shutting down a VKS cluster. Also contains sample scripts that will do much of the procedure.

@legal-compliance-bot

Copy link
Copy Markdown

🛑 Legal Compliance Check Failed

Hi @dsu-igeek, thank you for your contribution!

To merge this Pull Request, you must sign our CLA.

Note: Even if you signed off your commits locally (using git commit -s), you must post the comment below to register your signature with our automated system.
Note: This is a one-time process. Once signed, future contributions to this repository will be verified automatically.

1. Read the Document: Click here to read the CLA
2. Sign via Comment: Copy and paste the exact line below into a new comment on this Pull Request:

I have read the CLA Document and I hereby sign the CLA for this and all future contributions.

⏳ Processing Schedule:
Our 'Compliance Sweeper' runs automatically approximately every 15-20 minutes.
After you post the comment, your status will update automatically during the next scheduled run.
You do not need to take any further action.

@dsu-igeek

Copy link
Copy Markdown
Contributor Author

I have read the CLA Document and I hereby sign the CLA for this and all future contributions.

@zjs zjs left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, this looks good to me.

Comment thread vks-cluster-shutdown.md

# Shutdown of a VKS Workload Cluster

Shutdown of a VKS Workload Cluster is the process of powering off all of the Control Plane and Worker Node VMs.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thought: What happens if the Supervisor or VKS is upgraded, or someone edits the Cluster, during the shutdown? Perhaps it'd be useful to include a section to tell readers not to perform some set of operations during the outage.

Comment on lines +185 to +190
ORIGINAL_CONTROL_PLANE_REPLICAS=$(
kubectl get cluster "$CLUSTER_NAME" -n "$KUBENAMESPACE" \
-o jsonpath='{.spec.topology.controlPlane.replicas}'
)
echo "Original number of control plane replicas: ${ORIGINAL_CONTROL_PLANE_REPLICAS}"
echo "Note this number - restart-vks-cluster.sh requires it: ./restart-vks-cluster.sh ${CLUSTER_NAME} ${ORIGINAL_CONTROL_PLANE_REPLICAS}"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Would it make sense to persist this (e.g., as an annotation on the Cluster, written if not already present) and have restart-vks-cluster.sh read it (and then clear it)? Printing to the terminal is probably fine, but this might reduce opportunity for mistakes (e.g., if terminal output is lost between shutdown and restart) and reduce the inputs required to restart.

if [[ -n "$in_progress" ]]; then
echo "Cluster ${CLUSTER_NAME} has operation(s) in progress (${in_progress}) - aborting" >&2
exit 1
fi

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: Do we need to either document that this flow only works on VKS versions that include Cluster API v1beta2 or fallback to reading from .status.v1beta2.conditions?

Comment on lines +85 to +88
confirm_prerequisites

# Verifies every required env var is set and usable
check_env() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: Would it be better to do the prechecking before we prompt the user to confirm they've completed the prerequisites?

# shellcheck disable=SC2034 # out_ref is a nameref: assignment writes to the caller's array
get_provider_ids_array() {
local selector="$1"
local -n out_ref=$2

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: Does local -n create any compatibility constraints? (Do we need to check for a sufficiently new bash version at the beginning of the script?)

fi

echo "Verifying access to the Supervisor cluster (\$KUBECONFIG)..."
if ! kubectl get namespace "$KUBENAMESPACE" >/dev/null; then

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: Should we explicitly check for the necessary tools (kubectl, govc, jq, etc.) so we can give clear errors if any are missing?

# grep -v exits 1 (no non-matching lines) when every pod is healthy -
# that's the success case, not an error, so `|| true` keeps set -e from
# treating it as one.
bad_pods=$(KUBECONFIG="$WORKLOAD_KUBECONFIG" kubectl get pods -A --no-headers 2>/dev/null | grep -viE "running|completed" || true)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: grep -viE "running|completed" treats a pod as healthy if the line contains either word anywhere (e.g., even in a pod name). Since this is the final "all good" signal for the restart, could we check readiness more explicitly, e.g. kubectl wait --for=condition=Ready pod --all -A or something along those lines.

Comment on lines +218 to +225
KCP_NAME=$(
kubectl get kubeadmcontrolplane -n "$KUBENAMESPACE" \
-l "cluster.x-k8s.io/cluster-name=${CLUSTER_NAME}" \
-o jsonpath='{.items[0].metadata.name}'
)

if [[ -z "$KCP_NAME" ]]; then
echo "Could not find KubeadmControlPlane for cluster '${CLUSTER_NAME}' in namespace '${KUBENAMESPACE}'" >&2

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: Seems like anything that causes kubectl to exit with an error code (e.g., .items not containing an element) is going to cause set -e to exit before we get to the friendly error message. Maybe -o name avoids this?

echo "$(date -u +%H:%M:%S) - still waiting on unhealthy pods:"
echo "$bad_pods"
sleep 10
done

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Since the user is told to save PDB copies as a prerequisite, would it be useful to include a closing reminder ("Remember to restore any Pod Disruption Budgets you removed before shutdown")?

@jswolf-vmware
jswolf-vmware merged commit 89f2b6b into vmware:main Oct 8, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants