K3s over Tailnet
I set my home lab is set up with K3s. This is great, but I'd like to access it from not just inside my dungeon.
To make this happen, I set up the network with Tailscale. With a NixOS, this is dirt-simple:
{ lib, config, ... }: {
options = { tailscale.enable = lib.mkEnableOption "Enable Tailscale"; };
config = { services.tailscale.enable = config.tailscale.enable; };
}
I added the Tailnet IP to the ~/.kube/config.
apiVersion: v1
clusters:
- cluster:
server: https://<Tailnet IP>:6443
name: default
kubectl get nodes...
Unable to connect to the server: tls: failed to verify certificate: x509: certificate is valid for <Internal IP>
not <Tailnet IP>
D: Lets make sure we can actually reach the nodes over the Tailnet...
$ k get nodes --insecure-skip-tls-verify
NAME STATUS ROLES AGE VERSION
leonardo Ready <none> 9d v1.34.1+k3s1
raphael Ready <none> 20d v1.32.4+k3s1
splinter Ready control-plane,etcd,master 95d v1.32.7+k3s1
Yeah seems like we can.
After a bit more reading, it looks like we need to rotate the cert for the new IP Luckily there's nothing important running on this cluster!
Let's just restart the master node... And nothing.
After a bit more digging, this issue looks promising Remote Kubectl
We need to edit the k3s-serving secret in the kube-system to include the new Tailnet IP of the master node.
kind: Secret
metadata:
annotations:
listener.cattle.io/cn-<Internal IP>: 10.0.0.10
listener.cattle.io/cn-<Tailnet IP>: 10.43.0.1
After modifying the cluster secret and k3s regenerate certificates, we are back in business.
$ k get nodes
NAME STATUS ROLES AGE VERSION
donatello Ready <none> 8d v1.32.4+k3s1
leonardo Ready <none> 30d v1.34.1+k3s1
raphael Ready <none> 41d v1.32.4+k3s1
splinter Ready control-plane,etcd,master 116d v1.32.7+k3s1
Future Me
Is this reproducible? Probably not. Since the certs are already generated for the master node, I didn't feel like going through the exercise of completely bootstrapping the cluster again to test a reproducible setup with the new IP. To test this, we could add the following to the cluster settings.
if config.isK3sNode.isServer then [ "-tls-san=${hostTailIP}" ] else [ ];