Using Istio, a Service Mesh, with Amazon Elastic Kubernetes Service (EKS) - Part 2
Tags: aws, eks, servicemesh, istio
Published: 2023-11-10 21:47:57

This is the second part of the series on Using Istio, a Service Mesh, with Amazon Elastic Kubernetes Service (EKS). The first article discussed what a Service Mesh and Istio are, what technologies we will use, the prerequisites and architecture overview, and the configuration and setup process.

In this part two article, we will be working on these tasks.

- Configure access to Amazon EKS Cluster
- Install Istio CLI tool - istioctl
- Run the "configure.sh" script to configure the Flux Repository
- Install Flux to the Amazon EKS Cluster
- Review Addons and Applications managed by Flux
- Discuss the Istio Components and Addons used by Istio.
- Review how Istio works with Applications and Microservices

You can access the code in my [GitHub Repository](https://github.com/junglekid/aws-eks-istio-lab).

![Istio and AWS EKS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kefv69nsassdos8t8q57.png)

## Configure access to Amazon EKS Cluster

Amazon EKS Cluster details can be extracted from terraform output or by accessing the AWS Console to get the name of the cluster. This following command can be used to update the kubeconfig in your local machine where you run kubectl commands to interact with your EKS Cluster. Navigate to the root of the directory of the GitHub repo and run the following commands:

```bash
cd terraform

AWS_REGION=$(terraform output -raw aws_region)
EKS_CLUSTER_NAME=$(terraform output -raw eks_cluster_name)
aws eks --region $AWS_REGION update-kubeconfig --name $EKS_CLUSTER_NAME
```

Results of configuring kubeconfig.

![Kubeconfig](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bz9pdiraas3oq86erz77.png)

## Install Istio CLI - istioctl

1. Install Istioctl CLI

    a. For macOS or Linux, follow these instructions using [Homebrew](https://brew.sh/)

    ```bash
    brew install istioctl
    ```

    b. For Windows, follow these instructions with [Chocolatey](https://chocolatey.org/install).

    ```powershell
    choco install istioctl
    ```

    c. For Windows, follow these instructions with [Scoop](https://scoop.sh/).

    ```powershell
    scoop bucket add main
    scoop install main/istioctl
    ```

    d. Install instructions for other methods can be found [here](https://istio.io/latest/docs/setup/getting-started/).

2. Instructions on how to use **istioctl** can be found [here](https://istio.io/latest/docs/reference/commands/istioctl) and [here](https://istio.io/latest/docs/ops/diagnostic-tools/istioctl).

3. Verify that **istioctl** is installed by running the following command.

    ```bash
    istioctl version
    ```

4. Results of running **istioctl**.

    ![istioctl](./images/istioctl.png)

## Configure and Install Flux

1. Configure Variables needed to install Flux

    ```bash
    export GITHUB_TOKEN='<REPLACE_WITH_GITHHUB_TOKEN>'
    export GITHUB_USER='<REPLACE_WITH_GITHUB_USER>'
    export GITHUB_OWNER='<REPLACE_WITH_GITHUB_OWNER>'
    export GITHUB_REPO_NAME='<REPLACE_WITH_GITHUB_REPO_NAME>'
    ```

2. Configure the Flux Repository by running the "configure.sh" script. The "configure.sh" script updates the various applications with the necessary values to run correctly. Navigate to the root of the directory of the GitHub repo and run the following commands:

    ```bash
    cd scripts

    ./configure.sh
    cd ..
    ```

3. Results of running the "configure.sh" script.

    ![Configure Flux](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xqooytg49exqr48ynr2a.png)

4. Install Flux on the Amazon EKS Cluster

    ```bash
    flux bootstrap github \
      --components-extra=image-reflector-controller,image-automation-controller \
      --owner=$GITHUB_OWNER \
      --repository=$GITHUB_REPO_NAME \
      --private=false \
      --path=clusters/eks-istio-lab \
      --personal
    ```

5. Results of installing Flux on the Amazon EKS Cluster.

    ![Install Flux](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d24em12x3t5n3phk10qw.png)

6. Wait 2 to 5 minutes for Flux to reconcile the Git repository we specified, During this time, Flux will install and configure all of the defined Kubernetes Addons and Applications.

7. Run the following command to check if all of the Kubernetes Addons and Applications deployed successfully

    ```bash
    flux get all -A
    ```

## Managing Flux

Managing Flux is handled by using the Flux CLI. Flux does not come with any Web or UI interface to manage Flux. Please click [here](https://fluxcd.io/flux/cmd/) if you would like more information on the Flux CLI.

The following are some commands you can use to manage Flux.

```bash
flux get all
flux get sources all|git|helm|chart
flux get helmreleases
flux get kustomizations
flux logs
flux suspend kustomization <kustomization_name>
flux reconcile source git flux-system
```

For additional information on using Flux, please look at the following series I wrote about Flux.

- [Using Flux, a GitOps Tool, with Amazon Elastic Kubernetes Service (EKS) - Part 1](https://www.linkedin.com/pulse/using-flux-gitops-tool-amazon-elastic-kubernetes-service-rasmuson)
- [Using Flux, a GitOps Tool, with Amazon Elastic Kubernetes Service (EKS) - Part 2](https://www.linkedin.com/pulse/using-flux-gitops-tool-amazon-elastic-kubernetes-service-rasmuson-1c)
- [Using Flux, a GitOps Tool, with Amazon Elastic Kubernetes Service (EKS) - Part 3](https://www.linkedin.com/pulse/using-flux-gitops-tool-amazon-elastic-kubernetes-service-rasmuson-1f)

## Kubernetes Addons managed by Flux

Below are the Applications that Flux manages, the Kubernetes Addons will be deployed and configured by Flux first. The following Kubernetes Addons will be installed.

- AWS Application Load Balancer Controller
- External DNS
- Cluster Autoscaler
- Cert manager
- Metrics Server

The AWS Application Load Balancer Controller and External DNS must be deployed first because the Applications need to be accessible by a load balancer and have the DNS Name registered with Route 53.

## Applications managed by Flux

Flux manages the following applications. These applications will be used to demonstrate the various Istio features.

- [Bookinfo](https://istio.io/latest/docs/examples/bookinfo/) - A sample application composed of four separate microservices
- [Podinfo](https://github.com/stefanprodan/podinfo) - A tiny web application made with Go

## Istio and Istio Addons managed by Flux

Istio is comprised of the following three components.

- [Istio](https://istio.io/) - An open-source service mesh that provides a uniform way to connect, manage, and secure microservices, enabling traffic flow control, policy enforcement, and telemetry data aggregation without altering service code.
- [Istiod](https://istio.io/latest/docs/ops/deployment/architecture/#istiod) - Consolidated control plane daemon of the Istio service mesh, responsible for service discovery, configuration management, certificate issuance, and providing overall operational control.
- [Istio Ingress Gateway](https://istio.io/latest/docs/setup/additional-setup/gateway/) - A dedicated network gateway in the Istio service mesh architecture that manages incoming traffic routing to various services within the mesh.

The following components are not necessary to run Istio but are addons to help the observability features of Istio.

- [Kiali](https://kiali.io/) - An open-source observability platform tailored for service mesh deployments, providing insights into the performance and structure of microservices networks within Istio. Kiali will retrieve data from Prometheus, Grafana, and Jaeger if installed and configured correctly.
- [Jaeger](https://www.jaegertracing.io/) - Distributed Tracing platform - An open-source, end-to-end distributed tracing system that helps monitor and troubleshoot transactions in complex, microservice-based architectures.
- [Kube Prometheus Stack](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack)
  - [Prometheus](https://prometheus.io/) - An open-source monitoring system with a dimensional data model, flexible query language, and powerful alerting functionality for storing and querying time-series data.
  - [Grafana](https://grafana.com/oss/) - An open-source analytics and monitoring platform designed for visualizing and exploring metrics from various databases and time-series data.
- [Grafana Loki](https://grafana.com/oss/loki/) - A horizontally scalable, multi-tenant log aggregation system inspired by Prometheus, designed for cost-effective storage and querying of logs at scale.

## Review how Istio works with Applications and Microservices

### Review Configuration of Kubernetes Namespaces work with Istio

By default, Istio doesn't inject sidecars/proxies into the pods. The easiest way to have Istio inject a sidecar/proxy to a pod is by adding a label to a Kubernetes namespace. When the label is added to an existing Kubernetes namespace, the existing pods must be deleted to add the sidecar/proxy container.

As part of the Bookinfo and Podinfo installation managed by Flux, the Kubernetes namespaces included the label to have Istio inject a sidecar/proxy. Let's review the Kubernetes namespaces that have the label "istio-injection=enabled".

In the Bookinfo namespace.yaml file. As you can see, when this namespace is created, the label "istio-injection=enabled" is added.

```yaml
apiVersion: v1
kind: Namespace
metadata:
  name: bookinfo
  labels:
    istio-injection: enabled
```

Let's review which Kubernetes namespaces have the label "istio-injection=enabled".

1. Run the following command to determine which Kubernetes namespaces have the label "istio-injection=enabled".

2. The result is four Kubernetes namespaces with the label "istio-injection=enabled".

    ![Istio Proxy Enabled Namespaces](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pu3mvkimjvs5oajabjx0.png)

3. Check Pods in the Bookinfo namespace as two containers running for each pod by running the following command.

4. As you can see, each pod is running two containers

    ![Istio Proxy Enabled Bookinfo Pods](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aovca3oy0zkl1spzetdt.png)

### Review Configuration of Istio Gateway and VirtualServices

Istio Gateway is a component of the Istio service mesh that manages incoming and outgoing traffic for microservices-based applications. It handles routing, load balancing, security, and TLS termination tasks. You define routing rules, authentication, and authorization policies, and it provides observability and high availability features to ensure efficient and secure communication within the service mesh.

Istio VirtualService is a Kubernetes custom resource definition (CRD) that defines how traffic is routed to services in a service mesh. It is a powerful tool that can be used to implement various traffic management policies, such as load balancing, fault injection, and rate limiting.

Here is the Istio Gateway that was created. This is an Istio Ingress Gateway.

```yaml
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: common-gateway
  namespace: istio-ingress
spec:
  selector:
    istio: ingressgateway
  servers:
    - port:
        number: 443
        name: https-443
        protocol: HTTPS
      tls:
        mode: SIMPLE
        credentialName: "wildcard-tls"
      hosts:
        - "*"
    - port:
        number: 80
        name: http-80
        protocol: HTTP
      tls:
        httpsRedirect: true
      hosts:
        - "*"
```

As part of the Istio Gateway, a TLS certificate is required. The TLS certificate can be created in several ways, but for the guide, Cert-Manager was used to create a wildcard certificate with Let's Encrypt.

When Istio Gateways are created, a Kubernetes Service is created. This Kubernetes Service can be defined and used in Kubernetes Ingresses.

Let's review the Bookinfo Kubernetes Ingress to see how this works.

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig":
      { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
    alb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:us-west-2:012345678910:certificate/3860d571-18bc-4c62-af82-92a5d1cc3aba"
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/ssl-redirect: "443"
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/healthcheck-path: /healthz/ready
    alb.ingress.kubernetes.io/healthcheck-port: status-port
    alb.ingress.kubernetes.io/healthcheck-protocol: HTTP
    alb.ingress.kubernetes.io/backend-protocol: HTTPS
    external-dns.alpha.kubernetes.io/hostname: "bookinfo.dallin.brewsentry.com"
  name: bookinfo-ingress
  namespace: istio-ingress
spec:
  ingressClassName: alb
  tls:
  - hosts:
    - bookinfo.dallin.brewsentry.com
    secretName: bookinfo-tls
  rules:
  - host: bookinfo.dallin.brewsentry.com
    http:
      paths:
      - backend:
          service:
            name: istio-ingressgateway
            port:
              number: 443
        path: /*
        pathType: ImplementationSpecific
```

The Bookinfo Kubernetes Ingress has a rule that listens for requests from a host and then routes the requests to the istio-ingressgateway Kubernetes Service.

Istio VirtualService is a Kubernetes custom resource definition (CRD) that defines how traffic is routed to services in a service mesh. It is a powerful tool that can be used to implement various traffic management policies, such as load balancing, fault injection, and rate limiting.

A VirtualService consists of a set of routing rules. Each routing rule defines a match condition and a destination. A request is routed to the destination if it matches the match condition.

Here is the VirtualService for Bookinfo.

```yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: bookinfo-vs
  namespace: bookinfo
spec:
  hosts:
  - "bookinfo.dallin.brewsentry.com"
  gateways:
  - istio-ingress/common-gateway
  http:
  - match:
    - uri:
        exact: /
    redirect:
      uri: /productpage
  - match:
    - uri:
        exact: /productpage
    - uri:
        prefix: /static
    - uri:
        exact: /login
    - uri:
        exact: /logout
    - uri:
        prefix: /api/v1/products
    route:
    - destination:
        host: productpage
        port:
          number: 9080
```

Let's review what Istio VirtualServices were created.

1. Run the following command to determine what Istio virtual services were created.

    ```bash
    kubectl get virtualservices.networking.istio.io -A
    ```

2. The result is that three Istio virtual services were created.

    ![Istio VirtualServices](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b03jx2srjc36usgt2qxd.png)

In this article, we configured access to Amazon EKS Cluster and installed the Istio CLI - istioctl tool. We ran the "configure.sh" script and installed Flux on the Amazon EKS Cluster. We reviewed the Addons and Applications managed by Flux and discussed the Istio Components and Addons used by Istio. Finally, we reviewed how Istio works with Applications and Microservices.

Please stay tuned for the third and final part of the series, where we will complete the following tasks.

- Access the Applications managed by Flux
- Demonstrate how Istio works
- Review the Istio Addons
- Clean up apps and infrastructure