Mesh Week: Traffic Management (# 1)
I tried the mock exam provided by Mesh Week at the following link:
Question: Traffic Management
You have access to a Kubernetes cluster with Istio installed. Two workloads are running in their respective namespaces: payments
in the payments
namespace and frontend
in the frontend
namespace. Both workloads have corresponding Kubernetes services with the same names as the workloads.
You want to expose both services through the ingress gateway as follows:
The payments service should be accessible at mycompany.com/payments
.
The frontend service should be accessible at mycompany.com
.
Create Gateway and VirtualService resources to expose the services.
Answer
Step 1: Enable Istio Sidecar Injection for Namespaces
First, enable Istio sidecar injection for the payments
and frontend
namespaces:
$ kubectl label ns payments istio-injection=enabled
$ kubectl label ns frontend istio-injection=enabled
To verify the labels:
$ kubectl get ns -L istio-injection
Output:
NAME STATUS AGE ISTIO-INJECTION
default Active 46h
frontend Active 17m enabled
payments Active 17m enabled
...
Both the frontend
and payments
namespaces now have Istio sidecar injection enabled.
Step 2: Create Deployments for Payments and Frontend
Create the deployments for the payments
and frontend
services:
$ kubectl create deployment payments --image=kennethreitz/httpbin
$ kubectl create deployment frontend --image=nginx:alpine
This creates the payments
deployment using the kennethreitz/httpbin
image and the frontend
deployment using the nginx:alpine
image.
Step 3: Verify Istio Gateway Pods are Running
Verify that Istio’s ingress and egress gateways, as well as the control plane (istiod
), are running:
$ kubectl get pod -n istio-system -L istio | grep istio
Output:
istio-egressgateway-6f4b5fb9db-9mh98 1/1 Running 0 50m egressgateway
istio-ingressgateway-6d898ccdfd-sxx6c 1/1 Running 0 50m ingressgateway
istiod-79bdb7885d-wgp8w 1/1 Running 0 50m pilot
This confirms that Istio’s core components are up and ready to handle traffic.
Step 4: Create a Gateway
Define a Gateway resource to route external traffic to the services. Create a gateway named mycompany-com-gateway
:
# mycompany-com-gateway.yaml
apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
name: mycompany-com-gateway
spec:
selector:
istio: ingressgateway # Use Istio's ingress gateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- mycompany.com
Apply the configuration:
$ kubectl apply -f mycompany-com-gateway.yaml
Step 5: Expose Services
Expose the payments
and frontend
deployments as ClusterIP services:
$ kubectl -n payments expose deployment payments --name=payments --port=80 --type=ClusterIP
$ kubectl -n frontend expose deployment frontend --name=frontend --port=80 --type=ClusterIP
Verify the services:
$ kubectl get po,svc -A | grep -e payment -e frontend
Output:
frontend pod/frontend-xxxxx 2/2 Running
payments pod/payments-xxxxx 2/2 Running
frontend service/frontend ClusterIP 10.108.148.78 <none> 80/TCP
payments service/payments ClusterIP 10.110.18.227 <none> 80/TCP
Both payments
and frontend
services are exposed and ready to receive traffic.
Step 6: Define the Virtual Service
Define a VirtualService
to route HTTP requests based on the URI. This configuration directs requests to either the payments
or frontend
service:
# mycompany-com-vs.yaml
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: mycompany-com-vs
spec:
hosts:
- mycompany.com
gateways:
- mycompany-com-gateway
http:
- match:
- uri:
prefix: "/payments"
rewrite:
uri: "/get" # Rewrite URI before forwarding
route:
- destination:
host: payments.payments.svc.cluster.local
- route:
- destination:
host: frontend.frontend.svc.cluster.local
Apply the VirtualService
:
$ kubectl apply -f mycompany-com-vs.yaml
This configuration routes /payments
requests to the payments
service, and all other traffic to frontend
.
Step 7: Test the Setup
Test Basic Access:
$ kubectl get svc -A | grep -e NAME -e ingressgateway
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-system istio-ingressgateway LoadBalancer 10.96.171.1 localhost 15021:31634/TCP,80:31790/TCP,443:31337/TCP,31400:30494/TCP,15443:31184/TCP 5h43m
# Since the EXTERNAL-IP of the Ingress Gateway service is localhost, access it via localhost.
$ curl -H "Host: mycompany.com" http://localhost:80/
Output:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
<h1>Welcome to nginx!</h1>
...
</html>
This confirms that NGINX is running and responding to the base URL.
Test /payments Route:
$ curl -H "Host: mycompany.com" http://localhost:80/payments
Output:
{
"args": {},
"headers": {
"Host": "mycompany.com",
"User-Agent": "curl/8.1.2",
"X-Envoy-Original-Path": "/payments",
"X-Forwarded-Client-Cert": "...",
},
"origin": "192.168.65.3",
"url": "http://mycompany.com/get"
}
This confirms that requests to /payments
are routed correctly, with the URI rewritten to /get
.
Successfully created an Istio-based routing solution that handles traffic for two services (payments
and frontend
) on a Kubernetes cluster.
The original question has the payments
and frontend
workloads in the default namespace, but I changed each of them to a different namespace.