remove examples/, and kustomize (#1906)
this directory is unmaintained and not verified, if it should be restored, it should end up under the community docs effort. Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
This commit is contained in:
parent
aba4b36030
commit
9229d17bbe
22 changed files with 0 additions and 532 deletions
|
@ -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.
|
|
2
examples/kustomize/.gitignore
vendored
2
examples/kustomize/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
||||||
/**/site
|
|
||||||
/**/secrets
|
|
|
@ -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
|
|
|
@ -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"
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -1,3 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
set -eu
|
|
||||||
exec kubectl -n headscale exec -ti pod/headscale-0 -- /go/bin/headscale "$@"
|
|
|
@ -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 <<EOF
|
|
||||||
public-hostname=localhost
|
|
||||||
public-proto=http
|
|
||||||
contact-email=headscale@example.com
|
|
||||||
EOF
|
|
||||||
)
|
|
||||||
[ ! -e base/site/derp.yaml ] && cp ../derp.yaml base/site/derp.yaml
|
|
||||||
|
|
||||||
umask 077
|
|
||||||
mkdir -p base/secrets/
|
|
||||||
[ ! -e base/secrets/private-key ] && (
|
|
||||||
wg genkey > base/secrets/private-key
|
|
||||||
)
|
|
||||||
mkdir -p postgres/secrets/
|
|
||||||
[ ! -e postgres/secrets/password ] && (head -c 32 /dev/urandom | base64 -w0 > postgres/secrets/password)
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -1,9 +0,0 @@
|
||||||
namespace: headscale
|
|
||||||
bases:
|
|
||||||
- ../base
|
|
||||||
resources:
|
|
||||||
- production-issuer.yaml
|
|
||||||
patches:
|
|
||||||
- path: ingress-patch.yaml
|
|
||||||
target:
|
|
||||||
kind: Ingress
|
|
|
@ -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
|
|
|
@ -1,5 +0,0 @@
|
||||||
namespace: headscale
|
|
||||||
bases:
|
|
||||||
- ../base
|
|
||||||
resources:
|
|
||||||
- statefulset.yaml
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -1,9 +0,0 @@
|
||||||
namespace: headscale
|
|
||||||
bases:
|
|
||||||
- ../base
|
|
||||||
resources:
|
|
||||||
- staging-issuer.yaml
|
|
||||||
patches:
|
|
||||||
- path: ingress-patch.yaml
|
|
||||||
target:
|
|
||||||
kind: Ingress
|
|
|
@ -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
|
|
Loading…
Reference in a new issue