Skip to content

Instantly share code, notes, and snippets.

@jpeach
Last active January 11, 2022 06:54
Show Gist options
  • Save jpeach/cd097d09fba37acbaadd110c4b332a3a to your computer and use it in GitHub Desktop.
Save jpeach/cd097d09fba37acbaadd110c4b332a3a to your computer and use it in GitHub Desktop.
Kuma Gateway Demo
This is a quick demo of Kuma Gateway in Universal mode.
This demo just runs Kuma locally so that all the components are running on the same host.
Some of the scripts assume that Kuma tools are in your $PATH. This will be true if you use
direnv amd `make dev/envrc` in your working Kuma repository.
#! /usr/binenv bash
# First build Kuma with gateway enabled.
make build BUILD_WITH_EXPERIMENTAL_GATEWAY=Y
#! /usr/bin/env bash
# Next, start a local kuma-cp instance. Because kuma-cp is running on localhost,
# we don't need to worry about any special access control config.
./build/artifacts-linux-amd64/kuma-cp/kuma-cp run
#! /usr/bin/env bash
# This script starts an echo server (Kuma test-server) and runs it with an envoy side-car.
set -o errexit
clean::name() {
echo "$@" | tr --delete --complement '[0-9a-z]_-'
}
kill::tagged() {
kill -TERM $(ps e | grep --fixed-strings -e "KILLTAG=$KILLTAG" | awk '{print $1}') 2>/dev/null
}
readonly ENVOY=${ENVOY:-./build/artifacts-linux-amd64/envoy/envoy-1.20.1-dev-b16d390f-alpine}
readonly KILLTAG="$(basename $0)-$RANDOM"
readonly NAME=$(clean::name "$(hostname)-echo-server")
trap kill::tagged EXIT
kumactl apply -f <(
cat <<EOF
type: Dataplane
mesh: default
name: $NAME
networking:
address: 127.0.0.1
inbound:
- port: 20011
servicePort: 10011
tags:
kuma.io/service: echo-service
EOF
)
# Start the echo server in the background.
env KILLTAG=$KILLTAG \
test-server echo --instance="$(basename $0)-$$" --port=10011 &
# Start kuma-cp sidecar in the background.
env KILLTAG=$KILLTAG \
kuma-dp run \
--binary-path=$ENVOY \
--dataplane-token=$(kumactl generate dataplane-token --proxy-type=dataplane) \
--proxy-type=dataplane \
--mesh=default \
--name=$NAME \
"$@" &
# Wait for all the child processes to complete.
wait
#! /usr/bin/env bash
# Now we start a DP in builtin gateway mode. This is a DP with serving capacity that we can bind
# Gateway resources to.
#
# Note the service name in SERVICE, which is the primary key for matching policies to this DP.
readonly SERVICE="edge-gateway"
# The default envoy comes from the Kuma build.
readonly ENVOY=${ENVOY:-./build/artifacts-linux-amd64/envoy/envoy-1.20.1-dev-b16d390f-alpine}
# Request a dataplane token from kuma-cp.
readonly TOKEN=$(kumactl generate dataplane-token --proxy-type=dataplane)
exec kuma-dp run \
--binary-path=$ENVOY \
--dataplane-token=$(kumactl generate dataplane-token --proxy-type=${DPTYPE}) \
--proxy-type=dataplane \
--dataplane-file=<(
cat <<EOF
type: Dataplane
mesh: default
name: $(hostname)-$SERVICE
networking:
address: 127.0.0.1
gateway:
type: BUILTIN
tags:
kuma.io/service: $SERVICE
EOF
) "$@"
#! /usr/bin/env
# Now we can create a Kateway resource and bind it to the dataplane using the "edge-gateway"
# service tag. We have 2 hostnames listening on port 8080.
kumactl apply -f <(
cat <<EOF
type: Gateway
mesh: default
name: edge-gateway
selectors:
- match:
kuma.io/service: edge-gateway
conf:
listeners:
- port: 8080
protocol: HTTP
hostname: foo.example.com
tags:
hostname: foo.example.com
- port: 8080
protocol: HTTP
hostname: bar.example.com
tags:
hostname: bar.example.com
EOF
)
#! /usr/bin/env bash
# Now, we can create a route from the edge gateway to the echo service.
# We match the prefix "/", so this will take all requests.
# The route policy selector matches on the service, so this route will attach to all listeners.
# curl -H "Host: foo.example.com" http://127.0.0.1:8080/bar
# curl -H "Host: bar.example.com" http://127.0.0.1:8080/bar
kumactl apply -f <(
cat <<EOF
type: GatewayRoute
mesh: default
name: edge-gateway
selectors:
- match:
kuma.io/service: edge-gateway
conf:
http:
rules:
- matches:
- path:
match: PREFIX
value: /
backends:
- destination:
kuma.io/service: echo-service
EOF
)
#! /usr/bin/env bash
# Now, we delete that route (because it captures /), and create specific routes for each host.
# This shows how we can match routes to a subset of gateway listeners.
# We ensure that the "foo" host only routes /foo and "bar" host only routes /bar.
# You can also implement something similar using tha listener.hostname field but this is more general.
# kumactl get gateway-routes
# This now emits a 404P
# curl -v -H "Host: foo.example.com" http://127.0.0.1:8080/bar
kumactl delete gateway-route edge-gateway
kumactl apply -f <(
cat <<EOF
type: GatewayRoute
mesh: default
name: foo-gateway
selectors:
- match:
kuma.io/service: edge-gateway
hostname: foo.example.com
conf:
http:
rules:
- matches:
- path:
match: PREFIX
value: /foo
backends:
- destination:
kuma.io/service: echo-service
EOF
)
kumactl apply -f <(
cat <<EOF
type: GatewayRoute
mesh: default
name: bar-gateway
selectors:
- match:
kuma.io/service: edge-gateway
hostname: bar.example.com
conf:
http:
rules:
- matches:
- path:
match: PREFIX
value: /bar
backends:
- destination:
kuma.io/service: echo-service
EOF
)
#! /usr/bin/env bash
# Now we rewrite the Gateway to also listen on port 8443 for HTTPS sessions to the same hostnames
kumactl apply -f <(
cat <<EOF
type: Gateway
mesh: default
name: edge-gateway
selectors:
- match:
kuma.io/service: edge-gateway
conf:
listeners:
- port: 8080
protocol: HTTP
hostname: foo.example.com
tags:
hostname: foo.example.com
- port: 8080
protocol: HTTP
hostname: bar.example.com
tags:
hostname: bar.example.com
- port: 8443
protocol: HTTPS
hostname: foo.example.com
tags:
hostname: foo.example.com
tls:
mode: TERMINATE
certificates:
- secret: foo-example-com-certificate
- port: 8443
protocol: HTTPS
hostname: bar.example.com
tags:
hostname: bar.example.com
tls:
mode: TERMINATE
certificates:
- secret: bar-example-com-certificate
EOF
)
#! /usr/bin/env bash
# Now generate TLS secrets. Each secret contains the TLS server certificate and private key, as well as any
# needed certificate chain.
# Base64 the whole thing into a YAML string.
# curl --insecure --resolve bar.example.com:8443:127.0.0.1 https://bar.example.com:8443/bar
# curl --insecure --resolve foo.example.com:8443:127.0.0.1 https://bar.example.com:8443/foo
NAME=foo.example.com
kumactl apply -f <(
cat<<EOF
type: Secret
mesh: default
name: $(echo $NAME | tr . -)-certificate
data: $(kumactl generate tls-certificate --type=server --hostname=$NAME --key-file=- --cert-file=- | base64 -w0)
EOF
)
NAME=bar.example.com
kumactl apply -f <(
cat<<EOF
type: Secret
mesh: default
name: $(echo $NAME | tr . -)-certificate
data: $(kumactl generate tls-certificate --type=server --hostname=$NAME --key-file=- --cert-file=- | base64 -w0)
EOF
)
#! /usr/bin/env bash
# Now for the hostname foo.example.com, we can install a redirect to send HTTP requsts back to HTTPS.
# curl doesn't seem to resolve properly, but the following ought to work:
# curl -v --location --insecure --resolve bar.example.com:8443:127.0.0.1 -H "Host: foo.example.com" http://127.0.0.1:8080/foo
kumactl apply -f <(
cat <<EOF
type: GatewayRoute
mesh: default
name: foo-gateway
selectors:
- match:
kuma.io/service: edge-gateway
hostname: foo.example.com
conf:
http:
rules:
- matches:
- path:
match: PREFIX
value: /
filters:
- redirect:
scheme: https
hostname: foo.example.com
port: 8443
statusCode: 302
EOF
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment