Skip to content

Commit

Permalink
#185492729 : Istio support and example cluster configuration (#4)
Browse files Browse the repository at this point in the history
Istio support for the WASM plugin
  • Loading branch information
bakennedy authored Jul 10, 2023
1 parent bc43d95 commit 84d0ff5
Show file tree
Hide file tree
Showing 17 changed files with 469 additions and 64 deletions.
19 changes: 19 additions & 0 deletions Cargo-build.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Build environment setup
# examples/envoy/docker-compose.yaml shows how to mount the build directory
# as a volume so the build artifacts will be cached locally
FROM rust:1.70.0 as builder

# The user ID and group ID of the host user
# so the container can be run as the host user to avoid permission issues
ARG USER_ID
ARG GROUP_ID

# Create a new user with the host user's ID and group ID
# This enables mounting the project directory as a volume for build caching
RUN groupadd -f -g $GROUP_ID user && useradd -l -u $USER_ID -g user user
USER user

WORKDIR /build

# Install wasm32-wasi target to build for WASM
RUN rustup target add wasm32-wasi
108 changes: 106 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ These configuration options are specified as JSON in the `configuration` section
| `user_id_header` | String | None | Optional. The header key for User Id. If provided, the corresponding header value is used as the User Id in Moesif event models. |
| `company_id_header` | String | None | Optional. The header key for Company Id. If provided, the corresponding header value is used as the Company Id in Moesif event models. |
| `batch_max_size` | Integer | 100 | Optional. The maximum batch size of events to be sent to Moesif. |
| `batch_max_wait` | Integer | 2 | Optional. The maximum wait time in seconds before a batch is sent to Moesif, regardless of the batch size. |
| `upstream` | String | "moesif_api" | Optional. The upstream cluster in Envoy that points to Moesif's API. |
| `batch_max_wait` | Integer | 2000 | Optional. The maximum wait time in milliseconds before a batch is sent to Moesif, regardless of the batch size. |
| `upstream` | String | "moesif_api" | Optional. The upstream cluster that points to Moesif's API. |

### Example

Expand Down Expand Up @@ -169,6 +169,110 @@ If you're using Docker, you can use the provided `docker-compose.yaml` to easily

