134 lines
4.3 KiB
Markdown
134 lines
4.3 KiB
Markdown
## Kubernetes Integration
|
|
|
|
The Kubernetes integration allows you to run Headplane and Headscale together
|
|
in a cluster. It allows you to unlock full functionality such as automatic
|
|
reloading of ACLs, DNS management, and Headscale configuration management.
|
|
|
|
Currently there are a few limitations to the Kubernetes integration:
|
|
- Headplane and Headscale need to run in the same Pod and share the same
|
|
process space for the integration to work correctly due to a limitation in
|
|
the Kubernetes API.
|
|
|
|
- The only supported methods of deploying the integration are through a
|
|
`Deployment` or `Pod` (more coming soon). You can still get around this with
|
|
the `HEADSCALE_INTEGRATION_UNSTRICT` variable, but it's not recommended.
|
|
|
|
- The integration will assume that the Headscale container will always restart
|
|
because the integration relies on a system call that will exit the container.
|
|
|
|
### Deployment
|
|
|
|
In order to ensure Headplane can read Kubernetes resources, you'll need to
|
|
grant additional RBAC permissions to the default `ServiceAccount` in the
|
|
namespace. This can be done with the following:
|
|
```yaml
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: Role
|
|
metadata:
|
|
name: headplane-agent
|
|
namespace: default # Adjust namespace as needed
|
|
rules:
|
|
- apiGroups: ['']
|
|
resources: ['pods']
|
|
verbs: ['get', 'list']
|
|
- apiGroups: ['apps']
|
|
resources: ['deployments']
|
|
verbs: ['get', 'list']
|
|
---
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: RoleBinding
|
|
metadata:
|
|
name: headplane-agent
|
|
namespace: default # Adjust namespace as needed
|
|
roleRef:
|
|
apiGroup: rbac.authorization.k8s.io
|
|
kind: Role
|
|
name: headplane-agent
|
|
subjects:
|
|
- kind: ServiceAccount
|
|
name: default # If you use a different service account, change this
|
|
namespace: default # Adjust namespace as needed
|
|
```
|
|
|
|
Keep in mind you'll need to make `PersistentVolumeClaim`s for the data and that
|
|
they need to be either `ReadWriteOnce` or `ReadWriteMany` depending on your
|
|
topology. Additionally, you can abstract environment variables and configuration
|
|
away into a `ConfigMap` or `Secret` for easier management.
|
|
|
|
The important parts of this deployment are the `HEADSCALE_INTEGRATION` and
|
|
`DEPLOYMENT_NAME` environment variables. The `HEADSCALE_INTEGRATION` variable
|
|
should be set to `kubernetes` and the `POST_NAME` variable should be set
|
|
to the name of the pod (done using the Downward API below).
|
|
|
|
> If you are having issues with validating `shareProcessNamespace`, you can
|
|
set `HEADSCALE_INTEGRATION_UNSTRICT` to `true` to disable the strict checks.
|
|
|
|
A basic deployment of the integration would look like this. Keep in mind that
|
|
you are responsible for setting up a reverse-proxy via an `Ingress` or `Service`
|
|
otherwise Headplane will not work:
|
|
```yaml
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: headplane
|
|
namespace: default # Adjust namespace as needed
|
|
labels:
|
|
app: headplane
|
|
spec:
|
|
replicas: 1
|
|
selector:
|
|
matchLabels:
|
|
app: headplane
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: headplane
|
|
spec:
|
|
shareProcessNamespace: true
|
|
serviceAccountName: default
|
|
containers:
|
|
- name: headplane
|
|
image: ghcr.io/tale/headplane:0.3.2
|
|
env:
|
|
- name: COOKIE_SECRET
|
|
value: 'abcdefghijklmnopqrstuvwxyz'
|
|
- name: HEADSCALE_INTEGRATION
|
|
value: 'kubernetes'
|
|
- name: POD_NAME
|
|
valueFrom:
|
|
fieldRef:
|
|
fieldPath: metadata.name
|
|
|
|
# Only set this to false if you aren't behind a reverse proxy
|
|
- name: COOKIE_SECURE
|
|
value: 'false'
|
|
volumeMounts:
|
|
- name: headscale-config
|
|
mountPath: /etc/headscale
|
|
|
|
- name: headscale
|
|
image: headscale/headscale:0.23.0
|
|
command: ['serve']
|
|
env:
|
|
- name: TZ
|
|
value: 'America/New_York'
|
|
volumeMounts:
|
|
- name: headscale-data
|
|
mountPath: /var/lib/headscale
|
|
- name: headscale-config
|
|
mountPath: /etc/headscale
|
|
|
|
volumes:
|
|
- name: headscale-data
|
|
persistentVolumeClaim:
|
|
claimName: headscale-data
|
|
- name: headscale-config
|
|
persistentVolumeClaim:
|
|
claimName: headscale-config
|
|
```
|
|
|
|
> For a breakdown of each configuration variable, please refer to the
|
|
[Configuration](/docs/Configuration.md) guide.
|
|
> It explains what each variable does, how to configure them, and what the
|
|
default values are.
|