How to Setup AWS App Mesh with EKS?

Reading Time: 5 minutes

Introduction

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.

Prerequisites

  • AWS account
  • EKS cluster
  • AWS CLI
  • Eksctl
  • Kubectl
  • 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

8. Create an IAM role, attach the AWSAppMeshFullAccess and AWSCloudMapFullAccess policies to it, and bind it to the appmesh-controller Kubernetes service account.

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.

Create Mesh

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.

Virtual-Node

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

Virtual Service

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.

Deploy Workload

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.

Conclusion

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.

Happy Learning!!

Written by 

Sunil is a technology enthusiast Devops Engineer with overall experience of 9 years. He possesses deep experience with CI/CD development, AWS and Google Cloud platforms, Kubernets,Docker and other Devops practices.