Skip to content

Commit

Permalink
Add ztunnel example
Browse files Browse the repository at this point in the history
  • Loading branch information
bkneis authored and pascalbreuninger committed Nov 20, 2024
1 parent 4856dbd commit d703f83
Show file tree
Hide file tree
Showing 6 changed files with 614 additions and 0 deletions.
138 changes: 138 additions & 0 deletions examples/ztunnel/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# Ztunnel example

```bash
curl -L -o devpod "https://github.com/loft-sh/devpod/releases/latest/download/devpod-darwin-arm64" && sudo install -c -m 0755 devpod /usr/local/bin && rm -f devpod
```

Update the provider

```bash
devpod provider update kubernetes kubernetes
```

Version deployed and version of source code matters. Make sure they match. Pull the latest version of the source code. And copy the devcontainer.json file to the source code. Or you can use the latest version of `gcr.io/istio-testing/build-tools` image.

Make sure you hve a fresh installation of Istio:

```bash
istioctl uninstall --purge -y

istioctl install -y --set profile=ambient --set meshConfig.accessLogFile=/dev/stdout
```

Also, if you want to start from scratch, better you delete the devpod:

```bash
devpod delete . --force
```

Let's deploy an app to test ambient:

```bash
kubectl create ns my-ambient
kubectl label namespace my-ambient istio.io/dataplane-mode=ambient --overwrite
kubectl apply -f sleep.yaml -n my-ambient
kubectl apply -f helloworld.yaml -n my-ambient
```

Verify that app was included to Ambient mode:

```bash
kubectl -n istio-system logs -l k8s-app=istio-cni-node
```

Send traffic to the app:

```bash
kubectl -n my-ambient exec deploy/sleep -- sh -c 'for i in $(seq 1 100); do curl -s -I http://helloworld:5000/hello; done'
```

Output:

```text
HTTP/1.1 200 OK
Server: gunicorn
Date: Tue, 23 Jul 2024 14:21:03 GMT
Connection: keep-alive
Content-Type: text/html; charset=utf-8
Content-Length: 60
```

Verify that the logs are being written to the stdout:

```bash
kubectl -n istio-system logs -l app=ztunnel
```

Output:

```text
2024-07-23T14:21:03.450051Z info access connection complete src.addr=10.12.0.8:37522 src.workload=sleep-bc9998558-bhv5z src.namespace=my-ambient src.identity="spiffe://cluster.local/ns/my-ambient/sa/sleep" dst.addr=10.12.0.9:15008 dst.hbone_addr=10.12.0.9:5000 dst.service=helloworld.my-ambient.svc.cluster.local dst.workload=helloworld-v1-77489ccb5f-pjbq5 dst.namespace=my-ambient dst.identity="spiffe://cluster.local/ns/my-ambient/sa/default" direction="outbound" bytes_sent=84 bytes_recv=158 duration="118ms"
```

At this point, traffic flows through the ztunnel.

Let's label with `devpod-ztunnel=enabled` only one node to deploy devpod-ztunnel in there:

```shell
FIRST_NODE=$(kubectl get nodes -o jsonpath='{.items[0].metadata.name}')
kubectl label node $FIRST_NODE devpod-ztunnel=enabled
```

Next command add nodeAffinity to make sure that the upstream ztunnel is not deployed in any node so our test if focused on one node and one devpod-ztunnel:

```bash
kubectl patch daemonset -n istio-system ztunnel --type=merge -p='{"spec":{"template":{"spec":{"affinity":{"nodeAffinity":{"requiredDuringSchedulingIgnoredDuringExecution":{"nodeSelectorTerms":[{"matchExpressions":[{"key":"upstream-ztunnel","operator":"In","values":["no"]}]}]}}}}}}}'
```

You should see that the ztunnel is not deployed anymore.

**NOTE**: To revert the previous command, run the following:

```bash
# RUN THIS ONLY TO REVERT THE PREVIOUS COMMAND
# kubectl patch daemonset -n istio-system ztunnel --type=merge -p='{"spec":{"template":{"spec":{"affinity":{"nodeAffinity":{"requiredDuringSchedulingIgnoredDuringExecution":{"nodeSelectorTerms":[{"matchExpressions":[{"key":"upstream-ztunnel","operator":"NotIn","values":["no"]}]}]}}}}}}}'
```

Make sure you have docker installed:

```bash
docker --version
```

Go to the root of the project and run the devpod:

**Note** Normally, to start a Devpod is a straight forward simple command. However, given the complexty of ztunnel setup, we need to adjut it a bit.

- `devcontainer.json` is overriden. In our version, we create a `postStartCommand` required to set the secret in the place that ztunnel app can find. Also, some `remoteEnv` are set to help on builing the app in the remote container.
- Using Kind cluster, the `STORAGE_CLASS` is `standard`. If you are using a different cluster, you may need to change it (i.e in EKS it would be `gp2`)
- The template of the pod is also overriden to match what ztunnel needs to run.

