Skip to content

Commit

Permalink
created 77
Browse files Browse the repository at this point in the history
  • Loading branch information
Houssem Dellai committed Nov 3, 2023
1 parent dfaf967 commit f2dbda5
Show file tree
Hide file tree
Showing 21 changed files with 519 additions and 5 deletions.
Binary file modified .infracost/pricing.gob
Binary file not shown.
4 changes: 2 additions & 2 deletions 76_migrate_lb_to_natgateway/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ Check outbound egress traffic uses Load Balancer public IP
```bash
kubectl run nginx --image=nginx
sleep 10
kubectl exec nginx -it -- curl http://ifconfig.me
kubectl exec nginx -it -- curl http://ifconf.me
```

Note that is the public IP of the Load Balancer. This is the default behavior of AKS clusters.
Expand All @@ -89,7 +89,7 @@ Run this command in new powershell session for watch for the downtime of egress
```bash
for ($i = 0; $i -lt 30; $i++) {
date
kubectl exec nginx -it -- curl http://ifconfig.me
kubectl exec nginx -it -- curl http://ifconf.me
sleep 10 # 10 seconds
}
# Wednesday, October 18, 2023 6:07:33 PM
Expand Down
6 changes: 3 additions & 3 deletions 76_migrate_lb_to_natgateway/commands.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ az aks get-credentials -g $RG -n aks-cluster --overwrite-existing

kubectl run nginx --image=nginx
sleep 10
kubectl exec nginx -it -- curl http://ifconfig.me
kubectl exec nginx -it -- curl http://ifconf.me

# Note that is the public IP of the Load Balancer. This is the default behavior of AKS clusters.

Expand All @@ -43,7 +43,7 @@ az network nat gateway create -g $RG -n nat-gateway --public-ip-addresses pip-na

az network vnet subnet update -g $RG --vnet-name vnet-aks --name subnet-aks --nat-gateway nat-gateway

kubectl exec nginx -it -- curl http://ifconfig.me
kubectl exec nginx -it -- curl http://ifconf.me
# timeout

# Update cluster from loadbalancer to userAssignedNATGateway in BYO vnet scenario
Expand All @@ -53,7 +53,7 @@ az aks update -g $RG -n aks-cluster --outbound-type userAssignedNATGateway

for ($i = 0; $i -lt 30; $i++) {
date
kubectl exec nginx -it -- curl http://ifconfig.me
kubectl exec nginx -it -- curl http://ifconf.me
sleep 10
}

Expand Down
135 changes: 135 additions & 0 deletions 77_migrate_lb_to_natgateway_tf/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# Migrating OutboundType from Load Balancer to user NAT Gateway

## Introduction

You will learn in this lab how to migrate `outboundType` of an AKS cluster from `LoadBalancer` to `user NAT Gateway`.

Why you might do that ?

Mainly in case your apps are consuming multiple SNAT ports.
The NAT Gateway manages more efficiently SNAT ports than Load Balancer.
More details on the lab `65_aks_egress_lb_natgw_udr`.

There are four options for configuring outbound type in AKS:
1. Load Balancer (default mode)
2. Managed NAT Gateway
3. User NAT Gateway
4. UserDefinedRouting (UDR)

AKS supports migrating from one mode to another.

| BYO VNet | loadBalancer | managedNATGateway | userAssignedNATGateway | userDefinedRouting |
| ------------ | ------------ | ----------------- | ---------------------- | ------------------ |
| loadBalancer | N/A | Not Supported | Supported | Supported |
| managedNATGateway | Not Supported | N/A | Not Supported | Not Supported |
| userAssignedNATGateway | Supported | Not Supported | N/A | Supported |
| userDefinedRouting | Supported | Not Supported | Supported | N/A |

Check the following link for an updated information: https://learn.microsoft.com/en-us/azure/aks/egress-outboundtype#update-cluster-from-managednatgateway-to-userdefinedrouting

## Prerequisites

You need first to enable the migration feature.

```bash
az feature register --namespace "Microsoft.ContainerService" --name "AKS-OutBoundTypeMigrationPreview"
az feature show --namespace "Microsoft.ContainerService" --name "AKS-OutBoundTypeMigrationPreview"
az provider register --namespace Microsoft.ContainerService
```

## 1. Creating an AKS cluster with outbound type load balancer

```bash
$RG = "rg-aks-cluster-dev"

az group create -n $RG -l westeurope

az network vnet create -g $RG -n vnet-aks --address-prefixes 172.16.0.0/20

