많은 애플리케이션들이 Kubernetes 환경에 배포되고 있는 요즈음 AWS, GCP 등.. 많은 CSP(Cloud Service Provider)가 Managed Kubernetes 서비스를 제공하고 있습니다.
CSP가 제공하는 Managed Kubernetes 서비스의 장점 중 하나는 기반이 되는 클라우드 서비스와 연계되는 기능을 제공한다는 점인데요.
특히 Kubernetes의 Ingress를 CSP의 L7 Loadbalancer 서비스와 연계해 생성하는 기능이 널리 사용되고 있습니다.
많은 CSP 이용자들이 Managed Kubernetes 서비스를 사용하며 이러한 이점을 활용하고 있는데요.
만약 Microsoft의 CSP인 Azure를 사용한다면 AKS(Azure Kubernetes Service)를 사용해 동일한 기능을 사용할 수 있습니다.
AKS는 Azure의 L7 Loadbalancer 서비스인 Application Gateway를 사용해서 Ingress를 구성할 수 있는데요.
이번 포스팅에서는 Azure의 Managed Kubernetes 서비스인 AKS에서 Application Gateway를 사용해서 Ingress를 사용하는 방법에 대해 알아보겠습니다.
1. Architecture
AKS와 Application Gateway를 사용하기 위한 Azure 아키텍쳐 구성도는 다음과 같습니다.
1. Azure의 빌링 및 권한을 위한 Subscription과 리소스 생성을 위한 Resource Group, 네트워킹을 위한 Vnet과 서브넷은 이미 준비되었음을 가정합니다.
2. AKS 클러스터는 기존에 존재하는 Resource Group(이하 RG)에 생성합니다. 이 과정에서 AKS의 구성요소를 위한 새 RG가 생성됩니다.
3. AKS 내의 서비스들은 Application Gateway를 이용한 Ingress를 통해 노출합니다.
4. Ingress는 Internal, External 2개의 엔드포인트를 가져 내,외부 Client들이 접근할 수 있도록 구성합니다.
5. External 엔드포인트는 HTTPS 접근만을 허용하며, 이를 위해 Azure Key Vault에 저장된 SSL 인증서를 사용합니다.
6. AKS의 노드 역할을 하는 VMSS(VM ScaleSet)과 Application Gateway는 각각 Private, Public 서브넷에 존재하며, 서브넷마다 필요한 Security Group을 부착합니다.
이번 포스팅에서는 위 아키텍쳐와 조건을 만족하는 AKS 클러스터 및 Ingress를 구성해보도록 하겠습니다.
2. Azure Kubernetes Service 구성
먼저 AKS 클러스터를 생성해 Kubernetes 환경을 구성해보겠습니다.
AKS 클러스터 생성은 웹 UI인 Azure Console을 이용한 방법과 Terraform을 이용한 IaC 방법 2가지로 진행하겠습니다.
2-1. Azure Console
AKS 클러스터를 생성하기 위해 Azure Console에 로그인 후, 상단 검색 바에서 Kubernetes Service를 검색한 뒤 클릭합니다.
이후 우측의 Create -> Create a Kubernetes cluster 순으로 버튼을 클릭해 AKS 생성 페이지로 접근합니다.
AKS 생성 페이지로 접근하면 먼저 Basic 탭에서 클러스터명, RG, Subscription 등의 기본적인 정보를 입력할 수 있습니다.
Production 환경 기준으로 다른 값은 따로 지정할 필요 없이 Subscription과 Resource Group, Cluster name만 지정합니다.
이후 각 탭을 따라 Node pool, Networking 등의 정보를 지정할 수 있습니다.
Networking 탭에서는 기존에 존재하는 Vnet에 생성하기 위해 Bring your own virtual network에 체크한 후, Vnet과 Private 서브넷을 선택합니다.
구성을 마쳤다면 마지막 Review+create 탭에서 입력한 정보를 확인 후 Create 버튼을 클릭해 클러스터를 생성합니다.
클러스터 생성을 마치면 MC_{Resource_group}_{Cluster_name}_{Region} 형식의 이름으로 생성된 Resource Group이 추가된 것을 확인할 수 있습니다.
해당 RG에는 AKS 클러스터에 필요한 VMSS, Security Group, Public IP 등의 리소스들이 존재하는 것을 확인할 수 있습니다.
이제 생성한 AKS 클러스터에 Application Gateway로 Ingress를 생성하기 위한 구성을 진행하겠습니다.
생성한 AKS 페이지에서 우측의 Networking을 클릭한 뒤, Enable ingress controller를 체크합니다.
이후 Application Gateway 속성의 Create new 버튼을 클릭해 새 Application Gateway를 생성한 후, 이를 사용하도록 지정합니다.
새 Application gateway는 아래와 같은 속성으로 생성합니다
속성 | 값 | 비고 |
Resource Group | 생성한 AKS와 동일한 RG | '' |
Vnet | 생성한 AKS와 동일한 Vnet | '' |
Subnet | Public Subnet | Node와 Ingress 네트워크의 분리를 위함 |
SKU | Standard_v2 | V2 지정 필수 |
여기까지 진행했다면 AKS와 Application Gateway 구성이 마무리된 것입니다.
2-2. Terraform
동일한 구성을 Terraform을 활용한 IaC로 생성하는 방법을 알아보겠습니다.
먼저 Terraform 및 Provider의 Version 설정과 Azure 스토리지에 State를 저장하기 위한 Backend 설정입니다.
아래 코드를 사용하기 전 Azure Storage account와 Container가 생성되어 있어야 합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
terraform {
required_version = ">=1.3"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">= 3.51, < 4.0"
}
}
backend "azurerm" {
resource_group_name = "RG_NAME"
storage_account_name = "STORAGE_ACCOUNT_NAME"
container_name = "CONTAINER_NAME"
key = "PATH/TO/BACKEND/FILE/terraform.tfstate"
}
}
|
cs |
다음으로 Azure 리소스를 생성하기 위한 Azure Provider를 구성합니다.
Terraform을 통해 생생된 리소스가 Azure resource provider에 등록될 필요가 없다면 skip_provider_registration 속성을 true로 지정합니다.
하위 리소스가 존재할 경우 삭제를 방지하는 옵션을 해제하려면 prevent_deletion_if_contains_resources 속성을 false로 지정합니다.
1
2
3
4
5
6
7
8
9
|
provider "azurerm" {
skip_provider_registration = true
features {
resource_group {
prevent_deletion_if_contains_resources = false
}
}
}
|
cs |
다음으로 AKS 클러스터를 생성하기 위한 코드를 작성합니다. AKS 생성은 Azure에서 제공하는 AKS 모듈을 이용합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
module "aks" {
source = "Azure/aks/azurerm"
cluster_name = "CLUSTER_NAME"
resource_group_name = "RG_NAME"
kubernetes_version = 1.28
agents_availability_zones = ["1", "2"]
agents_max_count = 50
agents_min_count = 1
agents_pool_name = "agentpool"
agents_type = "VirtualMachineScaleSets"
agents_size = "Standard_B16ls_V2"
azure_policy_enabled = false
enable_auto_scaling = true
ingress_application_gateway_enabled = true
ingress_application_gateway_name = "AGW_NAME"
ingress_application_gateway_subnet_id = "PUBLIC_SUBNET_ID"
log_analytics_workspace_enabled = false
net_profile_dns_service_ip = "10.0.0.10"
net_profile_service_cidr = "10.0.0.0/16"
network_plugin = "azure"
node_os_channel_upgrade = "None"
oidc_issuer_enabled = true
os_disk_size_gb = 60
private_cluster_enabled = false
rbac_aad = false
role_based_access_control_enabled = true
sku_tier = "Standard"
workload_identity_enabled = true
vnet_subnet_id = "PRIVATE_SUBNET_ID"
}
|
cs |
위 코드에서 주의해야 할 사항들은 아래와 같습니다.
속성 | 값 | 설명 |
ingress_application_gateway_enabled | true | Application gateway Ingress를 활성화 |
ingress_application_gateway_name | AGW_NAME | 생성할 AGW의 이름 |
ingress_application_gateway_subnet_id | PUBLIC_SUBNET_ID | AGW가 배치될 Public subnet의 ID |
vnet_subnet_id | PRIVATE_SUBNET_ID | AKS 노드가 배치될 Private subnet의 ID |
sku_tier | Standard | 운영 환경은 Standard 권장 |
enable_auto_scaling | true | 노드 오토스케일링 활성화 |
위 코드를 기반으로 terraform apply를 실행하면 AKS 클러스터 및 Ingress 구성이 완료됩니다.
3. Application Gateway 구성
AKS 클러스터 구성을 마쳤으니 Application Gateway를 Ingress로 사용하기 위한 구성을 진행하겠습니다.
3-1. SSL Certificate 등록
Application Gateway를 HTTPS 요청이 가능한 Ingress로 생성하려면 해당 도메인의 인증을 받은 SSL Certificate가 등록되어 있어야 합니다.
필요한 SSL Certificate를 Azure의 Secret manager 서비스인 Keyvault에 저장한 뒤, 이를 Application gateway에 등록해보겠습니다.
먼저 Azure Console에서 Keyvault 페이지로 접근한 뒤, 상단의 Create 버튼을 클릭해 Keyvault 생성 페이지로 진입합니다.
Keyvault 생성 페이지의 Basics 탭에서 Keyvault가 생성될 Subsciption, RG 및 이름을 지정할 수 있습니다.
Access Configuration 탭에서는 Keyvault의 접근 제어를 구성할 수 있습니다. Permission model을 Vault access policy로 지정합니다.
Access polices에는생성한 Application Gateway가 Keyvault에 저장된 Certificate를 꺼내올 수 있도록 아래 정책을 추가합니다.
속성 | 값 | 설명 |
Application | AGW_NAME | 생성한 AGW 이름 |
Permission | Certificate : Get | Certificate를 꺼내오기 위한 권한 |
위와 같이 설정한 뒤, Create 버튼을 클릭해 Keyvault를 생성합니다.
이후 생성된 Keyvault 페이지의 Access control (IAM) 탭에서 Application Gateway에게 Key Vault Administrator 역할을 부여하는 정책을 추가합니다.
여기까지 진행했다면 Keyvault 구성을 마친 것입니다.
Keyvault에 인증서를 등록하기 위해 Certificate 탭에서 Generate/Import 버튼을 클릭합니다.
인증서 Import시 Application Gateway에 붙이기 위해서는 .pfx 확장자의 인증서를 Import해야 함에 주의합니다.
인증서를 Keyvault에 담았다면 Application Gateway에 해당 인증서를 등록하기 위해 Listener -> Listener TLS certificate -> Add certificate 순으로 클릭합니다.
이후 Choose a certificate from Key Vault를 선택한 뒤 생성한 pfx 인증서를 지정해 해당 인증서를 등록합니다.
여기까지 진행했다면 Application Gateway를 이용해 HTTPS 요청을 받을 수 있는 Ingress를 생성할 준비가 되었습니다.
3-2. Private IP 부착
Application Gateway로 Internal endpoint를 노출한 Ingress를 생성하기 위해서는 Application Gateway에 Private IP가 부착되어 있어야 합니다.
Private IP를 구성하기 위해 생성한 Application Gateway 페이지에서 Frontend IP configuration -> Private 순으로 클릭합니다.
이후 접근하는 페이지에서 Private IP 이름을 지정한 뒤, Choose a specifix private IP addess에 체크합니다.
Private IP address는 Application Gateway가 존재하는 Subnet 내의 예약되지 않은 IP 주소를 지정합니다.
Application Gateway를 Standard V2 SKU로 생성했기 때문에 Static IP Address를 사용해야 정상적으로 진행됩니다.
Private 타입의 상태가 Configured로 변경되었다면 정상적으로 반영된 것입니다.
Private IP가 구성되었다면 Application Gateway를 사용해 Internal Endpoint를 노출할 수 있는 Ingress를 사용할 수 있습니다.
4. Kubernetes Ingress 생성
여기까지 Azure에서 진행해야 할 모든 구성을 마쳤습니다.
이제 Kubernetes에 접속해서 Ingress를 생성해 어플리케이션을 노출해 보겠습니다.
4-1. Kubernetes 사전 준비
먼저 생성한 AKS 클러스터에 접속하기 위해 아래 명령어로 클러스터를 등록합니다.
1
|
az aks get-credentials --resource-group RG_NAME --name CLUSTER_NAME
|
cs |
아래와 같은 텍스트가 출력됐다면 정상적으로 클러스터가 등록된 것입니다.
이후 클러스터에 접속한 후 kube-system 네임스페이스에 Ingress를 Application Gateway로 사용하기 위한 Application gateway Ingress controller가 정상적으로 설치되었는지 확인합니다.
아래 명령어를 실행해 Ingress로 노출할 애플리케이션을 생성합니다.
1
2
|
kubectl run nginx --image nginx
kubectl expose pod nginx --type ClusterIP --name nginx --port 80
|
cs |
아래와 같이 Nginx Pod와 이를 노출해주는 ClusterIP Service가 존재하는지 확인합니다.
1
2
3
4
5
|
NAME READY STATUS RESTARTS AGE
pod/nginx 1/1 Running 0 69s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/nginx ClusterIP 10.0.243.68 <none> 80/TCP 45s
|
cs |
이제 Ingress로 노출할 애플리케이션이 준비되었습니다.
4-2. HTTP Ingress 생성
먼저 HTTP 요청을 받을 수 있는 HTTP Ingress를 생성해보겠습니다.
Application Gateway로 HTTP Ingress를 생성하기 위해 아래 yaml을 적용합니다.
spec.ingressClassName 속성의 값으로 azure-application-gateway를지정해야 함에 주의합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
spec:
ingressClassName: azure-application-gateway rules:
- http:
paths:
- path: /
backend:
service:
name: nginx
port:
number: 80
pathType: Exact
|
cs |
이후 Ingress 목록을 확인했을시 아래와 같이 Application Gateway의 Public endpoint가 붙은 것을 볼 수 있습니다.
1
2
|
NAME CLASS HOSTS ADDRESS PORTS AGE
nginx-ingress azure-application-gateway * 20.239.45.215 80 14s
|
cs |
Application Gateway의 Listener에서 확인 시 아래와 같이 80포트, HTTP 프로토콜, Public IP를 가진 새 Listener가 생성된 것을 볼 수 있습니다.
Application Gateway Ingress는 HTTP 프로토콜을 지정할 시 기본적으로 80 포트를 노출하도록 설정됩니다.
이후 부여된 Public IP를 HTTP 프로토콜로 접속했을시 Nginx 서버로 라우팅되는 것을 확인할 수 있습니다.
4-2. HTTPS Ingress 생성
다음으로 HTTPS 요청을 받을 수 있는 Ingress를 생성해보겠습니다.
HTTPS 요청을 받기 위해서는 해당 도메인의 인증을 받은 SSL Certificate가 필요합니다.
HTTPS Ingress를 생성하기 위해 아래 yaml을 적용합니다.
annotations.appgw.ingress.kubernetes.io/appgw-ssl-certificate 속성의 값으로 Application gateway에 등록한 SSL Certificate 이름을 지정해야 함에 주의합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
appgw.ingress.kubernetes.io/appgw-ssl-certificate: "SSL_CERT_NAME"
spec:
ingressClassName: azure-application-gateway
rules:
- http:
paths:
- path: /
backend:
service:
name: nginx
port:
number: 80
pathType: Exact
|
cs |
위 yaml을 적용한 뒤 Ingress가 정상적으로 생성되면 Application Gateway의 Listener에 443 포트,HTTPS 프로토콜, Public IP를 가진 새 Listner가 등록된 것을 확인할 수 있습니다.
Application Gateway Ingress는 HTTPS 프로토콜을 지정할 시 기본적으로 443 포트를 노출하도록 설정됩니다.
4-3. Private Ingress 생성
마지막으로 Private Endpoint를 가지는 Ingress를 생성해보겠습니다.
Ingress의 Address는 Application Gateway에 구성해놓은 Private IP를 가지게 됩니다.
Private Ingress를 생성하기 위해 아래 yaml을 적용합니다.
annotations.appgw.ingress.kubernetes.io/use-private-ip 속성의 값으로 true를 지정해야 함에 주의합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
appgw.ingress.kubernetes.io/use-private-ip: "true"
spec:
ingressClassName: azure-application-gateway
rules:
- http:
paths:
- path: /
backend:
service:
name: nginx
port:
number: 80
pathType: Exact
|
cs |
Private Ingress를 생성했을시 아래와 같이 Address가 구성된 Private IP로 변경되는 것을 확인할 수 있습니다.
1
2
|
NAME CLASS HOSTS ADDRESS PORTS AGE
nginx-ingress azure-application-gateway * 10.21.1.4 80 21m
|
cs |
Application Gateway에서 확인할 시 아래와 같이 80 포트, HTTP 프로토콜 Private IP를 가지는 Listener가 등록된 것을 확인할 수 있습니다.
5. 마무리
지금까지 AKS에서 Application Gateway를 활용한 Ingress를 사용하는 방법에 대해 알아봤습니다.
이를 위해 AKS 클러스터와 Application Gateway를 적절한 위치에 생성하고, 구성해야 했습니다.
생성 및 구성은 AWS Console을 통한 Web UI와 Terraform을 통한 IaC 방법 두 가지로 진행할 수 있었습니다.
구성을 마친 뒤에는 Kubernetes Ingress를 적용해 HTTP, HTTPS, Private 3가지 종류의 Ingress를 Application Gateway로 생성할 수 있었습니다.
이 글을 보는 분들이 AKS로 Application gateway를 이용한 Ingress를 생성하는데 도움을 받았으면 합니다.
'Azure' 카테고리의 다른 글
Microsoft Azure AZ-304 합격 및 Azure Solutions Architect Expert 취득 후기 (0) | 2021.10.18 |
---|---|
Azure AZ-303 시험 합격 후기 (2) | 2021.04.30 |
Azure Fundamentals Certificate 취득기 (AZ-900 Exam) (0) | 2021.02.17 |