Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions charts/ziti-edge-tunnel/Chart.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
apiVersion: v2
appVersion: 1.5.12
appVersion: 1.7.13
description: Dial OpenZiti services with a tunneler daemonset
kubeVersion: '>= 1.20.0-0'
name: ziti-edge-tunnel
type: application
version: 1.2.0
version: 1.3.0
icon: https://openziti.io/img/ziti-logo-dark.svg
home: https://openziti.io
home: https://netfoundry.io/docs/openziti/
sources:
- https://github.com/openziti/ziti-tunnel-sdk-c
keywords:
Expand Down
113 changes: 96 additions & 17 deletions charts/ziti-edge-tunnel/README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<!-- README.md generated by helm-docs from README.md.gotmpl -->
# ziti-edge-tunnel

![Version: 1.2.0](https://img.shields.io/badge/Version-1.2.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.5.12](https://img.shields.io/badge/AppVersion-1.5.12-informational?style=flat-square)
![Version: 1.3.0](https://img.shields.io/badge/Version-1.3.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.7.13](https://img.shields.io/badge/AppVersion-1.7.13-informational?style=flat-square)

Dial OpenZiti services with a tunneler daemonset

**Homepage:** <https://openziti.io>
**Homepage:** <https://netfoundry.io/docs/openziti/>

## Source Code

Expand All @@ -25,46 +25,121 @@ For multinode kubernetes installations, where your cluster DNS could run on a di

## How this Chart Works

This chart deploys a pod running `ziti-edge-tunnel`, [the OpenZiti Linux tunneler](https://docs.openziti.io/docs/reference/tunnelers/linux/), in transparent proxy mode with DNS nameserver. The chart uses container image `docker.io/openziti/ziti-edge-tunnel` which runs `ziti-edge-tunnel run`.
This chart deploys a DaemonSet running [the OpenZiti Linux tunneler](https://docs.openziti.io/docs/reference/tunnelers/linux/), in transparent node-level proxy with DNS nameserver. The chart uses container image `docker.io/openziti/ziti-edge-tunnel` which runs `ziti-edge-tunnel run`.

The enrolled Ziti identity JSON is persisted in a volume, and the chart will migrate the identity from a secret to the volume if the legacy secret exists.
### Identity Storage Options

The chart supports two approaches for persisting the tunneler's Ziti identity:

1. **PersistentVolumeClaim (Default)**: Identity is stored in a volume, allowing the tunneler to autonomously renew its certificate.

2. **Existing Secret**: Identity is mounted from a pre-created Kubernetes secret (read-only). This approach requires manual certificate management since the tunneler cannot write updates.

## Installation

```console
helm repo add openziti https://docs.openziti.io/helm-charts/
```

After adding the charts repo to Helm then you may enroll the identity and install the chart. You may supply a Ziti identity JSON file when you install the chart. This approach enables you to use any option available to the `ziti-edge-tunnel enroll` command.
#### Identity Storage (Preferred) - Identity in PVC from Enrollment Token

Provide the enrollment token as a JWT. The identity will be enrolled on first run and stored in a PVC, allowing autonomous certificate renewal. This is preferred for security because only the one-time enrollment token must be orchestrated, and the private key is generated in-place during first-run enrollment.

```console
ziti-edge-tunnel enroll --jwt /tmp/k8s-tunneler.jwt --identity /tmp/k8s-tunneler.json
helm install ziti-edge-tunnel openziti/ziti-edge-tunnel --set-file zitiIdentity=/tmp/k8s-tunneler.json
helm install ziti-edge-tunnel openziti/ziti-edge-tunnel --set-file zitiEnrollToken=/tmp/k8s-tunneler.jwt
```

Alternatively, you may supply the JWT directly to the chart. In this case, a private key will be generated on first run and the identity will be enrolled.
#### Identity Storage Option - Pre-Enrolled Identity in PVC

Alternatively, you may supply a pre-enrolled identity as JSON. The identity will be stored in a PVC, allowing autonomous certificate renewal.

```console
helm install ziti-edge-tunnel openziti/ziti-edge-tunnel --set-file zitiEnrollToken=/tmp/k8s-tunneler.jwt
ziti-edge-tunnel enroll --jwt /tmp/k8s-tunneler.jwt --identity /tmp/k8s-tunneler.json
helm install ziti-edge-tunnel openziti/ziti-edge-tunnel --set-file zitiIdentity=/tmp/k8s-tunneler.json
```

### Installation using a existing secret
#### Identity Storage Option - Existing Secret

**Warning:** this approach does not allow the tunneler to autonomously renew its identity certificate, so you must renew the identity certificate out of band and supply it as an existing secret.
**⚠️ Warning:** This approach disables autonomous certificate renewal. You must manually manage certificate updates, private key rolling, etc.

Create the secret:

```console
kubectl create secret generic k8s-tunneler-identity --from-file=persisted-identity=k8s-tunneler.json
kubectl create secret generic k8s-tunneler-identity --from-file=zitiIdentity=k8s-tunneler.json
```

Deploy the Helm chart, referring to the existing secret:
Deploy with the existing secret:

```console
helm install ziti-edge-tunnel openziti/ziti-edge-tunnel --set secret.existingSecretName=k8s-tunneler-identity
```

If desired, change the key name `persisted-identity` with `--set secret.keyName=myKeyName`.
You may specify another Kubernetes Secret resource data key name if your existing secret does not store the identity under the key `persisted-identity`:

```console
helm install ziti-edge-tunnel openziti/ziti-edge-tunnel \
--set secret.existingSecretName=k8s-tunneler-identity \
--set secret.keyName=myKeyName
```

### PVC Configuration (Options 1 & 2 only)

When using PVC storage (Options 1 & 2), you can configure the PersistentVolumeClaim settings. The chart uses ReadWriteMany access mode by default for DaemonSet compatibility:

```console
# Configure access mode (ReadWriteMany is default for multi-node DaemonSets)
helm install ziti-edge-tunnel openziti/ziti-edge-tunnel \
--set-file zitiIdentity=/tmp/k8s-tunneler.json \
--set pvc.accessMode=ReadWriteOnce

# Configure storage class (uses cluster default if not set)
helm install ziti-edge-tunnel openziti/ziti-edge-tunnel \
--set-file zitiIdentity=/tmp/k8s-tunneler.json \
--set pvc.storageClass=nfs

# Configure storage size (default is 2Gi)
helm install ziti-edge-tunnel openziti/ziti-edge-tunnel \
--set-file zitiIdentity=/tmp/k8s-tunneler.json \
--set pvc.storageSize=5Gi

# Combine multiple PVC settings
helm install ziti-edge-tunnel openziti/ziti-edge-tunnel \
--set-file zitiIdentity=/tmp/k8s-tunneler.json \
--set pvc.accessMode=ReadWriteMany \
--set pvc.storageClass=nfs \
--set pvc.storageSize=1Gi
```

**Important:** For DaemonSets running on multiple nodes, your storage class must support `ReadWriteMany` access mode. If your cluster doesn't support RWX volumes, use Option 3 (existing secret) instead.

### System Integration

#### D-Bus Socket Configuration

The tunneler can integrate with systemd-resolved via D-Bus to configure the node's system resolver automatically. This is enabled by default.

**⚠️ Important:** If systemd-resolved integration is disabled, you must manually configure the node's resolver to query the tunneler's nameserver first for proper DNS interception.

```console
# Disable D-Bus integration (if causing issues)
helm install ziti-edge-tunnel openziti/ziti-edge-tunnel \
--set-file zitiIdentity=/tmp/k8s-tunneler.json \
--set systemDBus.enabled=false

# Use different D-Bus socket path (if default doesn't exist)
helm install ziti-edge-tunnel openziti/ziti-edge-tunnel \
--set-file zitiIdentity=/tmp/k8s-tunneler.json \
--set systemDBus.systemDBusSocketMnt=/run/dbus/system_bus_socket
```

**Common D-Bus socket paths:**
- `/var/run/dbus/system_bus_socket` (default, most distributions)
- `/run/dbus/system_bus_socket` (systemd-based systems)
- `/var/lib/dbus/system_bus_socket` (some older systems)

**Troubleshooting:** If you see `hostPath type check failed: ... is not a socket file`, either:
1. Verify the correct D-Bus socket path on your nodes: `ls -la /var/run/dbus/`
2. Disable D-Bus integration with `--set systemDBus.enabled=false`

### Configure CoreDNS

Expand Down Expand Up @@ -205,16 +280,20 @@ Once the image is present on every node, you can proceed to upgrade the tunneler
| podAnnotations | object | `{}` | |
| podSecurityContext | object | `{}` | |
| ports | list | `[]` | |
| pvc.accessMode | string | `"ReadWriteMany"` | Access mode for the identity PVC (ReadWriteMany recommended for DaemonSets) |
| pvc.storageClass | string | `""` | Storage class for the identity PVC (uses cluster default if empty) |
| pvc.storageSize | string | `"2Gi"` | Storage size for the identity PVC |
| resources | object | `{}` | |
| secret | object | `{}` | |
| secret.existingSecretName | string | `""` | Use an existing secret name (if set, disables PVC and certificate auto-renewal) |
| secret.keyName | string | `"persisted-identity"` | Key name in the secret containing the identity JSON encoding |
| securityContext.privileged | bool | `true` | |
| serviceAccount.annotations | object | `{}` | Annotations to add to the service account |
| serviceAccount.create | bool | `true` | Specifies whether a service account should be created |
| serviceAccount.name | string | `""` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template |
| spireAgent.enabled | bool | `false` | if you are running a container with the spire-agent binary installed then this will allow you to add the hostpath necessary for connecting to the spire socket |
| spireAgent.spireSocketMnt | string | `"/run/spire/sockets"` | file path of the spire socket mount |
| systemDBus.enabled | bool | `true` | enable D-Bus socket connection |
| systemDBus.systemDBusSocketMnt | string | `"/var/run/dbus/system_bus_socket"` | file path of the System D-Bus socket mount |
| systemDBus.enabled | bool | `true` | Enable D-Bus socket connection for systemd-resolved integration |
| systemDBus.systemDBusSocketMnt | string | `"/var/run/dbus/system_bus_socket"` | Host path to the system D-Bus socket (varies by distribution) |
| tolerations | list | `[]` | |
| zitiEnrollToken | string | `""` | JWT to enroll a new identity and write in the PVC |
| zitiIdentity | string | `""` | JSON of an enrolled identity to write in the PVC |
Expand Down
99 changes: 87 additions & 12 deletions charts/ziti-edge-tunnel/README.md.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -24,46 +24,121 @@ For multinode kubernetes installations, where your cluster DNS could run on a di

## How this Chart Works

This chart deploys a pod running `ziti-edge-tunnel`, [the OpenZiti Linux tunneler](https://docs.openziti.io/docs/reference/tunnelers/linux/), in transparent proxy mode with DNS nameserver. The chart uses container image `docker.io/openziti/ziti-edge-tunnel` which runs `ziti-edge-tunnel run`.
This chart deploys a DaemonSet running [the OpenZiti Linux tunneler](https://docs.openziti.io/docs/reference/tunnelers/linux/), in transparent node-level proxy with DNS nameserver. The chart uses container image `docker.io/openziti/ziti-edge-tunnel` which runs `ziti-edge-tunnel run`.

The enrolled Ziti identity JSON is persisted in a volume, and the chart will migrate the identity from a secret to the volume if the legacy secret exists.
### Identity Storage Options

The chart supports two approaches for persisting the tunneler's Ziti identity:

1. **PersistentVolumeClaim (Default)**: Identity is stored in a volume, allowing the tunneler to autonomously renew its certificate.

2. **Existing Secret**: Identity is mounted from a pre-created Kubernetes secret (read-only). This approach requires manual certificate management since the tunneler cannot write updates.

## Installation

```console
helm repo add openziti https://docs.openziti.io/helm-charts/
```

After adding the charts repo to Helm then you may enroll the identity and install the chart. You may supply a Ziti identity JSON file when you install the chart. This approach enables you to use any option available to the `ziti-edge-tunnel enroll` command.
#### Identity Storage (Preferred) - Identity in PVC from Enrollment Token

Provide the enrollment token as a JWT. The identity will be enrolled on first run and stored in a PVC, allowing autonomous certificate renewal. This is preferred for security because only the one-time enrollment token must be orchestrated, and the private key is generated in-place during first-run enrollment.

```console
ziti-edge-tunnel enroll --jwt /tmp/k8s-tunneler.jwt --identity /tmp/k8s-tunneler.json
helm install ziti-edge-tunnel openziti/ziti-edge-tunnel --set-file zitiIdentity=/tmp/k8s-tunneler.json
helm install ziti-edge-tunnel openziti/ziti-edge-tunnel --set-file zitiEnrollToken=/tmp/k8s-tunneler.jwt
```

Alternatively, you may supply the JWT directly to the chart. In this case, a private key will be generated on first run and the identity will be enrolled.
#### Identity Storage Option - Pre-Enrolled Identity in PVC

Alternatively, you may supply a pre-enrolled identity as JSON. The identity will be stored in a PVC, allowing autonomous certificate renewal.

```console
helm install ziti-edge-tunnel openziti/ziti-edge-tunnel --set-file zitiEnrollToken=/tmp/k8s-tunneler.jwt
ziti-edge-tunnel enroll --jwt /tmp/k8s-tunneler.jwt --identity /tmp/k8s-tunneler.json
helm install ziti-edge-tunnel openziti/ziti-edge-tunnel --set-file zitiIdentity=/tmp/k8s-tunneler.json
```

### Installation using a existing secret
#### Identity Storage Option - Existing Secret

**Warning:** this approach does not allow the tunneler to autonomously renew its identity certificate, so you must renew the identity certificate out of band and supply it as an existing secret.
**⚠️ Warning:** This approach disables autonomous certificate renewal. You must manually manage certificate updates, private key rolling, etc.

Create the secret:

```console
kubectl create secret generic k8s-tunneler-identity --from-file=persisted-identity=k8s-tunneler.json
kubectl create secret generic k8s-tunneler-identity --from-file=zitiIdentity=k8s-tunneler.json
```

Deploy the Helm chart, referring to the existing secret:
Deploy with the existing secret:

```console
helm install ziti-edge-tunnel openziti/ziti-edge-tunnel --set secret.existingSecretName=k8s-tunneler-identity
```

If desired, change the key name `persisted-identity` with `--set secret.keyName=myKeyName`.
You may specify another Kubernetes Secret resource data key name if your existing secret does not store the identity under the key `persisted-identity`:

```console
helm install ziti-edge-tunnel openziti/ziti-edge-tunnel \
--set secret.existingSecretName=k8s-tunneler-identity \
--set secret.keyName=myKeyName
```

### PVC Configuration (Options 1 & 2 only)

When using PVC storage (Options 1 & 2), you can configure the PersistentVolumeClaim settings. The chart uses ReadWriteMany access mode by default for DaemonSet compatibility:

```console
# Configure access mode (ReadWriteMany is default for multi-node DaemonSets)
helm install ziti-edge-tunnel openziti/ziti-edge-tunnel \
--set-file zitiIdentity=/tmp/k8s-tunneler.json \
--set pvc.accessMode=ReadWriteOnce

# Configure storage class (uses cluster default if not set)
helm install ziti-edge-tunnel openziti/ziti-edge-tunnel \
--set-file zitiIdentity=/tmp/k8s-tunneler.json \
--set pvc.storageClass=nfs

# Configure storage size (default is 2Gi)
helm install ziti-edge-tunnel openziti/ziti-edge-tunnel \
--set-file zitiIdentity=/tmp/k8s-tunneler.json \
--set pvc.storageSize=5Gi

# Combine multiple PVC settings
helm install ziti-edge-tunnel openziti/ziti-edge-tunnel \
--set-file zitiIdentity=/tmp/k8s-tunneler.json \
--set pvc.accessMode=ReadWriteMany \
--set pvc.storageClass=nfs \
--set pvc.storageSize=1Gi
```

**Important:** For DaemonSets running on multiple nodes, your storage class must support `ReadWriteMany` access mode. If your cluster doesn't support RWX volumes, use Option 3 (existing secret) instead.

### System Integration

#### D-Bus Socket Configuration

The tunneler can integrate with systemd-resolved via D-Bus to configure the node's system resolver automatically. This is enabled by default.

**⚠️ Important:** If systemd-resolved integration is disabled, you must manually configure the node's resolver to query the tunneler's nameserver first for proper DNS interception.

```console
# Disable D-Bus integration (if causing issues)
helm install ziti-edge-tunnel openziti/ziti-edge-tunnel \
--set-file zitiIdentity=/tmp/k8s-tunneler.json \
--set systemDBus.enabled=false

# Use different D-Bus socket path (if default doesn't exist)
helm install ziti-edge-tunnel openziti/ziti-edge-tunnel \
--set-file zitiIdentity=/tmp/k8s-tunneler.json \
--set systemDBus.systemDBusSocketMnt=/run/dbus/system_bus_socket
```

**Common D-Bus socket paths:**
- `/var/run/dbus/system_bus_socket` (default, most distributions)
- `/run/dbus/system_bus_socket` (systemd-based systems)
- `/var/lib/dbus/system_bus_socket` (some older systems)

**Troubleshooting:** If you see `hostPath type check failed: ... is not a socket file`, either:
1. Verify the correct D-Bus socket path on your nodes: `ls -la /var/run/dbus/`
2. Disable D-Bus integration with `--set systemDBus.enabled=false`

### Configure CoreDNS

Expand Down
4 changes: 3 additions & 1 deletion charts/ziti-edge-tunnel/templates/daemonset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ spec:
env:
- name: ZITI_IDENTITY_BASENAME
value: {{ include "ziti-edge-tunnel.fullname" . }}-identity
{{- if not .Values.secret.existingSecretName }}
{{- if .Values.zitiIdentity }}
- name: ZITI_IDENTITY_JSON
value: {{ .Values.zitiIdentity | quote }}
Expand All @@ -52,6 +53,7 @@ spec:
- name: ZITI_ENROLL_TOKEN
value: {{ .Values.zitiEnrollToken }}
{{- end }}
{{- end }}
- name: ZITI_LOG
value: {{ .Values.log.zitiLevel | default 3 | quote }}
- name: TLSUV_DEBUG
Expand Down Expand Up @@ -101,7 +103,7 @@ spec:
secretName: {{ .Values.secret.existingSecretName }}
defaultMode: 0444
items:
- key: {{ .Values.secret.keyName | default "persisted-identity" | quote }}
- key: {{ .Values.secret.keyName | quote }}
path: {{ include "ziti-edge-tunnel.fullname" . }}-identity.json
{{- else }}
- name: persisted-identity
Expand Down
29 changes: 0 additions & 29 deletions charts/ziti-edge-tunnel/templates/identity-migrate-job.yaml

This file was deleted.

8 changes: 0 additions & 8 deletions charts/ziti-edge-tunnel/templates/identity-migrate-role.yaml

This file was deleted.

This file was deleted.

Loading