Why ambient mesh and not sidecar?
Ambient mesh uses a shared agent on each Kubernetes node, called a ztunnel. This zero-trust tunnel securely connects and authenticates elements within the mesh, redirecting all traffic through the local ztunnel agent.
This separation allows operators to manage the data plane independently from applications, enabling easier scaling and upgrades.
Ztunnels provide core service mesh functions: zero trust, mTLS, telemetry, authentication, and L4 authorization, without parsing HTTP.
In comparison, ztunnel doesn't perform L7 processing, making it leaner than sidecars and suitable as shared infrastructure. The traditional sidecar, which has been a staple of Istio for years, now faces a significant competitor. This new contender challenges the long-standing dominance of the sidecar model, introducing innovative approaches and technologies that promise to enhance performance, security, and overall efficiency in service mesh architectures.
In this guide we will:
- Install Istio and it's components.
- Install a Kubernetes Gateway (not part of istio, but is in the kubernetes sig).
- Setup some HTTPRoutes.
- Restrict to ip addresses (optional).
- Profit.
Pre-requisites
This post assumes you already have istio set up in ambient
mode. In case you donโt, this will get you up and running in two minutes:
helm repo add istio <https://istio-release.storage.googleapis.com/charts> --force-update
helm install -n istio-system istio-base istio/base --create-namespace
helm install -n istio-system istio-cni istio/cni --set profile=ambient
helm install -n istio-system istiod istio/istiod --set profile=ambient
helm install -n istio-system ztunnel istio/ztunnel
helm install -n istio-ingress istio-ingress istio/gateway --create-namespace
kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || { kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.1.0" | kubectl apply -f -; }
Donโt have istioctl
yet? I got you:
curl -L <https://istio.io/downloadIstio> | sh -
sudo cp istio-1.22.2/bin/istioctl /usr/local/bin/istioctl
rm -rf istio-1.22.2
The Gateway
The Gateway API simplifies the configuration of ingress and egress traffic, providing a unified approach to managing traffic routing within the mesh. This helps in maintaining a clear and manageable structure for directing traffic to the appropriate services.
Setting Up the Gateway
To set up the Gateway, you need to create a Gateway
resource that defines how traffic enters the mesh.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: gateway
namespace: ingress-internal
spec:
gatewayClassName: istio
addresses: #
- value: 10.0.16.3 # This block is optional
type: IPAddress #
listeners:
- name: http
hostname: "*.matthewdavis.io"
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
gateway-internal-access: "true"
- name: https
hostname: "*.matthewdavis.io"
port: 443
protocol: HTTPS
tls:
mode: Terminate
certificateRefs:
- name: ingress-internal # Ensure secret is in the same namespace!
# Refence your cert-manager cert here, etc.
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
gateway-internal-access: "true"
Labeling the Namespace
๐ก If you do not label your namespace(s) to match the selector above your routes will not be added!
Next, label the namespace that will host your internal services to allow the Gateway to route traffic to them. This is a crucial step which tells istio to look for HTTPRoute
objects in this namespace.
kubectl label ns internal-services gateway-internal-access=true
Create HTTPRoute
Objects
Create HTTPRoute
resources to define how traffic should be routed to your services. Hereโs an example for two different services:
HTTP-to-HTTPS redirect
Force redirecting of http to https with this HTTPRoute
:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-to-https
namespace: istio-system
spec:
parentRefs:
- name: gateway
namespace: istio-system
sectionName: http
hostnames:
- "*.matthewdavis.io"
rules:
- filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301
Tool A
Define an HTTPRoute
for tool-a
:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: tool-a
namespace: internal-services
spec:
hostnames:
- "tool-a.matthewdavis.io"
parentRefs:
- name: gateway
namespace: ingress-internal
rules:
- backendRefs:
- name: tool-a
port: 8080
Tool B
Define an HTTPRoute
for tool-b
:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: tool-b
namespace: internal-services
spec:
hostnames:
- "tool-b.matthewdavis.io"
parentRefs:
- name: gateway
namespace: ingress-internal
rules:
- backendRefs:
- name: tool-b
port: 9090
Restrict by IP (optional)
You can easily restrict access to your HTTPRoute
's by using istio's AuthorizationPolicy
object:
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: restrict-access-by-ip
namespace: ingress-external
spec:
selector:
matchLabels:
app: nginx
action: ALLOW
rules:
- from:
- source:
remoteIpBlocks: ["1.1.1.1"]
- to:
- operation:
paths: ["/"]
Need more help?
Ping me at matthew@matthewdavis.io or mateothegreat
on discord.
Happy ingress'ing!