AWS App Mesh is a service mesh that provides application-level networking to make it easy for your services to communicate with each other across multiple types of compute infrastructure. Additionally, It gives end-to-end visibility and high-availability for your applications. Further, it uses Envoy an open source proxy, making it compatible with a wide range of AWS partner and open source tools for connecting and monitoring micro-services.
Components of App Mesh
Service mesh – A service mesh is a logical boundary for network traffic between the services that reside within it.
Virtual services – A virtual service is an abstraction of a real service that is provided by a virtual node directly or indirectly by means of a virtual router.
Virtual nodes – A virtual node acts as a logical pointer to a particular task group, such as an ECS service or a Kubernetes deployment. When you create a virtual node, you must specify the service discovery name for your task group.
Envoy proxy – The Envoy proxy configures your micro-service task group to use the App Mesh service mesh traffic rules that you set up for your virtual routers and virtual nodes. As well as you need to add the Envoy container to your task group after you have created your virtual nodes, virtual routers, routes, and virtual services.
Virtual routers – The virtual router handles traffic for one or more virtual services within your mesh.
Routes – A route is associated with a virtual router in order to direct traffic that matches a service name prefix to one or more virtual nodes.
- AWS account
- EKS cluster
- AWS CLI
- ECR Registry
- Helm version 3.0 or later installed.
Lets start with the Setup
1. To connect with AWS account
aws configure (Provide Access Key, Secret Access Key and Region)
2. Firstly, create an EKS Cluster if you don’t have any existing one.
eksctl create cluster --name mesh-test-cluster --version 1.21 --region ap- south-1 --zones ap-south-1a,ap-south-1b --nodegroup-name cls-nodes --node- type t2.micro --nodes 2
3. Further to connect with EKS cluster update the Kubeconfig.
aws eks --region ap-south-1 update-kubeconfig --name mesh-test-cluster
4. Add the eks-charts repository to Helm.
helm repo add eks https://aws.github.io/eks-charts
5. Install the App Mesh Kubernetes custom resource definitions (CRD).
kubectl apply -k "https://github.com/aws/eks-charts/stable/appmesh-controller /crds?ref=master"
6. Create appmesh-system Namespace.
kubectl create ns appmesh-system
7. Create an OpenID Connect (OIDC) identity provider for your cluster.
eksctl utils associate-iam-oidc-provider --region=ap-south-1 --cluster mesh- test-cluster --approve
eksctl create iamserviceaccount \ --cluster mesh-test-cluster \ --namespace appmesh-system \ --name appmesh-controller \ --attach-policy-arn arn:aws:iam::aws:policy/AWSCloudMapFullAccess,arn:aws:iam::aws:policy/AWSAppMeshFullAccess \ --override-existing-serviceaccounts \ --approve
9. Deploy the App Mesh controller.
helm upgrade -i appmesh-controller eks/appmesh-controller \ --namespace appmesh-system \ --set region=ap-south-1 \ --set serviceAccount.create=false \ --set serviceAccount.name=appmesh-controller
10. Finally, verify if Controller pod is running.
As we are done with the app-mesh-contoller setup, we can move ahead with Mesh Creation.
We can create mesh from Aws-cli, AWS Console and Kubernetes native yaml. However, for now i will create using yaml.
Lets create a file mesh.yaml with below contents.
apiVersion: appmesh.k8s.aws/v1beta2 kind: Mesh metadata: name: knol-mesh spec: namespaceSelector: matchLabels: mesh: knol-mesh
11. Create the mesh and verify.
12. As mesh has been created now, we can enable/disable sidecar injection by adding a label as below to the namespace.
Create a file namespace.yaml adding the contents below.
apiVersion: v1 kind: Namespace metadata: name: mesh-workload labels: appmesh.k8s.aws/sidecarInjectorWebhook: enabled
Note: Once you enable the Injection you need to have mesh components in place else existing pods, if terminated will not come up waiting for the mesh resources.
13. Furthermore, remaining mesh resources can also be created from Aws-cli, AWS Console and Kubernetes native yaml. For now we will use yaml to create the same.
Create virtual-node.yaml with below contents and apply.
apiVersion: appmesh.k8s.aws/v1beta2 kind: VirtualNode metadata: name: knol-service namespace: mesh-workload spec: awsName: knol-service-virtual-node podSelector: matchLabels: app: knol-service listeners: - portMapping: port: 80 protocol: http serviceDiscovery: dns: hostname: knol-service.mesh-workload.svc.cluster.local
Virtual Router and Route
Create virtual-route.yaml with below contents and apply.
apiVersion: appmesh.k8s.aws/v1beta2 kind: VirtualRouter metadata: namespace: mesh-workload name: knol-service spec: awsName: knol-service-virtual-router listeners: - portMapping: port: 80 protocol: http routes: - name: route httpRoute: match: prefix: / action: weightedTargets: - virtualNodeRef: name: knol-service weight: 1
Create virtual-service.yaml with below contents and apply.
apiVersion: appmesh.k8s.aws/v1beta2 kind: VirtualService metadata: name: knol-service namespace: mesh-workload spec: awsName: knol-service-virtual-service provider: virtualRouter: virtualRouterRef: name: knol-service
14. Once all the resources have been created we can create the Service and deployment.
Create a Service account.
Create serviceaccount.yaml with below contents and apply.
apiVersion: v1 kind: ServiceAccount metadata: name: knol-service namespace: mesh-workload annotations: eks.amazonaws.com/role-arn: arn:aws:iam::Account_ID:role/appmesh_role
Note: Update the role-arn with the role created above attaching AWSAppMeshFullAccess and AWSCloudMapFullAccess policies to it.
Create deployment.yaml file with below contents and apply.
apiVersion: v1 kind: Service metadata: name: knol-service namespace: mesh-workload labels: app: knol-service spec: selector: app: knol-service ports: - protocol: TCP port: 80 targetPort: 80 --- apiVersion: apps/v1 kind: Deployment metadata: name: knol-service namespace: mesh-workload labels: app: knol-service spec: replicas: 1 selector: matchLabels: app: knol-service template: metadata: labels: app: knol-service spec: serviceAccountName: knol-service containers: - name: nginx image: nginx:1.19.0 ports: - containerPort: 80
Post successful implementation of above steps we could see pod has come up with one sidecar container which will be responsible for establishing communication between the services.
Eventually, As a result all services in the cluster can communicate with each other by calling the corresponding service names.
Note: App Mesh does not allow any traffic to go outside the Mesh by default. If your application is designed to connect other resources outside the mesh you might need to enable egress traffic for the Mesh.
So in this blog we learnt about how to setup AWS App Mesh with EKS cluster.
I hope this blog will help you to setup Service Mesh. If you like this blog please do share and comment.