Guest EkeleAsonye Posted October 25, 2022 Posted October 25, 2022 A number of organizations adopting microservices architectures have looked to service meshes as one of the tools that help these organizations in enforcing enterprise-wide policies and rules for traffic, security, reliability, and monitoring. These are generally categorized into Security, Reliability and Observability. While a networking solution other than service mesh can provide some of these features, it won’t do it without disrupting the application code or existing infrastructure. Service Mesh provides an independent infrastructure layer that can be managed by a separate team and is least intrusive. It deploys a sidecar container to pods by design, which makes it very powerful for monitoring your services within a kubernetes cluster. Open Service Mesh (OSM) is a lightweight, extensible service mesh that is utilized to secure communication of services running in a Kubernetes environment. To achieve interoperability between service meshes, a common interface standard SMI (Service Mesh Interface) has been defined by CNCF. OSM is Microsoft's implementation of the Service Mesh Interface in an actual service mesh. It is easy to install, maintain and operate. It is also effortless to troubleshoot and less complicated to configure with SMI. The Open Service Mesh extension is a managed service mesh for Arc-enabled Kubernetes clusters that is lightweight and extensible. It can be configured with Service Mesh Interface APIs, works by injecting envoy proxy as a sidecar to each application instance, and brings a new Azure Portal experience for onboarding. Some of the use cases you can solve with OSM are: Service to Service communication over mutual TLS authentication Access control for service-to-service communication Traffic management for canary deployments Observability for services Traffic management capabilities like auto retries, rate limiting, circuit breaking Multi-cluster communication over mTLS. With the OSM extension being enabled through Azure Arc, OSM can be applied to your on-premises AKS hybrid environment to manage communication and secure your cloud-native workload. In this article, the OSM functionalities were applied to the communication between the bookbuyer and bookstore sample applications. First, traffic access between the bookbuyer and bookstore services was disabled, but only got enabled by applying an SMI traffic policy. Additionally, the traffic-splitting capability was also implemented by creating a second bookstore service and then weighted traffic from the bookbuyer to bookstore-v1 and bookstore-v2 respectively. Setting up OSM The latest OSM version (v1.2.0) used for this article requires a kubernetes cluster running v1.22.9 or higher and a Kubernetes command-line tool. It also requires a workstation that is capable of executing bash commands/scripts and has the OSM code repo available locally. For this work, the setup was done in an Arc-enabled Aks cluster with WSL-2 (windows subsystem for linux) enabled. To setup your own Aks hybrid cluster, see Use PowerShell to set up Kubernetes on Azure Stack HCI and Windows Server clusters - AKS-HCI | Microsoft Learn. This should have Az CLI running, but you can check using az version. To get things going, bring up your cluster. PS C:\Users\ekele> Get-AksHciCluster Status : {ProvisioningState, Details} ProvisioningState : Deployed KubernetesVersion : v1.23.8 PackageVersion : v1.23.8 NodePools : linuxpool WindowsNodeCount : 0 LinuxNodeCount : 3 ControlPlaneNodeCount : 3 ControlPlaneVmSize : Standard_A2_v2 AutoScalerEnabled : False AutoScalerProfile : LoadBalancer : {VMSize, Count, Sku} Name : <ClusterName> The next step is to enable OSM kubernetes extension on the AKS hybrid cluster after connecting the cluster to Azure Arc. Note: In order to run some bash commands for validation purposes, the rest of the cmdlets used in this article were run in Git bash terminal on Visual Studio Code with Az cli installed. Also, ensure to download the OSM cli to be able to run osm commands. To download the latest OSM cli, see Releases · openservicemesh/osm (github.com) ea@SA18n30-3 MINGW64 ~ (master) $ az k8s-extension create --cluster-name <ClusterName> --resource-group <ResourceGroup> --cluster-type connectedClusters --extension-type Microsoft.openservicemesh --scope cluster --name osm { "aksAssignedIdentity": null, "autoUpgradeMinorVersion": true, "configurationProtectedSettings": {}, "configurationSettings": {}, "customLocationSettings": null, "errorInfo": null, "extensionType": "microsoft.openservicemesh", "id": "/subscriptions/5807bea4-cd17-4b81-b4d8-d4e94caab82d/resourceGroups/<ResourceGroup>/providers/Microsoft.Kubernetes/connectedClusters/<ClusterName>/providers/Microsoft.KubernetesConfiguration/extensions/osm", "identity": { "principalId": "0c8ed1d6-358f-4f6a-8342-61d10e1a9571", "tenantId": null, "type": "SystemAssigned" }, "name": "osm", "packageUri": null, "provisioningState": "Succeeded", "releaseTrain": "Stable", "resourceGroup": "<ResourceGroup>", "scope": { "cluster": { "releaseNamespace": "arc-osm-system" }, "type": "Microsoft.KubernetesConfiguration/extensions", "version": "1.1.1-1" } Verify that the OSM k8s extension was installed correctly by running ea@SA18n30-3 MINGW64 ~ (master) $ az k8s-extension show --cluster-type connectedClusters --cluster-name <ClusterName> --resource-group <ResourceGroup> --name osm Get the credentials of your cluster to be sure you can run kubectl using ea@SA18n30-3 MINGW64 ~ (master) $ kubectl config current-context <ClusterName>-admin@<ClusterName> You can further verify that the OSM components are running on your cluster by checking the deployment, pods, and services in arc-osm-system namespace. ea@SA18n30-3 MINGW64 ~ (master) $ kubectl get deployment -n arc-osm-system NAME READY UP-TO-DATE AVAILABLE AGE osm-bootstrap 1/1 1 1 86m osm-controller 1/1 1 1 86m osm-injector 1/1 1 1 86m osm-metrics-agent 1/1 1 1 86m ea@SA18n30-3 MINGW64 ~ (master) $ kubectl get pods -n arc-osm-system NAME READY STATUS RESTARTS AGE osm-bootstrap-58b8986b87-wfp6g 1/1 Running 0 88m osm-controller-768df46759-n29ps 1/1 Running 0 88m osm-injector-6ddd574779-wl52s 1/1 Running 0 88m osm-metrics-agent-78c846d57b-v9vtd 4/4 Running 1 (87m ago) 88m ea@SA18n30-3 MINGW64 ~ (master) $ kubectl get services -n arc-osm-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE osm-bootstrap ClusterIP 10.99.80.35 <none> 9443/TCP,9095/TCP 88m osm-controller ClusterIP 10.111.193.40 <none> 15128/TCP,9092/TCP,9091/TCP 88m osm-injector ClusterIP 10.100.99.169 <none> 9090/TCP 88m osm-validator ClusterIP 10.108.48.217 <none> 9093/TCP 88m OSM controller configuration OSM deploys a MeshConfig resource osm-mesh-config as a part of its control plane in arc-osm-system namespace. The MeshConfig provides the mesh owner or operator the ability to update some of the mesh configurations based on need. The default values of the MeshConfig can be viewed using the following command. $ kubectl describe meshconfig osm-mesh-config -n arc-osm-system Name: osm-mesh-config Namespace: arc-osm-system Labels: <none> Annotations: <none> API Version: config.openservicemesh.io/v1alpha2 Kind: MeshConfig Metadata: Creation Timestamp: 2022-10-17T22:56:58Z Generation: 1 Managed Fields: API Version: config.openservicemesh.io/v1alpha2 Fields Type: FieldsV1 fieldsV1: f:metadata: f:annotations: { … Traffic: Enable Egress: false Enable Permissive Traffic Policy Mode: true … } It can be observed that the permissive traffic policy mode of the output is set at true. With permissive traffic policy mode enabled in your OSM mesh: The SMI traffic policy enforcement is bypassed. OSM automatically discovers services that are a part of the service mesh. OSM programs traffic policy rules on each Envoy proxy sidecar to be able to communicate with these services. It is important to note that values in the MeshConfig osm-mesh-config are persisted across upgrades. Changes to osm-mesh-config can be made using the kubectl patch command. In a subsequent step for this sample deployment, the permissive traffic policy mode was changed to false through this command. Deploy Bookstore Applications After validating the checks, the sample applications manifest (Bookbuyer, Bookstore, Bookwarehouse) is deployed that will generate the services on which OSM will be applied to. Kubectl create -f https://raw.githubusercontent.com/openservicemesh/osm/release-v0.8/docs/example/manifests/apps/bookbuyer.yaml Kubectl create -f https://raw.githubusercontent.com/openservicemesh/osm/release-v0.8/docs/example/manifests/apps/bookstore.yaml Kubectl create -f https://raw.githubusercontent.com/openservicemesh/osm/release-v0.8/docs/example/manifests/apps/bookwarehouse.yaml Validate Application by port-forwarding the Kubernetes service The components of the bookstore namespace can be checked to see the pods and services running using ‘kubectl get all -n bookstore’. Afterwards, the logs of the bookbuyer pod could be traced to ensure it is communicating with the bookstore service. To query that bookbuyer is reaching bookstore service, run the following commands to trail the bookbuyer logs. POD="$(kubectl get pods -n bookbuyer --show-labels --selector app=bookbuyer --no-headers | grep -v 'Terminating' | awk '{print $1}' | head -n1)" Kubectl logs “${POD}” -n bookbuyer -c bookbuyer --tail=100 -f { … Fetching http://bookstore.bookstore:14001/books-bought Request Headers: map[Client-App:[bookbuyer] User-Agent:[Go-http-client/1.1]] Identity: bookstore-v1 Booksbought: 5258 Server: n/a Date: Tue, 18 Oct 2022 04:42:48 GMT Status: 200 OK MAESTRO! THIS TEST SUCCEEDED! Fetching http://bookstore.bookstore:14001/buy-a-book/new Request Headers: map[] Identity: bookstore-v1 Booksbought: 5259 Server: n/a Date: Tue, 18 Oct 2022 04:42:49 GMT Status: 200 OK MAESTRO! THIS TEST SUCCEEDED! … } The status should show that everything is okay and that it is able to fetch http bookstore-v1 data. Onboard Bookstore Apps namespaces for OSM In order to start using OSM capabilities, the application namespaces need to be onboarded to the service mesh so that OSM can manage these namespaces. Run the command $ osm namespace add bookstore bookbuyer bookwarehouse Namespace [bookstore] successfully added to mesh [osm] Namespace [bookbuyer] successfully added to mesh [osm] Namespace [bookwarehouse] successfully added to mesh [osm] Enable proxy sidecar injection for Bookstore Apps The sidecar containers can be enabled using the ‘kubectl rollout restart’ command. You can check the pod details before and after to know that the sidecar proxies were correctly deployed. $ kubectl get pods -n bookbuyer NAME READY STATUS RESTARTS AGE bookbuyer-56d6bcc7f8-gvzn8 1/1 Running 0 86m ea@SA18n30-3 MINGW64 ~ (master) $ kubectl rollout restart deployment bookbuyer -n bookbuyer deployment.apps/bookbuyer restarted ea@SA18n30-3 MINGW64 ~ (master) $ kubectl rollout restart deployment bookstore -n bookstore deployment.apps/bookstore restarted ea@SA18n30-3 MINGW64 ~ (master) $ kubectl rollout restart deployment bookwarehouse -n bookwarehouse deployment.apps/bookwarehouse restarted By checking the pod details of the bookbuyer after restart, the ‘Ready’ state shows that there are 2 out of 2 pods running. $ kubectl get pods -n bookbuyer NAME READY STATUS RESTARTS AGE bookbuyer-6ccd656dbf-7c28x 2/2 Running 0 115s To get further information, the ‘kubectl describe pod’ command will show an envoy running alongside the bookbuyer container. POD="$(kubectl get pods -n bookbuyer --show-labels --selector app=bookbuyer --no-headers | grep -v 'Terminating' | awk '{print $1}' | head -n1)" Kubectl describe pod $POD -n bookbuyer Normal Started 4m29s kubelet Started container bookbuyer Normal Pulling 4m29s kubelet Pulling image "mcr.microsoft.com/oss/envoyproxy/envoy:v1.19.3" Normal Pulled 4m26s kubelet Successfully pulled image "mcr.microsoft.com/oss/envoyproxy/envoy:v1.19.3" in 3.413382681s Normal Created 4m26s kubelet Created container envoy Normal Started 4m26s kubelet Started container envoy Verify Bookstore App functioning with sidecar injection Kubectl logs "${POD}" -n bookbuyer -c bookbuyer --tail=100 -f … Fetching http://bookstore.bookstore:14001/books-bought Request Headers: map[Client-App:[bookbuyer] User-Agent:[Go-http-client/1.1]] Identity: bookstore-v1 Booksbought: 415 Server: envoy Date: Tue, 18 Oct 2022 04:51:14 GMT Status: 200 OK MAESTRO! THIS TEST SUCCEEDED! Fetching http://bookstore.bookstore:14001/buy-a-book/new Request Headers: map[] Identity: bookstore-v1 Booksbought: 416 Server: envoy Date: Tue, 18 Oct 2022 04:51:15 GMT Status: 200 OK MAESTRO! THIS TEST SUCCEEDED! … Disable OSM Permissive Mode If the permissive traffic policy mode is disabled, communication between the bookbuyer and bookstore will cease. This can be done using the following command $ kubectl patch meshconfig osm-mesh-config -n arc-osm-system -p '{"spec":{"traffic":{"enablePermissiveTrafficPolicyMode":false}}}' --type=merge meshconfig.config.openservicemesh.io/osm-mesh-config patched Verify that the bookbuyer can no longer reach the bookstore Kubectl logs "${POD}" -n bookbuyer -c bookbuyer --tail=100 -f { … Fetching http://bookstore.bookstore:14001/books-bought Request Headers: map[Client-App:[bookbuyer] User-Agent:[Go-http-client/1.1]] Error fetching http://bookstore.bookstore:14001/books-bought: Get "http://bookstore.bookstore:14001/books-bought": dial tcp 10.99.49.182:14001: connect: connection refused ERROR: response code for "http://bookstore.bookstore:14001/books-bought" is 0; expected 200 Fetching http://bookstore.bookstore:14001/buy-a-book/new Request Headers: map[] Error fetching http://bookstore.bookstore:14001/buy-a-book/new: Get "http://bookstore.bookstore:14001/buy-a-book/new": dial tcp 10.99.49.182:14001: connect: connection refused ERROR: response code for "http://bookstore.bookstore:14001/buy-a-book/new" is 0; expected 200 … } Deploy SMI Traffic Access Policies To restore traffic access between the bookbuyer and bookstore, run the SMI traffic policy that will enable communication between bookbuyer and bookstore. $ Kubectl apply -f 01-deploy-smi-access-policy.yaml traffictarget.access.smi-spec.io/bookbuyer-access-bookstore created httproutegroup.specs.smi-spec.io/bookstore-service-routes created traffictarget.access.smi-spec.io/bookstore-access-bookwarehouse created httproutegroup.specs.smi-spec.io/bookwarehouse-service-routes created If the bookbuyer logs are checked again, traffic between bookbuyer and bookstore are restored. $ Kubectl logs "${POD}" -n bookbuyer -c bookbuyer --tail=100 -f { … Fetching http://bookstore.bookstore:14001/books-bought Request Headers: map[Client-App:[bookbuyer] User-Agent:[Go-http-client/1.1]] Identity: bookstore-v1 Booksbought: 552 Server: envoy Date: Tue, 18 Oct 2022 04:56:07 GMT Status: 200 OK MAESTRO! THIS TEST SUCCEEDED! Fetching http://bookstore.bookstore:14001/buy-a-book/new Request Headers: map[] Identity: bookstore-v1 Booksbought: 553 Server: envoy Date: Tue, 18 Oct 2022 04:56:07 GMT Status: 200 OK MAESTRO! THIS TEST SUCCEEDED! …} Deploy bookstore v2 service To display the traffic split functionality of OSM, an additional bookstore v2 service was deployed to allow the bookbuyer reach either bookstore-v1 or bookstore-v2. The deployed bookstore-v2 service would have an SMI traffic policy created as well. $ Kubectl apply -f 02-deploy-bookstore-v2.yaml service/bookstore-v2 created serviceaccount/bookstore-v2 created deployment.apps/bookstore-v2 created traffictarget.access.smi-spec.io/bookbuyer-access-bookstore-v2 created Implement a SMI Traffic Split The SMI traffic split is applied to enable the bookbuyer to communicate with the bookstore and the bookstore-v2 service at weighted measures. Here, the weight was shared at 25% for bookstore and 75% for bookstore-v2 service. To see the content of the trafficsplit manifest run $ cat 03-deploy-smi-trafficsplit.yaml apiVersion: split.smi-spec.io/v1alpha2 kind: TrafficSplit metadata: name: bookstore-split namespace: bookstore spec: service: bookstore.bookstore backends: - service: bookstore weight: 25 - service: bookstore-v2 weight: 75 Apply the manifest by running $ Kubectl apply -f 03-deploy-smi-trafficsplit.yaml trafficsplit.split.smi-spec.io/bookstore-split created Trail the identity of the bookbuyer logs and see that traffic is split with 75% going to bookstore-v2 and 25% going to bookstore-v1. i.e. $ Kubectl logs "${POD}" -n bookbuyer -c bookbuyer --tail=100 -f | grep 'Identity:' Identity: bookstore-v2 Identity: bookstore-v2 Identity: bookstore-v2 Identity: bookstore-v2 Identity: bookstore-v1 Identity: bookstore-v1 Identity: bookstore-v2 Identity: bookstore-v2 Identity: bookstore-v1 Identity: bookstore-v2 Identity: bookstore-v2 Identity: bookstore-v2 To Uninstall OSM from your AKS hybrid cluster az k8s-extension delete --cluster-type connectedClusters --cluster-name $CLUSTER_NAME --resource-group $RESOURCE_GROUP --name osm Summary In this article, we see the capabilities of OSM been applied to a sample bookstore application and its usefulness in securing your Kubernetes cluster in a variety of ways like Ingress traffic management via policies to permit/deny external access into the mesh, Sidecar proxy injection using the envoy network proxy to ensure services participate in the mesh and obey policies that have been defined, Service-to-service access control via Layer 7 (http) access policies to allow authorized clients and disallow unauthorized clients, and Traffic splitting for canary and blue-green deployments. In a subsequent article, the observability benefits would be demonstrated to provide metrics, tracing, and logs. This would also enable visualizing application traffic flows, errors, latency and other metrics in tools like Grafana and Jaeger. Further reading Azure Arc-enabled Open Service Mesh - Azure Arc | Microsoft Learn Continue reading... Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.