```bash
devpod up . --provider-option STORAGE_CLASS=gp2 --provider-option KUBECTL_PATH=/usr/local/bin/kubectl --provider-option KUBERNETES_NAMESPACE=istio-system --provider-option POD_MANIFEST_TEMPLATE=$(pwd)/devpod/pod_manifest.yaml --devcontainer-path devpod/devcontainer.json --ide vscode --debug \
--recreate --reset
```

You will see DevPod cli copying your project files to the remote container. In the case of ztunnel project, make sure that the `out` folder is deleted before starting devpod. That folder is usully too heavy and unnecesary to be copied to the container.

At the moment, changes in the project when working in the container are not reflected in the local files. To do so, you can run the following command:

```bash
rsync -rlptzv --progress --delete --exclude=.git --exclude=out "ztunnel.devpod:/workspaces/ztunnel" .
```

When the process finishes, you can build the project:

```bash
cargo clean


RUST_LOG="debug" CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="sudo -E" cargo build --bin=ztunnel --package=ztunnel --message-format=json
```







35 changes: 35 additions & 0 deletions examples/ztunnel/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"name": "istio build-tools",
"image": "gcr.io/istio-testing/build-tools:release-1.23-d82829888b6f4a2b2b2644fe481d72ced2e402aa",
"postStartCommand": "mkdir -p /workspaces/ztunnel/var/run/secrets; cp -R /var/run/secrets/tokens /workspaces/ztunnel/var/run/secrets/; cp -R /var/run/secrets/istio /workspaces/ztunnel/var/run/secrets/",
"privileged": true,
"remoteEnv": {
"USE_GKE_GCLOUD_AUTH_PLUGIN": "True",
"BUILD_WITH_CONTAINER": "0",
"CARGO_HOME": "/home/.cargo",
"RUSTUP_HOME": "/home/.rustup",
"CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER": "sudo -E"
},
// "features": {
// "ghcr.io/devcontainers/features/docker-outside-of-docker:1": {}
// },
"customizations": {
"vscode": {
"extensions": [
"golang.go",
"rust-lang.rust-analyzer",
"eamodio.gitlens",
"zxh404.vscode-proto3",
"ms-azuretools.vscode-docker",
"redhat.vscode-yaml",
"IBM.output-colorizer",
"vadimcn.vscode-lldb"
],
"settings": {
"files.eol": "\n",
"go.useLanguageServer": true,
"go.lintTool": "golangci-lint"
}
}
}
}
80 changes: 80 additions & 0 deletions examples/ztunnel/helloworld.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
service: helloworld
spec:
ports:
- port: 5000
name: http
selector:
app: helloworld
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-v1
labels:
app: helloworld
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
version: v1
template:
metadata:
labels:
app: helloworld
version: v1
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: devpod-ztunnel
operator: In
values:
- enabled
containers:
- name: helloworld
image: docker.io/istio/examples-helloworld-v1
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent #Always
ports:
- containerPort: 5000
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-v2
labels:
app: helloworld
version: v2
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
version: v2
template:
metadata:
labels:
app: helloworld
version: v2
spec:
containers:
- name: helloworld
image: docker.io/istio/examples-helloworld-v2
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent #Always
ports:
- containerPort: 5000
125 changes: 125 additions & 0 deletions examples/ztunnel/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Debug unit tests in library 'ztunnel'",
"cargo": {
"args": [
"test",
"--no-run",
"--lib",
"--package=ztunnel"
],
"filter": {
"name": "ztunnel",
"kind": "lib"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug executable 'ztunnel'",
"cargo": {
"args": [
"build",
"--bin=ztunnel",
"--package=ztunnel"
],
"filter": {
"name": "ztunnel",
"kind": "bin"
}
},
"args": [],
"cwd": "${workspaceFolder}",
"env": {
"RUST_LOG": "debug",
"CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER": "sudo -E",
}
},
{
"type": "lldb",
"request": "launch",
"name": "Debug unit tests in executable 'ztunnel'",
"cargo": {
"args": [
"test",
"--no-run",
"--bin=ztunnel",
"--package=ztunnel"
],
"filter": {
"name": "ztunnel",
"kind": "bin"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug integration test 'namespaced'",
"cargo": {
"args": [
"test",
"--no-run",
"--test=namespaced",
"--package=ztunnel"
],
"filter": {
"name": "namespaced",
"kind": "test"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug integration test 'direct'",
"cargo": {
"args": [
"test",
"--no-run",
"--test=direct",
"--package=ztunnel"
],
"filter": {
"name": "direct",
"kind": "test"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug benchmark 'throughput'",
"cargo": {
"args": [
"test",
"--no-run",
"--bench=throughput",
"--package=ztunnel"
],
"filter": {
"name": "throughput",
"kind": "bench"
}
},
"args": [],
"cwd": "${workspaceFolder}"
}
]
}
Loading

0 comments on commit d703f83

Please sign in to comment.