Open3

Mesh Week: Traffic Management (# 1)

takashi.kanazawatakashi.kanazawa

I tried the mock exam provided by Mesh Week at the following link:

https://docs.google.com/forms/d/e/1FAIpQLSfD4BLLQfdUwnIyiTBSGC_OzmSbiyrIlNp5Am61fTOhRbfiLw/viewform

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.

takashi.kanazawatakashi.kanazawa

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.

takashi.kanazawatakashi.kanazawa

The original question has the payments and frontend workloads in the default namespace, but I changed each of them to a different namespace.