In my previous post AKS: Open Service Mesh & mTLS, I described how to deploy an AKS cluster with Open Service Mesh enabled, and how:
- Easy is to onboard applications onto the mesh by enabling automatic sidecar injection of Envoy proxy.
- OSM enables secure service to service communication.
This time I’ll show you that Open Service Mesh (OSM) also provides a nice feature for controlling traffic between microservices: Traffic Access Control based on the SMI specifications.
To control traffic between microservices using OSM you have to be aware of the following custom resource definitions:
- HTTPRouteGroup: used to describe HTTP/1 and HTTP/2 traffic, enumerating the routes that can be served by an application.
- TCPRoute: used to describe L4 TCP traffic for a list of ports.
- UDPRoute: used to describe L4 UDP traffic for a list of ports.
- TrafficTarget: associates a set of traffic definitions (rules) with a service identity which is allocated to a group of pods. Access is controlled via referenced TrafficSpecs (HTTPRouteGroup, TCPRoute, UDPRoute) and by a list of source service identities.
Access is controlled based on service identity, at present the method of assigning service identity is using Kubernetes service accounts, provision for other identity mechanisms will be handled by the spec at a later date.
A valid TrafficTarget must specify a destination, at least one rule, and at least one source.
Now let’s see how this works:
Deploy an AKS cluster with OSM enabled
Follow the steps in my previous post AKS: Open Service Mesh & mTLS to deploy an AKS cluster with Open Service Mesh enabled.
Disable Permissive Traffic Policy Mode
By default the OSM service mesh is configured to allow all traffic between services, so let’s disable the Permissive Traffic Policy Mode by running:
1kubectl patch meshconfig osm-mesh-config -n kube-system -p '{"spec":{"traffic":{"enablePermissiveTrafficPolicyMode":false}}}' --type=merge
Double check that the Permissive Traffic Policy Mode is disabled:
1kubectl get meshconfig osm-mesh-config -n kube-system -o yaml | grep -i enablePermissiveTrafficPolicyMode
Deploy the sample microservices
Create nginx.yaml with the following contents:
1---
2apiVersion: v1
3kind: ServiceAccount
4metadata:
5 creationTimestamp: null
6 name: nginx
7 namespace: default
8
9---
10apiVersion: v1
11kind: Pod
12metadata:
13 name: nginx
14 labels:
15 run: nginx
16 annotations:
17 openservicemesh.io/sidecar-injection: enabled
18spec:
19 containers:
20 - image: nginx
21 name: nginx
22 ports:
23 - containerPort: 80
24 serviceAccountName: nginx
25
26---
27apiVersion: v1
28kind: Service
29metadata:
30 creationTimestamp: null
31 name: nginx
32spec:
33 ports:
34 - port: 80
35 protocol: TCP
36 targetPort: 80
37 selector:
38 run: nginx
Note that:
- The
openservicemesh.io/sidecar-injection: enabled
annotation is required to enable sidecar injection. - The service account
nginx
is used to run the nginx container and will be key when defining the traffic rules.
Create busybox.yaml with the following contents:
1---
2apiVersion: v1
3kind: ServiceAccount
4metadata:
5 creationTimestamp: null
6 name: busybox
7 namespace: default
8
9---
10apiVersion: v1
11kind: Pod
12metadata:
13 name: busybox
14 labels:
15 run: busybox
16 annotations:
17 openservicemesh.io/sidecar-injection: enabled
18spec:
19 containers:
20 - image: busybox
21 name: busybox
22 ports:
23 - containerPort: 80
24 command:
25 - sh
26 - -c
27 - sleep 3600
28 serviceAccountName: busybox
Note that:
- The
openservicemesh.io/sidecar-injection: enabled
annotation is required to enable sidecar injection. - The service account
busybox
is used to run the busybox container and will be key when defining the traffic rules.
Deploy the microservices:
1kubectl apply -f nginx.yaml
2kubectl apply -f busybox.yaml
Test Connectivity
Since we disabled the Permissive Traffic Policy Mode, traffic is not allowed between the microservices. Test the connectivity by running the following:
1kubectl exec -it busybox -c busybox -- sh
once inside the container, run:
1wget -O- http://nginx
The result should be similar to the following:
1Connecting to nginx (10.0.149.72:80)
2wget: error getting response: Resource temporarily unavailable
Add Traffic Access Control to allow traffic between microservices
Let’s fix the issue by adding Traffic Access Control to the mesh and allow communication between the microservices:
Create nginx_traffic_target.yaml with the following contents:
1apiVersion: specs.smi-spec.io/v1alpha4
2kind: HTTPRouteGroup
3metadata:
4 name: all-routes
5 namespace: default
6spec:
7 matches:
8 - name: everything
9 pathRegex: "/*"
10 methods: ["*"]
11
12---
13apiVersion: access.smi-spec.io/v1alpha3
14kind: TrafficTarget
15metadata:
16 name: nginx
17 namespace: default
18spec:
19 destination:
20 kind: ServiceAccount
21 name: nginx
22 namespace: default
23 rules:
24 - kind: HTTPRouteGroup
25 name: all-routes
26 matches:
27 - everything
28 sources:
29 - kind: ServiceAccount
30 name: busybox
31 namespace: default
Note that:
- The
HTTPRouteGroup
all-routes
allows all traffic and methods, but you could easily make it more restrictive. - The
TrafficTarget
associates the destination and source with the rules. - The
TrafficTarget
definessources
anddestination
by using service account names:nginx
andbusybox
.
Deploy the HTTPRouteGroup and the TrafficTarget
Run:
1kubectl apply -f nginx_traffic_target.yaml
Recheck Connectivity
Now that we explicitly allowed traffic between the microservices, we can test connectivity by running the following:
1kubectl exec -it busybox -c busybox -- sh
and once inside the container, run the following command to test connectivity:
1wget -O- http://nginx
Hope it helps!!!
Please find the complete sample here
References:
Comments