Stream of Consciousness

Mark Eschbach's random writings on various topics.

HeadScale on Kubernetes

Categories: tech

Tags: kubernetes tailscale

HeadScale Experiment

I have used TailScale with a client and seems to work fairly well. I am hoping this integrates better than OpenVPN with less operational overhead for my family.

Effectively TailScale is an orchestration layer for Wireguard. Sometimes it uses the magic of DERP servers, their equivalent of STUN for NAT traversal.

Basics: A StatefulSet

HeadScale stores it’s data within a SQLite database with a configuration directory. There are several commands which are required to be run within the container.

apiVersion: v1
kind: Service
metadata:
  name: headscale
  labels:
    app: headscale
spec:
  ports:
  - port: 80
    targetPort: client
    name: client
  - port: 9090
    name: metrics
  - port: 50443
    name: control
  clusterIP: None
  selector:
    app: headscale
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: headscale
  serviceName: "headscale"
  replicas: 1
  minReadySeconds: 1
  template:
    metadata:
      labels:
        app: headscale
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: headscale
        # https://hub.docker.com/r/headscale/headscale/tags
        image: headscale/headscale:v0.25
        ports:
        - containerPort: 8080
          name: clients
        - containerPort: 9090
          name: metrics
        - containerPort: 50443
          name: control
        volumeMounts:
        - name: state
          mountPath: /var/lib/headscale
        - name: config
          mountPath: /etc/headscale
        livenessProbe:
          httpGet:
            path: /
            port: client
          initialDelaySeconds: 5
          periodSeconds: 5
        readinessProbe:
          httpGet:
            path: /
            port: client
          initialDelaySeconds: 5
          periodSeconds: 5
      volumes:
        - name: config
          configMap:
            name: headscale-config
  volumeClaimTemplates:
  - metadata:
      name: state
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "longhorn"
      resources:
        requests:
          storage: 1Gi

Setting up MacOS client

There are several UIs out there. However, the HeadScale debug image does provide a fully functional CLI to work against the service. A bit of a dance between the client device and the service without it but worth learning how on the CLI.

kubectl exec --namespace family-headscale headscale-0 -- headscale users create mark
/Applications/Tailscale.app/Contents/MacOS/Tailscale login --login-server "https://headscale.example.org"
kubectl exec --namespace family-headscale headscale-0 -- headscale nodes
# use the key shown in the prior command to register a code
kubectl exec --namespace family-headschale headscale-0 -- headscale nodes register --user mark --key UbrmlnL8LyoKe