$SUBNET_ID = $(az network vnet subnet create -g $RG --vnet-name vnet-aks -n subnet-aks `
--address-prefixes 172.16.0.0/22 `
--query id --output tsv)

$IDENTITY_ID = $(az identity create -g $RG -n identity-aks --query id --output tsv)

az aks create -g $RG -n aks-cluster `
--network-plugin azure `
--vnet-subnet-id $SUBNET_ID `
--outbound-type loadBalancer `
--enable-managed-identity `
--assign-identity $IDENTITY_ID
az aks get-credentials -g $RG -n aks-cluster --overwrite-existing
```

Check outbound egress traffic uses Load Balancer public IP

```bash
kubectl run nginx --image=nginx
sleep 10
kubectl exec nginx -it -- curl http://ifconf.me
```

Note that is the public IP of the Load Balancer. This is the default behavior of AKS clusters.

## 2. Migrate outbound type from load balancer to user NAT Gateway

### 2.1. Create the user NAT GAteway with its IP address

```bash
az network public-ip create -g $RG -n pip-natgateway --sku standard
az network nat gateway create -g $RG -n nat-gateway --public-ip-addresses pip-natgateway
```

### 2.2. Watch for downtime for egress traffic

Run this command in new powershell session for watch for the downtime of egress traffic.

```bash
for ($i = 0; $i -lt 30; $i++) {
date
kubectl exec nginx -it -- curl http://ifconf.me
sleep 10 # 10 seconds
}
# Wednesday, October 18, 2023 6:07:33 PM
# 20.31.59.30
# Wednesday, October 18, 2023 6:07:34 PM
# error: Timeout occurred
# Wednesday, October 18, 2023 6:08:06 PM
# Error from server: error dialing backend: EOF
# Wednesday, October 18, 2023 6:13:09 PM
# 13.93.68.197
```

### 2.3. Associate nat gateway with subnet where the workload is associated with.

```bash
az network vnet subnet update -g $RG --vnet-name vnet-aks --name subnet-aks --nat-gateway nat-gateway
```

### 2.4. Update cluster from loadBalancer to userAssignedNATGateway in BYO vnet scenario

```bash
az aks update -g $RG -n aks-cluster --outbound-type userAssignedNATGateway
```

Now the NAT Gateway is configured for your AKS cluster.

![](images/resources.png)

>It takes about 6 minutes to update the KAS outboundType from Load Balancer to user NAT Gateway. The pods are able to egress traffic during this time.

> It takes few seconds to update the Subnet. During this time, pods are not able to egress traffic.

Note the new IP address of the NAT Gateway used for egress/outbound traffic.

Note that the Load Balancer and its public IP was deleted.

![](images/deleted-lb.png)

## Cleanup resources

```bash
az group delete -n $RG --yes --no-wait
```
32 changes: 32 additions & 0 deletions 77_migrate_lb_to_natgateway_tf/aks.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
resource "azurerm_user_assigned_identity" "identity" {
name = "identity-aks"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
}

resource "azurerm_kubernetes_cluster" "aks" {
name = "aks-cluster"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
dns_prefix = "aks"

default_node_pool {
name = "default"
node_count = 3
vm_size = "Standard_B2s_v2"
vnet_subnet_id = azurerm_subnet.subnet.id
# pod_subnet_id = azurerm_subnet.subnet.id
zones = [1, 2, 3]
}

network_profile {
network_plugin = "azure"
load_balancer_sku = "standard"
outbound_type = "userAssignedNATGateway" # "loadBalancer"
}

identity {
type = "UserAssigned"
identity_ids = [azurerm_user_assigned_identity.identity.id]
}
}
36 changes: 36 additions & 0 deletions 77_migrate_lb_to_natgateway_tf/commands.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# prerequisites

az feature register --namespace "Microsoft.ContainerService" --name "AKS-OutBoundTypeMigrationPreview"
az feature show --namespace "Microsoft.ContainerService" --name "AKS-OutBoundTypeMigrationPreview"
az provider register --namespace Microsoft.ContainerService

# 1. AKS cluster with outbound type load balancer

terraform init

terraform apply -auto-approve

$RG = "rg-aks-cluster-dev"

az aks get-credentials -g $RG -n aks-cluster --overwrite-existing

# check outbound egress traffic uses Load Balancer public IP

kubectl run nginx --image=nginx
sleep 10
kubectl exec nginx -it -- curl http://ifconf.me

# Note that is the public IP of the Load Balancer. This is the default behavior of AKS clusters.

# Associate nat gateway with subnet where the workload is associated with.

