Skip to content

Instantly share code, notes, and snippets.

@drjackild
Created June 10, 2025 03:10
Show Gist options
  • Save drjackild/e40d17de4e6e3f9b15679e8c2152034c to your computer and use it in GitHub Desktop.
Save drjackild/e40d17de4e6e3f9b15679e8c2152034c to your computer and use it in GitHub Desktop.
The minimum configuration to reproduce https://github.com/kubernetes/kubernetes/issues/116481
apiVersion: v1
kind: Pod
metadata:
name: sa-token-test-pod
namespace: default
spec:
terminationGracePeriodSeconds: 3600
containers:
- name: test-container
image: curlimages/curl:8.4.0
command: ["/bin/sh", "-c", "echo 'Container started, sleeping indefinitely...'; sleep infinity;"]
lifecycle:
preStop:
exec:
command:
- "/bin/sh"
- "-c"
- |
# all output is redirected to the main process's stdout to be captured by `kubectl logs`
echo "--- Hook Started: Initial API Health Check ---" > /proc/1/fd/1
SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
TOKEN=$(cat $SERVICEACCOUNT/token)
CACERT=$SERVICEACCOUNT/ca.crt
APISERVER=https://kubernetes.default.svc
echo "attempting initial API call to $APISERVER/api/..." > /proc/1/fd/1
# perform the first API call, this should succeed
STATUS_CODE=$(curl -s -o /dev/null -w "%{http_code}" --cacert $CACERT --header "Authorization: Bearer $TOKEN" -X GET $APISERVER/api/)
echo "initial API call returned HTTP status: $STATUS_CODE" > /proc/1/fd/1
# check if the status code indicates success (2xx range)
if [ "$STATUS_CODE" -ge 200 ] && [ "$STATUS_CODE" -lt 300 ]; then
echo "initial API call succeeded" > /proc/1/fd/1
else
echo "initial API call failed, exit" > /proc/1/fd/1
exit 1
fi
echo "" > /proc/1/fd/1
# wait for a duration longer than the token's lifetime (600s)
echo "sleeping for 700 seconds to allow token to expire..." > /proc/1/fd/1
sleep 700
echo "" > /proc/1/fd/1
echo "--- Woke up: Final API Health Check ---" > /proc/1/fd/1
echo "attempting final API call..." > /proc/1/fd/1
# The Kubelet should have rotated the token, but the bug is that it does not.
TOKEN_FINAL=$(cat $SERVICEACCOUNT/token)
STATUS_CODE_FINAL=$(curl -s -o /dev/null -w "%{http_code}" --cacert $CACERT --header "Authorization: Bearer $TOKEN_FINAL" -X GET $APISERVER/api/)
echo "final API call returned HTTP status: $STATUS_CODE_FINAL" > /proc/1/fd/1
if [ "$STATUS_CODE_FINAL" -ge 200 ] && [ "$STATUS_CODE_FINAL" -lt 300 ]; then
echo "final API call succeeded. Token was likely rotated. Bug NOT confirmed." > /proc/1/fd/1
else
echo "final API call failed (status: $STATUS_CODE_FINAL). Token likely EXPIRED. Bug confirmed." > /proc/1/fd/1
fi
echo "" > /proc/1/fd/1
echo "--- Hook Finished ---" > /proc/1/fd/1
volumeMounts:
- name: kube-api-access
mountPath: /var/run/secrets/kubernetes.io/serviceaccount
readOnly: true
volumes:
- name: kube-api-access
projected:
sources:
- serviceAccountToken:
path: token
expirationSeconds: 600
- configMap:
name: kube-root-ca.crt
items:
- key: ca.crt
path: ca.crt
- downwardAPI:
items:
- path: "namespace"
fieldRef:
fieldPath: metadata.namespace
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment