mirror of
https://github.com/juanfont/headscale.git
synced 2024-11-26 08:53:05 +00:00
Add k8s deployment, standalone app Dockerfile.
Tested with Rancher k3s. See k8s/README.md for site configuration and deployment instructions. Add cert-manager, tls, remote headscale script.
This commit is contained in:
parent
a63fb6b007
commit
c64d756ea7
22 changed files with 531 additions and 0 deletions
12
Dockerfile
Normal file
12
Dockerfile
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
FROM golang:latest AS build
|
||||||
|
ENV GOPATH /go
|
||||||
|
COPY . /go/src/headscale
|
||||||
|
WORKDIR /go/src/headscale
|
||||||
|
RUN go install -a -ldflags="-extldflags=-static" -tags netgo,sqlite_omit_load_extension ./cmd/headscale
|
||||||
|
RUN test -e /go/bin/headscale
|
||||||
|
|
||||||
|
FROM scratch
|
||||||
|
COPY --from=build /go/bin/headscale /go/bin/headscale
|
||||||
|
ENV TZ UTC
|
||||||
|
EXPOSE 8080/tcp
|
||||||
|
ENTRYPOINT ["/go/bin/headscale"]
|
2
k8s/.gitignore
vendored
Normal file
2
k8s/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/**/site
|
||||||
|
/**/secrets
|
99
k8s/README.md
Normal file
99
k8s/README.md
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
# Deploying Headscale on Kubernetes
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
Juan Font Alonso <juanfontalonso@gmail.com> - 2021
|
||||||
|
https://gitlab.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
|
||||||
|
|
||||||
|
- Github action to publish the docker image
|
||||||
|
- 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
|
8
k8s/base/configmap.yaml
Normal file
8
k8s/base/configmap.yaml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: headscale-config
|
||||||
|
data:
|
||||||
|
server_url: $(PUBLIC_PROTO)://$(PUBLIC_HOSTNAME)
|
||||||
|
listen_addr: "0.0.0.0:8080"
|
||||||
|
ephemeral_node_inactivity_timeout: "30m"
|
18
k8s/base/ingress.yaml
Normal file
18
k8s/base/ingress.yaml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
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
|
42
k8s/base/kustomization.yaml
Normal file
42
k8s/base/kustomization.yaml
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
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
|
13
k8s/base/service.yaml
Normal file
13
k8s/base/service.yaml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: headscale
|
||||||
|
labels:
|
||||||
|
app: headscale
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: headscale
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
targetPort: http
|
||||||
|
port: 8080
|
3
k8s/headscale.bash
Executable file
3
k8s/headscale.bash
Executable file
|
@ -0,0 +1,3 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -eu
|
||||||
|
exec kubectl -n headscale exec -ti pod/headscale-0 -- /go/bin/headscale "$@"
|
22
k8s/init.bash
Executable file
22
k8s/init.bash
Executable file
|
@ -0,0 +1,22 @@
|
||||||
|
#!/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)
|
3
k8s/install-cert-manager.bash
Executable file
3
k8s/install-cert-manager.bash
Executable file
|
@ -0,0 +1,3 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -eux
|
||||||
|
kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.4.0/cert-manager.yaml
|
78
k8s/postgres/deployment.yaml
Normal file
78
k8s/postgres/deployment.yaml
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
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: PRIVATE_KEY_PATH
|
||||||
|
value: /vol/secret/private-key
|
||||||
|
- 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
|
13
k8s/postgres/kustomization.yaml
Normal file
13
k8s/postgres/kustomization.yaml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
namespace: headscale
|
||||||
|
bases:
|
||||||
|
- ../base
|
||||||
|
resources:
|
||||||
|
- deployment.yaml
|
||||||
|
- postgres-service.yaml
|
||||||
|
- postgres-statefulset.yaml
|
||||||
|
generatorOptions:
|
||||||
|
disableNameSuffixHash: true
|
||||||
|
secretGenerator:
|
||||||
|
- name: postgresql
|
||||||
|
files:
|
||||||
|
- secrets/password
|
13
k8s/postgres/postgres-service.yaml
Normal file
13
k8s/postgres/postgres-service.yaml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: postgres
|
||||||
|
labels:
|
||||||
|
app: postgres
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: postgres
|
||||||
|
ports:
|
||||||
|
- name: postgres
|
||||||
|
targetPort: postgres
|
||||||
|
port: 5432
|
49
k8s/postgres/postgres-statefulset.yaml
Normal file
49
k8s/postgres/postgres-statefulset.yaml
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
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
|
11
k8s/production-tls/ingress-patch.yaml
Normal file
11
k8s/production-tls/ingress-patch.yaml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
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
|
9
k8s/production-tls/kustomization.yaml
Normal file
9
k8s/production-tls/kustomization.yaml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
namespace: headscale
|
||||||
|
bases:
|
||||||
|
- ../base
|
||||||
|
resources:
|
||||||
|
- production-issuer.yaml
|
||||||
|
patches:
|
||||||
|
- path: ingress-patch.yaml
|
||||||
|
target:
|
||||||
|
kind: Ingress
|
16
k8s/production-tls/production-issuer.yaml
Normal file
16
k8s/production-tls/production-issuer.yaml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
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
|
5
k8s/sqlite/kustomization.yaml
Normal file
5
k8s/sqlite/kustomization.yaml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
namespace: headscale
|
||||||
|
bases:
|
||||||
|
- ../base
|
||||||
|
resources:
|
||||||
|
- statefulset.yaml
|
79
k8s/sqlite/statefulset.yaml
Normal file
79
k8s/sqlite/statefulset.yaml
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
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: PRIVATE_KEY_PATH
|
||||||
|
value: /vol/secret/private-key
|
||||||
|
- 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
|
11
k8s/staging-tls/ingress-patch.yaml
Normal file
11
k8s/staging-tls/ingress-patch.yaml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
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
|
9
k8s/staging-tls/kustomization.yaml
Normal file
9
k8s/staging-tls/kustomization.yaml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
namespace: headscale
|
||||||
|
bases:
|
||||||
|
- ../base
|
||||||
|
resources:
|
||||||
|
- staging-issuer.yaml
|
||||||
|
patches:
|
||||||
|
- path: ingress-patch.yaml
|
||||||
|
target:
|
||||||
|
kind: Ingress
|
16
k8s/staging-tls/staging-issuer.yaml
Normal file
16
k8s/staging-tls/staging-issuer.yaml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
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