This setup (Linux only) allows you to run ztunnel as a local process on your host while it connects to an Istiod instance running in a KinD cluster. This replaces the ztunnel running on a specific worker node.
1. Prepare KinD Cluster
Create a cluster with an extraMount to allow the local ztunnel to connect to the node's CNI socket:
kind create cluster --config=- <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: ambient
nodes:
- role: control-plane
- role: worker
extraMounts:
- hostPath: /tmp/worker1-ztunnel/
containerPath: /var/run/ztunnel/
- role: worker
containerdConfigPatches:
- |-
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."localhost:5000"]
endpoint = ["http://\\${KIND_REGISTRY_NAME}:5000"]
EOF
2. Remove ztunnel from the target node
Label the node to prevent ztunnel from scheduling there and patch the DaemonSet:
kubectl label node ambient-worker ztunnel=no
kubectl patch daemonset -n istio-system ztunnel --type=merge -p='{"spec":{"template":{"spec":{"affinity":{"nodeAffinity":{"requiredDuringSchedulingIgnoredDuringExecution":{"nodeSelectorTerms":[{"matchExpressions":[{"key":"ztunnel","operator":"NotIn","values":["no"]}]}]}}}}}}}'
3. Retrieve Credentials
Create a temporary pod to extract the ztunnel service account token and the Istio CA root cert:
kubectl get cm -n istio-system istio-ca-root-cert -o jsonpath='{.data.root-cert\.pem}' > /tmp/istio-root.pem
kubectl create -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: fake-tunnel-worker1
namespace: istio-system
spec:
nodeName: ambient-worker
terminationGracePeriodSeconds: 1
serviceAccountName: ztunnel
containers:
- name: cat-token
image: ubuntu:22.04
command:
- bash
- -c
args:
- "sleep 10000"
ports:
- containerPort: 80
volumeMounts:
- mountPath: /var/run/secrets/tokens
name: istio-token
volumes:
- name: istio-token
projected:
defaultMode: 420
sources:
- serviceAccountToken:
audience: istio-ca
expirationSeconds: 43200
path: istio-token
EOF
# Extract the token
kubectl exec -n istio-system fake-tunnel-worker1 -- cat /var/run/secrets/tokens/istio-token > ./var/run/secrets/tokens/istio-token
4. Configure Istiod and Run Ztunnel
Set ISTIOD_CUSTOM_HOST to localhost and port-forward the service:
kubectl set env -n istio-system deploy/istiod ISTIOD_CUSTOM_HOST=localhost
kubectl port-forward -n istio-system svc/istiod 15012:15012 &
# Run ztunnel
xargs env <<EOF
INPOD_UDS=/tmp/worker1-ztunnel/ztunnel.sock
CLUSTER_ID=Kubernetes
RUST_LOG=debug
PROXY_MODE="shared"
ISTIO_META_DNS_CAPTURE="true"
ISTIO_META_DNS_PROXY_ADDR="127.0.0.1:15053"
SERVICE_ACCOUNT=ztunnel
POD_NAMESPACE=istio-system
POD_NAME=ztunnel-worker1
CA_ROOT_CA=/tmp/istio-root.pem
XDS_ROOT_CA=/tmp/istio-root.pem
CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="sudo -E"
cargo run proxy ztunnel
EOF