Kubernetes Sidecar Client
This guide shows you how to access a NetFoundry service from a pre-existing (or third party) application that's running
in a Kubernetes Pod. To provide access to the service, we will deploy the
ziti-tunnel NetFoundry client in a sidecar
The Ziti Network Quickstart
walked you through standing up a Ziti instance and accessing a Ziti service from your workstation with
ziti-tunnel. In this guide we'll deploy the same
ziti-tunnel client, but instead of running it from the
command line we will deploy it in a sidecar container in a Kubernetes Pod.
This guide also demonstrates
ziti-tunnel's internal DNS server, which allows us to access NetFoundry services
by hostname instead of IP address.
- Complete the Ziti Network Quickstart. This guide uses the Ziti Controller and Ziti Edge Router that are created in the Ziti Quickstart.
- Admin-level access to a Kubernetes cluster via
Create an Identity and AppWAN
This guide will re-use the "eth0.ziti.cli" service that was created in the Ziti Network Quickstart.
We will create a new identity for our client, with a new AppWAN that uses the eth0.ziti.cli service.
Create the Identity:
$ ziti edge controller create identity device tunnel-sidecar -o tunnel-sidecar.jwt
Create the AppWAN:
$ ziti edge controller create app-wan ziti-tunnel-appwan -i tunnel-sidecar -s eth0.ziti.cli
Create a Kubernetes Secret
ziti-tunnel sidecar will access its identity by mounting a Kubernetes secret in the container.
We can mount the JWT as a secret like this:
$ kubectl create secret generic tunnel-sidecar.jwt --from-file=tunnel-sidecar.jwt
Deploy the Pod
Deploy a Pod that runs a client application and
ziti-tunnel as a sidecar container. For this
demonstration, the client application is
wget. Our Pod runs
wget in a loop so we can see content
from our NetFoundry service in the Pod's logs.
Save the following yaml to a file named tunnel-sidecar-demo.yaml
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: tunnel-sidecar-pv-claim spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi --- apiVersion: apps/v1 kind: Deployment metadata: name: ziti-tunnel-sidecar-demo spec: replicas: 1 selector: matchLabels: app: ziti-tunnel-sidecar-demo strategy: type: Recreate template: metadata: labels: app: ziti-tunnel-sidecar-demo spec: containers: - image: centos name: testclient command: ["sh","-c","while true; set -x; do curl -sSLf ethzero.ziti.ui 2>&1; set +x; sleep 5; done"] - image: netfoundry/ziti-tunnel:0.5.8-2554 name: ziti-tunnel env: - name: NF_REG_NAME value: tunnel-sidecar volumeMounts: - name: tunnel-sidecar-jwt mountPath: "/var/run/secrets/netfoundry.io/enrollment-token" readOnly: true - name: ziti-tunnel-persistent-storage mountPath: /netfoundry securityContext: capabilities: add: - NET_ADMIN dnsPolicy: "None" dnsConfig: nameservers: - 127.0.0.1 - 184.108.40.206 restartPolicy: Always volumes: - name: ziti-tunnel-persistent-storage persistentVolumeClaim: claimName: tunnel-sidecar-pv-claim - name: tunnel-sidecar-jwt secret: secretName: tunnel-sidecar.jwt
You'll notice that the
ziti-tunnel sidecar container has a few requirements:
- The name of the identity that is assumed by
ziti-tunnelmust be passed into the container with the
- The secret that we created above for the enrollment token must be mounted into the container at "/var/run/secrets/netfoundry.io/enrollment-token".
- A persistent volume must be mounted at "/netfoundry". This volume is used to save the json file that is created when the one-time enrollment token is used. If this volume is not persistent, you will need to provide a new enrollment token each time the Pod is restarted!
Once the yaml is saved, we can deploy the Pod with
$ kubectl apply -f ./tunnel-sidecar-demo.yaml
Test the Service
First we need to get the name of the Pod that Kubernetes deployed for us:
$ kubectl get pods ziti-tunnel-sidecar-demo-749c476989-6wpfn 1/1 Running 0 42s
Then we can tail the logs for the "testclient" container:
$ kubectl logs -f ziti-tunnel-sidecar-demo-749c476989-6wpfn --container testclient 220.127.116.11 18.104.22.168 22.214.171.124
Notice that the
wget client is using the DNS name that we provided in the Ziti service definition to make the