Remember to replace `<YOUR APPLICATION ID HERE>` in `envoy.yaml` file with your actual Moesif Application Id. Your Moesif Application Id can be found in the [_Moesif Portal_](https://www.moesif.com/).

### Moesif Istio WASM Plugin Example

This README describes how to install and configure the Moesif Istio WASM Plugin with Minikube, using the Kubernetes resources provided.

### Prerequisites

You'll need access to a Kubernetes cluster into which to install the Moesif Istio WASM Plugin. This example uses Minikube to provide everything you need, but you can use any Kubernetes cluster:
- [Istioctl](https://istio.io/latest/docs/setup/getting-started/#download) (v1.10.0 or later)
- [Minikube](https://minikube.sigs.k8s.io/docs/start/) (v1.27 or later)
- [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) (v1.25 or later)

Start Minikube giving it enough resources:

```bash
minikube start --cpus 4 --memory 8192
```

### Istio Installation

We're going to use the Istio CLI tool for the installation.

1. Install the Istio base chart which includes cluster-wide resources used by the Istio operator:

```bash
istioctl install --set profile=demo -y
```

2. Check the status of the Istio system pods:

```bash
kubectl get pods -n istio-system
```

### Deploy the Moesif Istio WASM Plugin Example

1. Navigate to the `examples/istio` directory in this repository:

2. Apply the resources to your Minikube cluster. This will create the echo service, Istio inbound configuration to route traffic to the echo service, Istio outbound configuration to allow Istio to contact Moesif's API, and the Moesif WASM plugin itself:

```bash
kubectl apply -f echo-service.yaml \
-f istio-echo-inbound.yaml \
-f istio-moesif-outbound.yaml \
-f moesif-wasm-plugin.yaml
```

3. Verify that the echo service is running:

```bash
kubectl get pods -n default
```

You should see the `echo` pod in the Running status.

4. Test the echo service:

```bash
kubectl port-forward svc/echo 8080:80
```

Now you can send a request to the echo service running inside the cluster from the host machine:

```bash
curl http://localhost:8080/echo
```

You should get a response: `Hello from echo service` validating the service is running.

### Moesif WASM Plugin Configuration

The WasmPlugin YAML definition in `moesif-wasm-plugin.yaml` configures the Moesif Istio WASM Plugin. The pluginConfig section of the YAML definition is shown below:

```yaml
moesif_application_id: <YOUR MOESIF APPLICATION ID>
upstream: outbound|443||api.moesif.net
```

This configuration allows the plugin to capture and log the requests and responses flowing through the Istio service mesh. To use the plugin, you need a Moesif application id, which is set in the `moesif_application_id` field in the plugin configuration. You can get this from your Moesif dashboard.

Remember to replace the `moesif_application_id` and `upstream` values in with your actual values. The upstream string value is the cluster name that points to Moesif's API in the Istio outbound configuration. `debug` is set to `true` to enable debug logging for the example, but this should be set to `false` in production.

### Accessing the echo service via Istio Ingress Gateway

Next, access the echo service via Istio Ingress Gateway, you first need to determine the ingress IP and ports:

- For Minikube:

```bash
export INGRESS_HOST=$(minikube ip)
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
```

Now, you can send a request to the echo service through the Istio Ingress Gateway and the Moesif WASM Plugin:

```bash
curl -sS "http://${INGRESS_HOST}:${INGRESS_PORT}/echo"
```

The response should be `Hello from echo service`.

### Finished, Check Logs

After the configuration is applied, you can check the events in your https://moesif.com account to see the plugin in action.

## Other Integrations

To view more documentation on integration options, please visit __[the Integration Options Documentation](https://www.moesif.com/docs/getting-started/integration-options/).__
3 changes: 2 additions & 1 deletion examples/envoy/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
version: '3.8'
services:
rust-builder:
image: moesiftest.azurecr.io/moesif-envoy-wasm-plugin-builder:latest
build:
context: ../../moesif-wasm/
context: ../../
dockerfile: Cargo-build.dockerfile
args:
USER_ID: ${UID:-1000}
Expand Down
2 changes: 1 addition & 1 deletion examples/envoy/envoy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ static_resources:
{
"moesif_application_id":"<YOUR APPLICATION ID HERE>",
"user_id_header":"X-User-Example-Header",
"company_id_header":"X-Company-Example-Header"
"debug":true
}
vm_config:
vm_id: "moesif_api_vm"
Expand Down
3 changes: 3 additions & 0 deletions examples/istio/artifact.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FROM scratch

COPY moesif_envoy_wasm_plugin.wasm ./plugin.wasm
34 changes: 34 additions & 0 deletions examples/istio/echo-service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
apiVersion: v1
kind: Service
metadata:
name: echo
namespace: default
spec:
ports:
- port: 80
targetPort: 5678
selector:
app: echo
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: echo
template:
metadata:
labels:
app: echo
spec:
containers:
- name: echo
image: hashicorp/http-echo
args:
- "-text=Hello from echo service"
ports:
- containerPort: 5678
35 changes: 35 additions & 0 deletions examples/istio/istio-echo-inbound.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: http-echo-gateway
namespace: default
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: echo-virtual-service
namespace: default
spec:
hosts:
- "*"
gateways:
- http-echo-gateway
http:
- match:
- uri:
exact: /echo
route:
- destination:
host: echo
port:
number: 80
26 changes: 26 additions & 0 deletions examples/istio/istio-moesif-outbound.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# This file is used to configure Istio to allow traffic to Moesif API
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: moesif
namespace: istio-system
spec:
hosts:
- api.moesif.net
ports:
- number: 443
name: https
protocol: HTTPS
location: MESH_EXTERNAL
resolution: DNS
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: moesif
namespace: istio-system
spec:
host: api.moesif.net
trafficPolicy:
tls:
mode: SIMPLE
19 changes: 19 additions & 0 deletions examples/istio/moesif-wasm-plugin.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
name: moesif-plugin
namespace: istio-system
spec:
selector:
matchLabels:
istio: ingressgateway
url: oci://docker.io/moesif/moesif-envoy-wasm-plugin:latest
imagePullPolicy: Always
phase: AUTHZ
priority: 10
pluginConfig:
moesif_application_id: <YOUR MOESIF APPLICATION ID>
user_id_header: X-User-Example-Header
company_id_header: X-Company-Example-Header
upstream: outbound|443||api.moesif.net
debug: true
46 changes: 46 additions & 0 deletions examples/istio/publish_docker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/bin/bash -e

TAG=${1:-latest}
if [ "$2" == "debug" ]; then
BUILD_VARIANT=debug
BUILD_FLAGS=""
else
BUILD_VARIANT=release
BUILD_FLAGS="--release"
fi

# Docker image names
REPO=docker.io/moesif
TAG_BUILD=$REPO/moesif-envoy-wasm-plugin-builder:latest
TAG_ARTIFACT=$REPO/moesif-envoy-wasm-plugin:$TAG
TAG_LATEST=$REPO/moesif-envoy-wasm-plugin:latest

# Get the directory of this script to make sure we can run it from anywhere
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BASE_DIR="$SCRIPT_DIR/../.."
SOURCE="$BASE_DIR/moesif-wasm"
OUTPUT="$SOURCE/target/wasm32-wasi/$BUILD_VARIANT"

# Create the build environment for the plugin
docker build \
--build-arg USER_ID=$(id -u) --build-arg GROUP_ID=$(id -g) \
-t $TAG_BUILD \
-f $BASE_DIR/Cargo-build.dockerfile \
$SOURCE

# perform the build inside the container by mounting the current directory
docker run \
-v $SOURCE:/build \
$TAG_BUILD \
bash -c "cargo build --target=wasm32-wasi $BUILD_FLAGS"

# package the plugin into a docker image for deployment
docker build \
-t $TAG_ARTIFACT \
-f $BASE_DIR/examples/istio/artifact.dockerfile \
$OUTPUT

docker push $TAG_ARTIFACT

docker tag $TAG_ARTIFACT $TAG_LATEST
docker push $TAG_LATEST
48 changes: 48 additions & 0 deletions examples/istio/publish_wasmhub.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/bin/bash -e
TAG=${1:-latest}

if [ "$2" == "debug" ]; then
BUILD_VARIANT=debug
BUILD_FLAGS=""
else
BUILD_VARIANT=release
BUILD_FLAGS="--release"
fi

TAG=${1:-latest}

# WASME is use to publish to WebAssemblyHub
# https://docs.solo.io/web-assembly-hub/latest/installation/
WASME=$HOME/.wasme/bin/wasme

# Get the directory of this script to make sure we can run it from anywhere
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BASE_DIR="$SCRIPT_DIR/../.."
SOURCE="$BASE_DIR/moesif-wasm"
OUTPUT="$SOURCE/target/wasm32-wasi/$BUILD_VARIANT"

# Docker image names
TAG_BUILD=moesiftest.azurecr.io/moesif-envoy-wasm-plugin-builder:latest
TAG_ARTIFACT=webassemblyhub.io/brian_moesif/moesif_envoy_wasm_plugin

# Create the build environment for the plugin
docker build \
--build-arg USER_ID=$(id -u) --build-arg GROUP_ID=$(id -g) \
-t $TAG_BUILD \
-f $BASE_DIR/Cargo-build.dockerfile \
$SOURCE

# perform the build inside the container by mounting the current directory
docker run \
-v $SOURCE:/build \
$TAG_BUILD \
bash -c "cargo build --target=wasm32-wasi $BUILD_FLAGS"

# package the plugin into a docker image for deployment
VERSION_TAG=$TAG_ARTIFACT:$TAG
$WASME build precompiled $BASE_DIR/moesif-wasm/target/wasm32-wasi/$BUILD_VARIANT/moesif_envoy_wasm_plugin.wasm --tag $VERSION_TAG --config $BASE_DIR/runtime-config.json
$WASME push $VERSION_TAG

LATEST_TAG=$TAG_ARTIFACT:latest
$WASME tag $VERSION_TAG $LATEST_TAG
$WASME push $LATEST_TAG
Loading

0 comments on commit 84d0ff5

Please sign in to comment.