az network vnet subnet update -g $RG --vnet-name vnet-aks --name subnet-aks --nat-gateway nat-gateway

# Update cluster from loadbalancer to userAssignedNATGateway in BYO vnet scenario
az aks update -g $RG -n aks-cluster --outbound-type userAssignedNATGateway

kubectl exec nginx -it -- curl 10.0.1.4
# Hello from virtual machine: vm-linux, with IP address: 10.0.1.4

# cleanup resources
az group delete -n $RG --yes --no-wait
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions 77_migrate_lb_to_natgateway_tf/install-webapp.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/bash

sudo apt -qq update

# Install curl and traceroute and jq
sudo apt -qq install curl traceroute inetutils-traceroute jq -y

# Install NGINX web server
sudo apt -qq install nginx -y

IP=$(hostname -i)

echo "Hello from virtual machine: $HOSTNAME, with IP address: $IP" > /var/www/html/index.html

# Script to force enable color prompt on Ubuntu and other Linux distros.
sed -i 's/#force_color_prompt=yes/force_color_prompt=yes/g' ~/.bashrc

# Reload the .bashrc file
source ~/.bashrc
25 changes: 25 additions & 0 deletions 77_migrate_lb_to_natgateway_tf/modules/bastion/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
resource "azurerm_public_ip" "pip" {
name = "pip-bastion"
location = var.location
resource_group_name = var.resource_group_name
allocation_method = "Static"
sku = "Standard"
}

resource "azurerm_bastion_host" "bastion" {
name = "bastion-host"
location = var.location
resource_group_name = var.resource_group_name
sku = "Standard" # "Basic", Developer
copy_paste_enabled = true
file_copy_enabled = true
shareable_link_enabled = true
tunneling_enabled = true
ip_connect_enabled = false

ip_configuration {
name = "configuration"
subnet_id = var.subnet_id
public_ip_address_id = azurerm_public_ip.pip.id
}
}
3 changes: 3 additions & 0 deletions 77_migrate_lb_to_natgateway_tf/modules/bastion/output.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
output "bastion_id" {
value = azurerm_bastion_host.bastion.id
}
11 changes: 11 additions & 0 deletions 77_migrate_lb_to_natgateway_tf/modules/bastion/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
variable "resource_group_name" {
type = string
}

variable "subnet_id" {
type = string
}

variable "location" {
type = string
}
49 changes: 49 additions & 0 deletions 77_migrate_lb_to_natgateway_tf/modules/vm_linux/doc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<!-- BEGIN_TF_DOCS -->
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.2.8 |
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >= 3.69.0 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | >= 3.69.0 |

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [azurerm_linux_virtual_machine.vm](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/linux_virtual_machine) | resource |
| [azurerm_network_interface.nic_vm](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_interface) | resource |
| [azurerm_public_ip.pip_vm](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/public_ip) | resource |
| [azurerm_resource_group.rg](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) | resource |
| [azurerm_role_assignment.role_contributor](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
| [azurerm_user_assigned_identity.identity_vm](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) | resource |
| [azurerm_virtual_machine_extension.vm_extension_linux](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine_extension) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_admin_password"></a> [admin\_password](#input\_admin\_password) | n/a | `any` | n/a | yes |
| <a name="input_admin_username"></a> [admin\_username](#input\_admin\_username) | n/a | `any` | n/a | yes |
| <a name="input_enable_public_ip"></a> [enable\_public\_ip](#input\_enable\_public\_ip) | n/a | `any` | n/a | yes |
| <a name="input_location"></a> [location](#input\_location) | n/a | `any` | n/a | yes |
| <a name="input_resource_group_name"></a> [resource\_group\_name](#input\_resource\_group\_name) | n/a | `any` | n/a | yes |
| <a name="input_subnet_id"></a> [subnet\_id](#input\_subnet\_id) | n/a | `any` | n/a | yes |
| <a name="input_subscription_id"></a> [subscription\_id](#input\_subscription\_id) | n/a | `any` | n/a | yes |
| <a name="input_tags"></a> [tags](#input\_tags) | n/a | `any` | n/a | yes |
| <a name="input_vm_name"></a> [vm\_name](#input\_vm\_name) | n/a | `any` | n/a | yes |
| <a name="input_vm_size"></a> [vm\_size](#input\_vm\_size) | n/a | `any` | n/a | yes |

## Outputs

No outputs.
<!-- END_TF_DOCS -->
Loading

0 comments on commit f2dbda5

Please sign in to comment.