Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: install istio service mesh #9

Merged
merged 2 commits into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,87 @@ Based on the `KUBECONFIG` value, the helm chart will be installed on that partic

> Due to an on-going issue with Terraform Helm Provider [[reference](https://github.com/hashicorp/terraform-provider-helm/issues/932)] which prevents the Terraform resource to pull a chart from a private GitHub repository (even after providing a GitHub PAT), we are forced to install the Helm chart locally.

## Kubernetes Provider

We make use of the [`Terraform Kubernetes Provider`](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/namespace) to help setup the namespaces with appropriate labels. We will use these labels to install/inject [`Istio Service Mesh`](https://istio.io/v1.16/docs/setup/install/helm/) `Envoy proxy` sidecar pods to inject the ingress/egress Istio gateway.

To setup namespaces on a cluster using the Kubernetes provider, we need to configure the `config_path` for the cluster configuration, which will tell terraform to create and configure the namespaces on that cluster.

```tf
provider "kubernetes" {
config_path = "~/.kube/config"
}
```

## [Istio Service Mesh](https://istio.io/latest/docs/setup/getting-started/)

Istio is an open-source service mesh platform designed to connect, secure, and manage microservices-based applications. A service mesh is a dedicated infrastructure layer that facilitates communication between microservices in a decentralized and resilient manner. Istio provides a set of powerful features and capabilities to address common challenges associated with microservices architectures.

Istio is suitable for organizations adopting microservices architectures where the number of services and their interactions can become complex. It provides a centralized and consistent way to manage and secure these interactions, improving the overall reliability and observability of microservices-based applications.

Here are key aspects and advantages of Istio:

- **`Traffic Management`**:
- Load Balancing: Istio can evenly distribute incoming traffic across multiple instances of a service to ensure optimal resource utilization and high availability.
- Canary Releases: Istio allows you to perform controlled rollouts by gradually shifting traffic from one version of a service to another (canary releases), minimizing the risk of introducing bugs or performance issues.

- **`Security`**:
- **Authentication and Authorization**: Istio enforces authentication and authorization policies for communication between services, ensuring that only authorized services can interact with each other.
- **Encryption**: Istio supports automatic mutual TLS (mTLS) encryption between services, adding an extra layer of security to communication.

- **`Observability`**:
- **Monitoring**: Istio provides detailed monitoring and logging capabilities, allowing you to observe the behavior of your microservices and diagnose issues.
- **Tracing**: Istio supports distributed tracing, helping you understand the flow of requests through your microservices architecture and identify performance bottlenecks.

- **`Resilience`**:
- **Circuit Breaking**: Istio can automatically detect when a service is failing and prevent further requests from being sent to it, allowing the system to gracefully degrade instead of cascading failures.
- **Timeouts and Retries**: Istio enables you to configure timeouts and retries for service-to-service communication, improving the resilience of your applications.

- **`Policy Enforcement`**:
- **Rate Limiting**: Istio allows you to enforce rate limits on incoming requests to prevent abuse or ensure fair resource utilization.
- **Access Control Lists (ACLs)**: Istio lets you define fine-grained access control policies for services, restricting communication based on various criteria.

- **`Service Mesh Federation`**:
- **Multi-Cluster Support**: Istio can be used to create a service mesh that spans multiple Kubernetes clusters, enabling communication and management across diverse environments.

- **`Easier Development and Operations`**:
- **Automatic Sidecar Injection**: Istio deploys a sidecar proxy alongside each microservice, which handles communication and offloads concerns such as security and monitoring. This simplifies the development and operation of individual services.

### Working with Istio

- The istio helm charts are installed automatically and in their own namespaces. To install these charts manually without terraform, but using helm, [refer the official documentation](https://istio.io/v1.16/docs/setup/install/helm/).

- There are 3 main Istio [charts](https://istio-release.storage.googleapis.com/charts) that we require for Istio service mesh to be fully functional:
- `istio/base`: The Istio base chart which contains cluster-wide resources used by the Istio control plane
- `istio/istiod`: The Istio discovery chart which deploys the `istiod` service
- `istio/gateway`: (Optional) Install an ingress gateway

- To inject Envoy proxy sidecar pods to all pods in a namespace, simply add the label `istio-injection=enabled` to the namespace:

```bash
kubectl label namespace <namespace-name>istio-injection=enabled
```

- To exclude a namespace from Envoy proxy sidecar pods, use the label `istio-injection=disabled`

```bash
kubectl label namespace <namespace-name>istio-injection=disabled
```

- (Optional) Install `istioctl`:

> NOTE: We will use this tool to analyze namespaces and to verify if the pods have been injected with Istio sidecar pods

```bash
brew install istioctl
# Prints out build version information
istioctl version
# Analyze Istio configuration and print validation messages
istioctl analyze
```

> **NOTE**: Add the `sidecar.istio.io/inject: "false"` annotation to the metadata section of the pod template. This will prevent the Istio sidecar from being injected into that specific pod.

## Configuring the chart values

For specific `values.yaml`, refer their specific charts and create their respective `values.yaml` files based on the dummy `values.yaml` file.
17 changes: 17 additions & 0 deletions modules/istio_base/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
resource "helm_release" "istio_base_chart" {
name = "istio-base"
namespace = "istio-system"
create_namespace = true
repository = "https://istio-release.storage.googleapis.com/charts"
chart = "base"
timeout = var.timeout
cleanup_on_fail = true
force_update = false
wait = false
# When performing a revisioned installation, the base chart requires the
# `--defaultRevision` value to be set for resource validation to function.
set {
name = "defaultRevision"
value = "default"
}
}
Empty file added modules/istio_base/output.tf
Empty file.
1 change: 1 addition & 0 deletions modules/istio_base/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
variable "timeout" {}
11 changes: 11 additions & 0 deletions modules/istio_gateway/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
resource "helm_release" "istio_gateway_chart" {
name = "istio-ingress"
namespace = "istio-ingress"
create_namespace = true
repository = "https://istio-release.storage.googleapis.com/charts"
chart = "gateway"
timeout = var.timeout
cleanup_on_fail = true
force_update = false
wait = false
}
Empty file added modules/istio_gateway/output.tf
Empty file.
1 change: 1 addition & 0 deletions modules/istio_gateway/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
variable "timeout" {}
11 changes: 11 additions & 0 deletions modules/istiod/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
resource "helm_release" "istiod_chart" {
name = "istiod"
namespace = "istio-system"
create_namespace = true
repository = "https://istio-release.storage.googleapis.com/charts"
chart = "istiod"
timeout = var.timeout
cleanup_on_fail = true
force_update = false
wait = true
}
Empty file added modules/istiod/output.tf
Empty file.
1 change: 1 addition & 0 deletions modules/istiod/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
variable "timeout" {}
33 changes: 33 additions & 0 deletions modules/namespace/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
resource "kubernetes_namespace" "webapp_proxy_setup" {
metadata {
labels = {
istio-injection = "enabled"
}
name = "webapp"
}
}

resource "kubernetes_namespace" "deps_proxy_setup" {
metadata {
labels = {
istio-injection = "enabled"
}
name = "deps"
}
}

resource "kubernetes_namespace" "istio_system" {
metadata {
name = "istio-system"
}
}

# The namespace the gateway is deployed in must not have a `istio-injection=disabled` label
resource "kubernetes_namespace" "istio_ingress" {
metadata {
labels = {
istio-injection = "enabled"
}
name = "istio-ingress"
}
}
11 changes: 6 additions & 5 deletions root/example.tfvars
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
namespace = "webapp"
timeout = 600
values_file = "./values.yaml"
chart_path = "../modules/infra_helm/charts"
release_name = "infra-helm-release"
timeout = 600
infra_values_file = "./infra_values.yaml"
webapp_values_file = "./webapp_values.yaml"
chart_path = "../modules/charts"
webapp_chart = "webapp-helm-chart-1.1.3.tar.gz"
infra_chart = "infra-helm-chart-1.4.0.tar.gz"
39 changes: 39 additions & 0 deletions root/main.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,43 @@
module "webapp_namespace" {
source = "../modules/namespace"
}

module "istio_base" {
depends_on = [module.webapp_namespace]
source = "../modules/istio_base"
timeout = var.timeout
}

resource "time_sleep" "istall_istio_crds" {
depends_on = [module.istio_base]
create_duration = "20s"
}

module "istio_discovery" {
depends_on = [time_sleep.istall_istio_crds]
source = "../modules/istiod"
timeout = var.timeout
}

resource "time_sleep" "istall_istio_discovery" {
depends_on = [module.istio_discovery]
create_duration = "20s"
}

module "istio_gateway" {
depends_on = [time_sleep.istall_istio_discovery]
source = "../modules/istio_gateway"
timeout = var.timeout
}


resource "time_sleep" "istall_istio_gateway" {
depends_on = [module.istio_gateway]
create_duration = "20s"
}

module "infra_dependencies" {
depends_on = [time_sleep.istall_istio_gateway]
source = "../modules/infra_helm"
timeout = var.timeout
infra_values_file = var.infra_values_file
Expand Down
10 changes: 10 additions & 0 deletions root/provider.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ terraform {
source = "hashicorp/helm"
version = "2.11.0"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = "2.24.0"
}
}
}

Expand All @@ -12,3 +16,9 @@ provider "helm" {
config_path = "~/.kube/config"
}
}


provider "kubernetes" {
config_path = "~/.kube/config"
}