Passed cilium connectivity tests as a worker node
This commit is contained in:
196
devtools/create-join-token.sh
Executable file
196
devtools/create-join-token.sh
Executable file
@@ -0,0 +1,196 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
ROOT_DIR="$(realpath "$SCRIPT_DIR/..")"
|
||||
LIB_DIR="$ROOT_DIR/scripts"
|
||||
CLUSTER_ENV_WORK="${CLUSTER_ENV_WORK:-$ROOT_DIR/configs/cluster.env.work}"
|
||||
|
||||
KUBECTL="${KUBECTL:-kubectl}"
|
||||
TTL_HOURS="${TTL_HOURS:-24}"
|
||||
WAIT_SECONDS="${WAIT_SECONDS:-30}"
|
||||
|
||||
need() {
|
||||
command -v "$1" >/dev/null 2>&1 || {
|
||||
echo "missing required command: $1" >&2
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
rfc3339_after_hours() {
|
||||
hours="$1"
|
||||
|
||||
# GNU date
|
||||
if date -u -d "+${hours} hours" '+%Y-%m-%dT%H:%M:%SZ' >/dev/null 2>&1; then
|
||||
date -u -d "+${hours} hours" '+%Y-%m-%dT%H:%M:%SZ'
|
||||
return
|
||||
fi
|
||||
|
||||
# BSD/macOS date
|
||||
if date -u -v+"${hours}"H '+%Y-%m-%dT%H:%M:%SZ' >/dev/null 2>&1; then
|
||||
date -u -v+"${hours}"H '+%Y-%m-%dT%H:%M:%SZ'
|
||||
return
|
||||
fi
|
||||
|
||||
echo "cannot compute expiration time with this date(1). Set EXPIRATION manually." >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
decode_base64_to_file() {
|
||||
input="$1"
|
||||
output="$2"
|
||||
|
||||
if printf '%s' "$input" | base64 -d >"$output" 2>/dev/null; then
|
||||
return
|
||||
fi
|
||||
|
||||
if printf '%s' "$input" | base64 -D >"$output" 2>/dev/null; then
|
||||
return
|
||||
fi
|
||||
|
||||
if printf '%s' "$input" | openssl base64 -d -A >"$output" 2>/dev/null; then
|
||||
return
|
||||
fi
|
||||
|
||||
echo "failed to decode certificate-authority-data" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
need "$KUBECTL"
|
||||
need openssl
|
||||
need awk
|
||||
need sed
|
||||
|
||||
TOKEN_ID="${TOKEN_ID:-$(openssl rand -hex 3)}"
|
||||
TOKEN_SECRET="${TOKEN_SECRET:-$(openssl rand -hex 8)}"
|
||||
TOKEN="${TOKEN_ID}.${TOKEN_SECRET}"
|
||||
SECRET_NAME="bootstrap-token-${TOKEN_ID}"
|
||||
|
||||
if [ "${TTL_HOURS}" = "0" ]; then
|
||||
EXPIRATION=""
|
||||
else
|
||||
EXPIRATION="${EXPIRATION:-$(rfc3339_after_hours "$TTL_HOURS")}"
|
||||
fi
|
||||
|
||||
echo "Creating bootstrap token Secret: ${SECRET_NAME}" >&2
|
||||
|
||||
{
|
||||
cat <<EOF
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: ${SECRET_NAME}
|
||||
namespace: kube-system
|
||||
type: bootstrap.kubernetes.io/token
|
||||
stringData:
|
||||
description: "Join token created with kubectl"
|
||||
token-id: "${TOKEN_ID}"
|
||||
token-secret: "${TOKEN_SECRET}"
|
||||
usage-bootstrap-authentication: "true"
|
||||
usage-bootstrap-signing: "true"
|
||||
auth-extra-groups: "system:bootstrappers:kubeadm:default-node-token"
|
||||
EOF
|
||||
|
||||
if [ -n "$EXPIRATION" ]; then
|
||||
printf ' expiration: "%s"\n' "$EXPIRATION"
|
||||
fi
|
||||
} | "$KUBECTL" apply -f -
|
||||
|
||||
TMPDIR="$(mktemp -d)"
|
||||
trap 'rm -rf "$TMPDIR"' EXIT INT TERM
|
||||
|
||||
CA_FILE="$TMPDIR/ca.crt"
|
||||
|
||||
CA_DATA="$("$KUBECTL" config view --raw --minify --flatten -o jsonpath='{.clusters[0].cluster.certificate-authority-data}')"
|
||||
|
||||
if [ -z "$CA_DATA" ]; then
|
||||
echo "could not find certificate-authority-data in current kubeconfig" >&2
|
||||
echo "token was created, but cannot print a safe kubeadm join command" >&2
|
||||
echo "token: ${TOKEN}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
decode_base64_to_file "$CA_DATA" "$CA_FILE"
|
||||
|
||||
CA_HASH="$(
|
||||
openssl x509 -in "$CA_FILE" -pubkey -noout |
|
||||
openssl pkey -pubin -outform der 2>/dev/null |
|
||||
openssl dgst -sha256 -hex |
|
||||
awk '{print $2}'
|
||||
)"
|
||||
|
||||
SERVER="$("$KUBECTL" config view --raw --minify -o jsonpath='{.clusters[0].cluster.server}')"
|
||||
JOIN_ENDPOINT="$(printf '%s\n' "$SERVER" | sed -E 's#^https?://##')"
|
||||
|
||||
echo "Waiting for cluster-info signature for token ${TOKEN_ID}..." >&2
|
||||
|
||||
i=0
|
||||
signed="false"
|
||||
while [ "$i" -lt "$WAIT_SECONDS" ]; do
|
||||
template="{{ index .data \"jws-kubeconfig-${TOKEN_ID}\" }}"
|
||||
sig="$("$KUBECTL" -n kube-public get configmap cluster-info -o "go-template=${template}" 2>/dev/null || true)"
|
||||
|
||||
if [ -n "$sig" ]; then
|
||||
signed="true"
|
||||
break
|
||||
fi
|
||||
|
||||
i=$((i + 1))
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo
|
||||
echo "Token:"
|
||||
echo " ${TOKEN}"
|
||||
|
||||
if [ -n "$EXPIRATION" ]; then
|
||||
echo
|
||||
echo "Expires:"
|
||||
echo " ${EXPIRATION}"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "Join command:"
|
||||
echo " kubeadm join ${JOIN_ENDPOINT} --token ${TOKEN} --discovery-token-ca-cert-hash sha256:${CA_HASH}"
|
||||
|
||||
TMP_ENV="$(mktemp)"
|
||||
trap 'rm -f "$TMP_ENV"; rm -rf "$TMPDIR"' EXIT INT TERM
|
||||
|
||||
cat >"$TMP_ENV" <<EOF
|
||||
MKS_API_SERVER_ENDPOINT=${JOIN_ENDPOINT}
|
||||
MKS_BOOTSTRAP_TOKEN=${TOKEN}
|
||||
MKS_DISCOVERY_TOKEN_CA_CERT_HASH=sha256:${CA_HASH}
|
||||
EOF
|
||||
|
||||
echo
|
||||
echo "cluster-config:"
|
||||
cat "$TMP_ENV"
|
||||
|
||||
if [ ! -x "$LIB_DIR/merge-env.sh" ]; then
|
||||
echo "merge-env.sh not found or not executable: $LIB_DIR/merge-env.sh" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
"$LIB_DIR/merge-env.sh" "$TMP_ENV" "$CLUSTER_ENV_WORK"
|
||||
|
||||
echo
|
||||
echo "Merged into:"
|
||||
echo " $CLUSTER_ENV_WORK"
|
||||
echo
|
||||
echo "Try"
|
||||
cat <<EOF
|
||||
make cluster-config \\
|
||||
MKS_HOSTNAME=monok8s-worker \\
|
||||
MKS_CLUSTER_ROLE=worker \\
|
||||
MKS_INIT_CONTROL_PLANE=no \\
|
||||
MKS_MGMT_ADDRESS=10.0.0.10/24 \\
|
||||
MKS_APISERVER_ADVERTISE_ADDRESS=10.0.0.10 \\
|
||||
MKS_CNI_PLUGIN=none
|
||||
EOF
|
||||
|
||||
|
||||
if [ "$signed" != "true" ]; then
|
||||
echo >&2
|
||||
echo "warning: cluster-info was not signed within ${WAIT_SECONDS}s." >&2
|
||||
echo "If kubeadm join fails discovery, check that kube-controller-manager enables bootstrapsigner." >&2
|
||||
fi
|
||||
Reference in New Issue
Block a user