diff --git a/examples/README.md b/examples/README.md deleted file mode 100644 index f9e85ff3..00000000 --- a/examples/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Examples - -This directory contains examples on how to run `headscale` on different platforms. - -All examples are provided by the community and they are not verified by the `headscale` authors. diff --git a/examples/kustomize/.gitignore b/examples/kustomize/.gitignore deleted file mode 100644 index 229058d2..00000000 --- a/examples/kustomize/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/**/site -/**/secrets diff --git a/examples/kustomize/README.md b/examples/kustomize/README.md deleted file mode 100644 index cc57f147..00000000 --- a/examples/kustomize/README.md +++ /dev/null @@ -1,100 +0,0 @@ -# Deploying headscale on Kubernetes - -**Note:** This is contributed by the community and not verified by the headscale authors. - -This directory contains [Kustomize](https://kustomize.io) templates that deploy -headscale in various configurations. - -These templates currently support Rancher k3s. Other clusters may require -adaptation, especially around volume claims and ingress. - -Commands below assume this directory is your current working directory. - -# Generate secrets and site configuration - -Run `./init.bash` to generate keys, passwords, and site configuration files. - -Edit `base/site/public.env`, changing `public-hostname` to the public DNS name -that will be used for your headscale deployment. - -Set `public-proto` to "https" if you're planning to use TLS & Let's Encrypt. - -Configure DERP servers by editing `base/site/derp.yaml` if needed. - -# Add the image to the registry - -You'll somehow need to get `headscale:latest` into your cluster image registry. - -An easy way to do this with k3s: - -- Reconfigure k3s to use docker instead of containerd (`k3s server --docker`) -- `docker build -t headscale:latest ..` from here - -# Create the namespace - -If it doesn't already exist, `kubectl create ns headscale`. - -# Deploy headscale - -## sqlite - -`kubectl -n headscale apply -k ./sqlite` - -## postgres - -`kubectl -n headscale apply -k ./postgres` - -# TLS & Let's Encrypt - -Test a staging certificate with your configured DNS name and Let's Encrypt. - -`kubectl -n headscale apply -k ./staging-tls` - -Replace with a production certificate. - -`kubectl -n headscale apply -k ./production-tls` - -## Static / custom TLS certificates - -Only Let's Encrypt is supported. If you need other TLS settings, modify or patch the ingress. - -# Administration - -Use the wrapper script to remotely operate headscale to perform administrative -tasks like creating namespaces, authkeys, etc. - -``` -[c@nix-slate:~/Projects/headscale/k8s]$ ./headscale.bash - -headscale is an open source implementation of the Tailscale control server - -https://github.com/juanfont/headscale - -Usage: - headscale [command] - -Available Commands: - help Help about any command - namespace Manage the namespaces of headscale - node Manage the nodes of headscale - preauthkey Handle the preauthkeys in headscale - routes Manage the routes of headscale - serve Launches the headscale server - version Print the version. - -Flags: - -h, --help help for headscale - -o, --output string Output format. Empty for human-readable, 'json' or 'json-line' - -Use "headscale [command] --help" for more information about a command. - -``` - -# TODO / Ideas - -- Interpolate `email:` option to the ClusterIssuer from site configuration. - This probably needs to be done with a transformer, kustomize vars don't seem to work. -- Add kustomize examples for cloud-native ingress, load balancer -- CockroachDB for the backend -- DERP server deployment -- Tor hidden service diff --git a/examples/kustomize/base/configmap.yaml b/examples/kustomize/base/configmap.yaml deleted file mode 100644 index 0ac2d563..00000000 --- a/examples/kustomize/base/configmap.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: headscale-config -data: - server_url: $(PUBLIC_PROTO)://$(PUBLIC_HOSTNAME) - listen_addr: "0.0.0.0:8080" - metrics_listen_addr: "127.0.0.1:9090" - ephemeral_node_inactivity_timeout: "30m" diff --git a/examples/kustomize/base/ingress.yaml b/examples/kustomize/base/ingress.yaml deleted file mode 100644 index 51da3427..00000000 --- a/examples/kustomize/base/ingress.yaml +++ /dev/null @@ -1,18 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: headscale - annotations: - kubernetes.io/ingress.class: traefik -spec: - rules: - - host: $(PUBLIC_HOSTNAME) - http: - paths: - - backend: - service: - name: headscale - port: - number: 8080 - path: / - pathType: Prefix diff --git a/examples/kustomize/base/kustomization.yaml b/examples/kustomize/base/kustomization.yaml deleted file mode 100644 index 93278f7d..00000000 --- a/examples/kustomize/base/kustomization.yaml +++ /dev/null @@ -1,42 +0,0 @@ -namespace: headscale -resources: - - configmap.yaml - - ingress.yaml - - service.yaml -generatorOptions: - disableNameSuffixHash: true -configMapGenerator: - - name: headscale-site - files: - - derp.yaml=site/derp.yaml - envs: - - site/public.env - - name: headscale-etc - literals: - - config.json={} -secretGenerator: - - name: headscale - files: - - secrets/private-key -vars: - - name: PUBLIC_PROTO - objRef: - kind: ConfigMap - name: headscale-site - apiVersion: v1 - fieldRef: - fieldPath: data.public-proto - - name: PUBLIC_HOSTNAME - objRef: - kind: ConfigMap - name: headscale-site - apiVersion: v1 - fieldRef: - fieldPath: data.public-hostname - - name: CONTACT_EMAIL - objRef: - kind: ConfigMap - name: headscale-site - apiVersion: v1 - fieldRef: - fieldPath: data.contact-email diff --git a/examples/kustomize/base/service.yaml b/examples/kustomize/base/service.yaml deleted file mode 100644 index 39e67253..00000000 --- a/examples/kustomize/base/service.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: headscale - labels: - app: headscale -spec: - selector: - app: headscale - ports: - - name: http - targetPort: http - port: 8080 diff --git a/examples/kustomize/headscale.bash b/examples/kustomize/headscale.bash deleted file mode 100755 index 66bfe92c..00000000 --- a/examples/kustomize/headscale.bash +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash -set -eu -exec kubectl -n headscale exec -ti pod/headscale-0 -- /go/bin/headscale "$@" diff --git a/examples/kustomize/init.bash b/examples/kustomize/init.bash deleted file mode 100755 index e5b7965c..00000000 --- a/examples/kustomize/init.bash +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env bash -set -eux -cd $(dirname $0) - -umask 022 -mkdir -p base/site/ -[ ! -e base/site/public.env ] && ( - cat >base/site/public.env < base/secrets/private-key -) -mkdir -p postgres/secrets/ -[ ! -e postgres/secrets/password ] && (head -c 32 /dev/urandom | base64 -w0 > postgres/secrets/password) diff --git a/examples/kustomize/install-cert-manager.bash b/examples/kustomize/install-cert-manager.bash deleted file mode 100755 index 1a5ecacb..00000000 --- a/examples/kustomize/install-cert-manager.bash +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash -set -eux -kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.4.0/cert-manager.yaml diff --git a/examples/kustomize/postgres/deployment.yaml b/examples/kustomize/postgres/deployment.yaml deleted file mode 100644 index 1dd88b41..00000000 --- a/examples/kustomize/postgres/deployment.yaml +++ /dev/null @@ -1,81 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: headscale -spec: - replicas: 2 - selector: - matchLabels: - app: headscale - template: - metadata: - labels: - app: headscale - spec: - containers: - - name: headscale - image: "headscale:latest" - imagePullPolicy: IfNotPresent - command: ["/go/bin/headscale", "serve"] - env: - - name: SERVER_URL - value: $(PUBLIC_PROTO)://$(PUBLIC_HOSTNAME) - - name: LISTEN_ADDR - valueFrom: - configMapKeyRef: - name: headscale-config - key: listen_addr - - name: METRICS_LISTEN_ADDR - valueFrom: - configMapKeyRef: - name: headscale-config - key: metrics_listen_addr - - name: DERP_MAP_PATH - value: /vol/config/derp.yaml - - name: EPHEMERAL_NODE_INACTIVITY_TIMEOUT - valueFrom: - configMapKeyRef: - name: headscale-config - key: ephemeral_node_inactivity_timeout - - name: DB_TYPE - value: postgres - - name: DB_HOST - value: postgres.headscale.svc.cluster.local - - name: DB_PORT - value: "5432" - - name: DB_USER - value: headscale - - name: DB_PASS - valueFrom: - secretKeyRef: - name: postgresql - key: password - - name: DB_NAME - value: headscale - ports: - - name: http - protocol: TCP - containerPort: 8080 - livenessProbe: - tcpSocket: - port: http - initialDelaySeconds: 30 - timeoutSeconds: 5 - periodSeconds: 15 - volumeMounts: - - name: config - mountPath: /vol/config - - name: secret - mountPath: /vol/secret - - name: etc - mountPath: /etc/headscale - volumes: - - name: config - configMap: - name: headscale-site - - name: etc - configMap: - name: headscale-etc - - name: secret - secret: - secretName: headscale diff --git a/examples/kustomize/postgres/kustomization.yaml b/examples/kustomize/postgres/kustomization.yaml deleted file mode 100644 index e732e3b9..00000000 --- a/examples/kustomize/postgres/kustomization.yaml +++ /dev/null @@ -1,13 +0,0 @@ -namespace: headscale -bases: - - ../base -resources: - - deployment.yaml - - postgres-service.yaml - - postgres-statefulset.yaml -generatorOptions: - disableNameSuffixHash: true -secretGenerator: - - name: postgresql - files: - - secrets/password diff --git a/examples/kustomize/postgres/postgres-service.yaml b/examples/kustomize/postgres/postgres-service.yaml deleted file mode 100644 index 6252e7f9..00000000 --- a/examples/kustomize/postgres/postgres-service.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: postgres - labels: - app: postgres -spec: - selector: - app: postgres - ports: - - name: postgres - targetPort: postgres - port: 5432 diff --git a/examples/kustomize/postgres/postgres-statefulset.yaml b/examples/kustomize/postgres/postgres-statefulset.yaml deleted file mode 100644 index b81c9bf0..00000000 --- a/examples/kustomize/postgres/postgres-statefulset.yaml +++ /dev/null @@ -1,49 +0,0 @@ -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: postgres -spec: - serviceName: postgres - replicas: 1 - selector: - matchLabels: - app: postgres - template: - metadata: - labels: - app: postgres - spec: - containers: - - name: postgres - image: "postgres:13" - imagePullPolicy: IfNotPresent - env: - - name: POSTGRES_PASSWORD - valueFrom: - secretKeyRef: - name: postgresql - key: password - - name: POSTGRES_USER - value: headscale - ports: - - name: postgres - protocol: TCP - containerPort: 5432 - livenessProbe: - tcpSocket: - port: 5432 - initialDelaySeconds: 30 - timeoutSeconds: 5 - periodSeconds: 15 - volumeMounts: - - name: pgdata - mountPath: /var/lib/postgresql/data - volumeClaimTemplates: - - metadata: - name: pgdata - spec: - storageClassName: local-path - accessModes: ["ReadWriteOnce"] - resources: - requests: - storage: 1Gi diff --git a/examples/kustomize/production-tls/ingress-patch.yaml b/examples/kustomize/production-tls/ingress-patch.yaml deleted file mode 100644 index 9e6177fb..00000000 --- a/examples/kustomize/production-tls/ingress-patch.yaml +++ /dev/null @@ -1,11 +0,0 @@ -kind: Ingress -metadata: - name: headscale - annotations: - cert-manager.io/cluster-issuer: letsencrypt-production - traefik.ingress.kubernetes.io/router.tls: "true" -spec: - tls: - - hosts: - - $(PUBLIC_HOSTNAME) - secretName: production-cert diff --git a/examples/kustomize/production-tls/kustomization.yaml b/examples/kustomize/production-tls/kustomization.yaml deleted file mode 100644 index d3147f5f..00000000 --- a/examples/kustomize/production-tls/kustomization.yaml +++ /dev/null @@ -1,9 +0,0 @@ -namespace: headscale -bases: - - ../base -resources: - - production-issuer.yaml -patches: - - path: ingress-patch.yaml - target: - kind: Ingress diff --git a/examples/kustomize/production-tls/production-issuer.yaml b/examples/kustomize/production-tls/production-issuer.yaml deleted file mode 100644 index f436090b..00000000 --- a/examples/kustomize/production-tls/production-issuer.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: cert-manager.io/v1 -kind: ClusterIssuer -metadata: - name: letsencrypt-production -spec: - acme: - # TODO: figure out how to get kustomize to interpolate this, or use a transformer - #email: $(CONTACT_EMAIL) - server: https://acme-v02.api.letsencrypt.org/directory - privateKeySecretRef: - # Secret resource used to store the account's private key. - name: letsencrypt-production-acc-key - solvers: - - http01: - ingress: - class: traefik diff --git a/examples/kustomize/sqlite/kustomization.yaml b/examples/kustomize/sqlite/kustomization.yaml deleted file mode 100644 index ca799419..00000000 --- a/examples/kustomize/sqlite/kustomization.yaml +++ /dev/null @@ -1,5 +0,0 @@ -namespace: headscale -bases: - - ../base -resources: - - statefulset.yaml diff --git a/examples/kustomize/sqlite/statefulset.yaml b/examples/kustomize/sqlite/statefulset.yaml deleted file mode 100644 index 2321d39d..00000000 --- a/examples/kustomize/sqlite/statefulset.yaml +++ /dev/null @@ -1,82 +0,0 @@ -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: headscale -spec: - serviceName: headscale - replicas: 1 - selector: - matchLabels: - app: headscale - template: - metadata: - labels: - app: headscale - spec: - containers: - - name: headscale - image: "headscale:latest" - imagePullPolicy: IfNotPresent - command: ["/go/bin/headscale", "serve"] - env: - - name: SERVER_URL - value: $(PUBLIC_PROTO)://$(PUBLIC_HOSTNAME) - - name: LISTEN_ADDR - valueFrom: - configMapKeyRef: - name: headscale-config - key: listen_addr - - name: METRICS_LISTEN_ADDR - valueFrom: - configMapKeyRef: - name: headscale-config - key: metrics_listen_addr - - name: DERP_MAP_PATH - value: /vol/config/derp.yaml - - name: EPHEMERAL_NODE_INACTIVITY_TIMEOUT - valueFrom: - configMapKeyRef: - name: headscale-config - key: ephemeral_node_inactivity_timeout - - name: DB_TYPE - value: sqlite3 - - name: DB_PATH - value: /vol/data/db.sqlite - ports: - - name: http - protocol: TCP - containerPort: 8080 - livenessProbe: - tcpSocket: - port: http - initialDelaySeconds: 30 - timeoutSeconds: 5 - periodSeconds: 15 - volumeMounts: - - name: config - mountPath: /vol/config - - name: data - mountPath: /vol/data - - name: secret - mountPath: /vol/secret - - name: etc - mountPath: /etc/headscale - volumes: - - name: config - configMap: - name: headscale-site - - name: etc - configMap: - name: headscale-etc - - name: secret - secret: - secretName: headscale - volumeClaimTemplates: - - metadata: - name: data - spec: - storageClassName: local-path - accessModes: ["ReadWriteOnce"] - resources: - requests: - storage: 1Gi diff --git a/examples/kustomize/staging-tls/ingress-patch.yaml b/examples/kustomize/staging-tls/ingress-patch.yaml deleted file mode 100644 index 5a1daf0c..00000000 --- a/examples/kustomize/staging-tls/ingress-patch.yaml +++ /dev/null @@ -1,11 +0,0 @@ -kind: Ingress -metadata: - name: headscale - annotations: - cert-manager.io/cluster-issuer: letsencrypt-staging - traefik.ingress.kubernetes.io/router.tls: "true" -spec: - tls: - - hosts: - - $(PUBLIC_HOSTNAME) - secretName: staging-cert diff --git a/examples/kustomize/staging-tls/kustomization.yaml b/examples/kustomize/staging-tls/kustomization.yaml deleted file mode 100644 index 0900c583..00000000 --- a/examples/kustomize/staging-tls/kustomization.yaml +++ /dev/null @@ -1,9 +0,0 @@ -namespace: headscale -bases: - - ../base -resources: - - staging-issuer.yaml -patches: - - path: ingress-patch.yaml - target: - kind: Ingress diff --git a/examples/kustomize/staging-tls/staging-issuer.yaml b/examples/kustomize/staging-tls/staging-issuer.yaml deleted file mode 100644 index cf290415..00000000 --- a/examples/kustomize/staging-tls/staging-issuer.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: cert-manager.io/v1 -kind: ClusterIssuer -metadata: - name: letsencrypt-staging -spec: - acme: - # TODO: figure out how to get kustomize to interpolate this, or use a transformer - #email: $(CONTACT_EMAIL) - server: https://acme-staging-v02.api.letsencrypt.org/directory - privateKeySecretRef: - # Secret resource used to store the account's private key. - name: letsencrypt-staging-acc-key - solvers: - - http01: - ingress: - class: traefik