Created
July 25, 2024 18:57
-
-
Save maelvls/adf680ae01612ff79658872c7dca013f to your computer and use it in GitHub Desktop.
kind-tailscale makes your Kind cluster's API server available to the internet, including the OpenID Configuration and JWKS endpoints.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# shellcheck disable=SC2059 | |
set -eo pipefail | |
help() { | |
cat <<EOF | |
A script to expose your Kind cluster's API server to the internet using | |
Tailscale Funnel. To do that, the API server's --service-account-issuer and | |
--service-account-jwks-uri are updated, and the API server's certificate SANs | |
are updated to include the funnel's hostname. | |
Usage: kind-tailscale | |
Options: | |
--name cluster The name of the Kind cluster to configure. Default: kind. | |
EOF | |
} | |
yel=$(tput setaf 3) | |
gray=$(tput setaf 8) | |
red=$(tput setaf 1) | |
end=$(tput sgr0) | |
# color "$yel" | |
color() { | |
# Let's prevent accidental interference from programs that also print colors. | |
# Caveat: does only work on lines that end with \n. Lines that do not end with | |
# \n are discarded. | |
sed -r "s/\x1B\[([0-9]{1,3}(;[0-9]{1,2})?)?[mGK]//g" | while read -r line; do | |
printf "${1}%s${end}\n" "$line" | |
done | |
} | |
name=kind | |
while [ $# -gt 0 ]; do | |
case "$1" in | |
--name) | |
name="$2" | |
shift | |
;; | |
--help) | |
help | |
exit 0 | |
;; | |
-*) | |
printf "${red}error${end}: unknown option: $1\n" | |
;; | |
*) | |
printf "${red}error${end}: unknown argument: $1\n" | |
;; | |
esac | |
shift | |
done | |
docker exec "$name-control-plane" kubectl create clusterrolebinding oidc-reviewer --clusterrole=system:service-account-issuer-discovery --group=system:unauthenticated --dry-run=client -o yaml \ | |
| docker exec -i "$name-control-plane" kubectl apply -f - | color "$gray" | |
hostname=$(tailscale status --json | jq -r .Self.DNSName | sed 's/\.$//') | |
# Tailscale Funnel only supports 443, 8443, and 10000. | |
addr_oidc_discovery=$hostname:8443 | |
addr_kubeconfig=$hostname:10000 | |
docker exec -i "$name-control-plane" bash <<EOF 2>&1 | color "$gray" || exit 1 | |
if ! command -v yq >/dev/null; then | |
curl -LO https://github.com/mikefarah/yq/releases/download/v4.43.1/yq_linux_arm64 | |
install yq_linux_arm64 /usr/local/bin/yq | |
fi | |
yq 'select(.kind == "ClusterConfiguration").apiServer.certSANs = ["localhost", "127.0.0.1", "$hostname"]' -i /kind/kubeadm.conf | |
yq 'del(select(.kind == "ClusterConfiguration").apiServer.extraArgs | select(."service-account-issuer"))' -i /kind/kubeadm.conf | |
yq 'del(select(.kind == "ClusterConfiguration").apiServer.extraArgs | select(."service-account-jwks-uri"))' -i /kind/kubeadm.conf | |
yq 'select(.kind == "ClusterConfiguration").apiServer.extraArgs += {"service-account-jwks-uri": "https://$addr_oidc_discovery/openid/v1/jwks"}' -i /kind/kubeadm.conf | |
yq 'select(.kind == "ClusterConfiguration").apiServer.extraArgs += {"service-account-issuer": "https://$addr_oidc_discovery"}' -i /kind/kubeadm.conf | |
kubeadm init phase control-plane apiserver --config /kind/kubeadm.conf | |
rm -f /etc/kubernetes/pki/apiserver.key /etc/kubernetes/pki/apiserver.crt | |
kubeadm init phase certs apiserver --config /kind/kubeadm.conf | |
EOF | |
localport=$(docker inspect "$name-control-plane" | jq -r '.[].HostConfig.PortBindings[][].HostPort') | |
tailscale funnel --bg --https "${addr_oidc_discovery/*:/}" "https+insecure://127.0.0.1:$localport" 2>&1 | color "$gray" | |
tailscale funnel --bg --tcp "${addr_kubeconfig/*:/}" "tcp://127.0.0.1:$localport" 2>&1 | color "$gray" | |
cat <<EOF | |
The OIDC discovery endpoint is: ${yel}https://$addr_oidc_discovery/.well-known/openid-configuration${end} | |
You can now share your cluster by sharing the kubeconfig with the following | |
command (the second command tests that the kubeconfig works): | |
${yel} | |
kind get kubeconfig -n $name | sed "s/127.0.0.1:[0-9]*/$addr_kubeconfig/" >kubeconfig | |
kubectl --kubeconfig kubeconfig get nodes | |
${end} | |
EOF |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment