본문 바로가기
IT/Kubernetes

Application Gateway를 AKS 인그레스 컨트롤러로 사용하기

by rapker 2023. 4. 11.
반응형

참고

추가 내용

Application Gateway를 AKS에서 인그레스 컨트롤러로 사용이 가능합니다.

장점은 Application Gateway 수신 컨트롤러 문서에서 자세히 확인할 수 있습니다.

 

AGIC 구성

 

Application Gateway의 설정을 컨트롤할 수 있는 AGIC(Application Gateway Ingress Controller)는 두 가지 방식으로 배포할 수 있습니다.

  • Helm (Kubelet 으로)
  • AKS Add-On (포탈에서) - Azure Docs
    • AKS 생성 시 옵션으로 (Add-On 방식과 동일) - Azure Docs

Azure Docs상의 Helm 배포와 AKS 추가기능 배포의 차이점 요약 정리

Helm AKS Add-On

AGIC 설정 - verbosityLevel (기본값 5) O X
AGIC 설정 - usePrivateIp (기본값 false) O https://docs.microsoft.com/ko-kr/azure/application-gateway/ingress-controller-annotations#use-private-ip으로 덮어쓸 수 있습니다.
AGIC 설정 - shared(이게 클러스터당 두 개 이상의 AGIC를 뜻하는건가?) O X
AGIC 설정 - reconcilePeriodSeconds O X
AGIC 설정 - .type O X
ProhibitedTargets O X
AGIC 자동 업데이트 X O
AKS 클러스터당 두 개 이상의 AGIC 배포 O X
AppGW 하나를 대상으로 여러 AGIC 사용 O X

 

AKS cluster를 CLI로 생성하는 경우에는 간단한 옵션 한 줄로 추가할 수 있습니다.

az aks create -n myCluster -g myResourceGroup --network-plugin azure --enable-managed-identity -a ingress-appgw --appgw-name myApplicationGateway --appgw-subnet-cidr "10.2.0.0/16" --generate-ssh-keys

 

Add-On 설치 방식은

  • CLI로 AKS 클러스터 생성 시 옵션으로 AGIC를 생성하거나
  • Portal에서 설정으로 진행할 수 있지만

helm으로 생성하는 방법보다 좀 쉽다는 잇점만 있을 뿐, 쉬운 설치 외 helm으로의 설치보다 나은점은 없어 보입니다.

앞으로도 Add-On 방식을 권장할 일은 없을 것 같아 Helm으로의 AGIC 설치 방법만 조사해 보도록 하겠습니다.

 


helm으로 AGIC 설치 하는 방법

참고

준비 사항

  • Azure CNI를 사용하는 AKS 클러스터

필요 도구

진행 순서

  • Application Gateway 생성
  • Application Gateway용 subnet 추가
  • Service Principal 생성
  • Ingress Controller 설치
  • Sample Application 및 Ingress 배포

 

시작 하기전 aks 리소스  확인

 

시작하기전  기본 상태 확인

 

비어있는 ingerss 항목 확인

kubectl get ingress

 

AzureCNI를 사용하는 AKS 클러스터에 실행중인 pod는 아무것도 없습니다.

kubectl get all

 

 

 

Application Gateway에서 사용할 Subnet 추가

Application Gateway를 만들기 위해 AKS가 속해있는 VNet에 Subnet을 추가 합니다.

 

 

 

Application Gateway 생성

AKS 리소스들이 존재하는 리소스 그룹에서 Application Gateway를 추가 합니다.

AGIC로 사용 가능한 AppGW 의 sku 아래 두 개 이며

  • AppGW v2
  • AppGW WAF v2

이번 테스트에는 AppGW WAF v2를 사용하겠습니다.

 

AppGW를 생성합니다.

 

AGIC로 사용하기 위한 설정은SKU와 VNet만 중요하고 그 외 설정들은 그냥 기본값으로 뚝딱뚝딱 넘어 갑니다.

 

깡통 옵션으로 만들어진 Application Gateway 확인

 

AKS 클러스터 자격증명 얻기

(agic를 고민할 정도면 aks 자격증명 얻는건 다 알고 있을 내용이지만. 그냥 기록)

az aks get-credentials -g <리소스 그룹 이름> -n <클러스터 이름>

az aks get-credentials -g rgAKS -n aksTest998

 

Service Principal 생성

AGIC는 k8s api server와 ARM(Azure Resource Manager)사이에서 설정값을 동기화 하기위한 통신을합니다.

AGIC가 두 server에 통신하기 위한 인증 방법에는 두 가지가 있습니다.

  • aadPodIdentity (AAD Pod Id)
  • servicePrincipal (SP)

두 가지 방법에 어떠한 장단점이 있는지는 다음번 기회가 있을 때 알아보도록 하고, 이번에는 ServicePrincipal인증을 사용하도록 합니다.

 

 

서비스 주체(SP = Service Principal) 생성

sp 주체를 만들고 k8s에 등록하기위해 base64로 인코딩 하는 과정입니다.

windows 10 에서 실행되었습니다. ( linux 환경이라면 쬐끔 더 쉽게 인코딩 할 수 있습니다.)

az ad sp create-for-rbac --sdk-auth -n <sp name> > sp.txt

 

생성된 SP 확인

 

sp credentials을 k8s의 secret으로 등록하기 위해 base64로 인코딩

certutil -encode sp.txt sp_base64.txt

 

인코딩된 sp_base64.txt파일의 내용은 다음 단계인 Helm으로 ingress controller 설치 에서 arm 인증에 사용됩니다.

(begin certificate 와 end certificate 사이의 값만 사용됩니다.)

 

 

 

Helm으로 ingress controller 설치

repogitory 추가

helm repo add application-gateway-kubernetes-ingress <https://appgwingress.blob.core.windows.net/ingress-azure-helm-package/>
helm repo update

 

helm-config.yaml 작성

sample-helm-config.yaml 원본 파일의 내용으로 helm-config.yaml 파일을 생성합니다.

 

생성한 helm-config.yaml 파일에서 몇 가지 정보 입력 및 확인하고 넘어가겠습니다.

 

 

VerbosityLevel

VerbosityLevel

  • verbosityLevel은 로그를 남기는 정도를 의미 합니다.
    • 1 : 기본 로그, 경고 및 오류 표시
    • 3 : 이벤트 및 변경 사항에 대한 정보 생성 된 개체 목록
    • 5 : 마샬링된 개체를 기록합니다. ARM에 적용된 정리 된 JSON구성을 보여줍니다.


watchNameSpace

  • ingress controller가 관찰 할 네임스페이스 지정
    • 특정 네임스페이스에서만 동작하게 하려면 네임스페이스를 작성해 줍니다.
    • 콤마(,)로 여러개 네임스페이스를 등록할 수 있습니다.
    • watchNamespace 항목이 비활성화(삭제, 주석) 되어 있으면 aks 클러스터내 모든 네임스페이스를 관찰합니다.

 

appgw

  • subscriptionId, resourceGroup, name : AppGW의 정보를 입력해 주면 되고
  • usePrivateIP는 Internal Application Gateway를 사용할 것인지 여부 인데 사용하는 경우는 상당히 드물 것 같습니다.
  • shared : ApplicationGateway 1개로 여러개의 AGIC를 사용할 것인가에 대한 옵션인데 나중에 기회 될 때 테스트 해보면 될 것 같습니다.

 

armAuth

 

  • AGIC가 ARM과 통신할 때 사용할 수 있는 자격증명은 두 가지 방법이 있습니다.
    • AAD Pod ID 사용
    • k8s secret 사용
  • json 파일에 armAuth가 두 개 있는데 사용하지 않는 armAuth는 주석처리 해주고, 필요한 값을 입력합니다.
    • SP 인증방식으로 진행되었기에 위에서 추출한 sp_base64.txt 파일의 일부 내용을 입력합니다.

 

rbac

 

  • AKS Cluster가 rbac을 사용한다면 true로 설정해 줍니다.
  • aks 속성에서 확인할 수 있습니다.

 

작성 완료된 helm-config.yaml 샘플

helm-config.yaml
0.00MB

# This file contains the essential configs for the ingress controller helm chart

# Verbosity level of the App Gateway Ingress Controller
verbosityLevel: 3

################################################################################
# Specify which application gateway the ingress controller will manage
#
appgw:
    subscriptionId: 4c3e8c6f-e570-448b-82c5-1507cb59d0b5
    resourceGroup: MC_rgAKS_aksTest998_koreacentral
    name: agwTest
    usePrivateIP: false

    # Setting appgw.shared to "true" will create an AzureIngressProhibitedTarget CRD.
    # This prohibits AGIC from applying config for any host/path.
    # Use "kubectl get AzureIngressProhibitedTargets" to view and change this.
    shared: false

################################################################################
# Specify which kubernetes namespace the ingress controller will watch
# Default value is "default"
# Leaving this variable out or setting it to blank or empty string would
# result in Ingress Controller observing all acessible namespaces.
#
# kubernetes:
#   watchNamespace: <namespace>

################################################################################
# Specify the authentication with Azure Resource Manager
#
# Two authentication methods are available:
# - Option 1: AAD-Pod-Identity (https://github.com/Azure/aad-pod-identity)
#armAuth:
#    type: aadPodIdentity
#    identityResourceID: <identityResourceId>
#    identityClientID:  <identityClientId>

## Alternatively you can use Service Principal credentials
armAuth:
    type: servicePrincipal
    secretJSON: ew0KICAiY2xpZW50SWQiOiAiZTc2ZGI1NzAtNzQxMy00MjdlLThkOTktMmFlNmUzMjQ2Y2M4IiwNCiAgImNsaWVudFNlY3JldCI6ICJPalMtcnlkZVU1SDlIdS1BTVVBamVCTllqQWptZ19fbkpiIiwNCiAgInN1YnNjcmlwdGlvbklkIjogIjRjM2U4YzZmLWU1NzAtNDQ4Yi04MmM1LTE1MDdjYjU5ZDBiNSIsDQogICJ0ZW5hbnRJZCI6ICJhNzRiNTQ1MS1hMjgwLTQ3NjgtYTVjZC1jYjQ3YWYxNTNjNzEiLA0KICAiYWN0aXZlRGlyZWN0b3J5RW5kcG9pbnRVcmwiOiAiaHR0cHM6Ly9sb2dpbi5taWNyb3NvZnRvbmxpbmUuY29tIiwNCiAgInJlc291cmNlTWFuYWdlckVuZHBvaW50VXJsIjogImh0dHBzOi8vbWFuYWdlbWVudC5henVyZS5jb20vIiwNCiAgImFjdGl2ZURpcmVjdG9yeUdyYXBoUmVzb3VyY2VJZCI6ICJodHRwczovL2dyYXBoLndpbmRvd3MubmV0LyIsDQogICJzcWxNYW5hZ2VtZW50RW5kcG9pbnRVcmwiOiAiaHR0cHM6Ly9tYW5hZ2VtZW50LmNvcmUud2luZG93cy5uZXQ6ODQ0My8iLA0KICAiZ2FsbGVyeUVuZHBvaW50VXJsIjogImh0dHBzOi8vZ2FsbGVyeS5henVyZS5jb20vIiwNCiAgIm1hbmFnZW1lbnRFbmRwb2ludFVybCI6ICJodHRwczovL21hbmFnZW1lbnQuY29yZS53aW5kb3dzLm5ldC8iDQp9DQo=

################################################################################
# Specify if the cluster is RBAC enabled or not
rbac:
    enabled: true # true/false

 

helm-config.yaml 파일로 ingress controller 설치

helm install ingress-azure ^
-f helm-config.yaml ^
application-gateway-kubernetes-ingress/ingress-azure

 

참고 (필수항목 아닙니다 일반적인 상황에서는 skip 하시면 됩니다.)

## AGIC 옵션이 바뀌었거나 설치 오류로 인해 다시 설치할 때
helm upgrade --install ingress-azure -f helm-config.yaml application-gateway-kubernetes-ingress/ingress-azure

 

참고로 helm으로 설치된 ingress-azure의 자세한 내용을 확인하려면

helm get all ingress-azure

실제 출력되는 내용은 엄청 긴데 대략 이런식으로 출력됩니다.

 

controller 잘 만들어 졌구요 생성된 리소스 확인해 봅니다.

kubectl get all -o wide

 

pod도 잘 올라와 있습니다.

만약 pod가 정상적으로 실행되지 않은 상태이면 당연한 소리지만 어떻게든 수정해서 정상화 시킨 후 다음 작업 진행해야 합니다.

 

포탈에서 AppGW도 확인해 봅니다.

 

AGIC를 설치 하고 나니 Application Gateway가 생성했을 때와는 다른 값들로 채워져 있네요

만약 수신기, 규칙 등의 네이밍 규칙이 위 화면과유사한 규칙을 보이지 않으면 AppGW와 정상적으로 연결이 되지 않은 상태 입니다.

helm-config.yaml 에 AppGW의 정보와 armAuth 정보를 다시 한번 확인해 주세요

 

 

 

Sample Application 배포

이제 샘플 웹서버와 ingress도 설치 해 봅니다.

yaml 준비

테스트에는 pod(deployment), cluster, ingress가 포함된 샘플 파일을 사용했습니다.

agic_sample_pod.yaml
0.00MB

apiVersion: apps/v1
kind: Deployment
metadata:
  name: aks-helloworld
spec:
  replicas: 1
  selector:
    matchLabels:
      app: aks-helloworld
  template:
    metadata:
      labels:
        app: aks-helloworld
    spec:
      containers:
      - name: aks-helloworld
        image: mcr.microsoft.com/azuredocs/aks-helloworld:v1
        ports:
        - containerPort: 80
        env:
        - name: TITLE
          value: "AKS Ingress Demo"
---
apiVersion: v1
kind: Service
metadata:
  name: svc-aks-helloworld
spec:
  type: ClusterIP
  ports:
  - port: 80
  selector:
    app: aks-helloworld

---

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-aks-helloworld
  annotations:
    kubernetes.io/ingress.class: azure/application-gateway
spec:
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: svc-aks-helloworld
          servicePort: 80

 

pod, ingress 배포

kubectl apply -f agic_sample_pod.yaml

 

배포 확인

kubectl get all -o wide

 

포탈에서 AppGW도 확인해 봅니다.

 

AGIC를 사용한 ingress가 추가 되니까 AppGW에 뭔가 한 세트가 추가 되어 있습니다.

 

자~ 그럼 Application Gateway로 접속을 해 봅니다.

 

AppGW의 public ip 확인

 

AppGW의 public ip로 접속

완성!!!!

 

참고

AGIC의 Annotations을 통해 frontend port, path 등 AppGW의 세부 설정들을 할 수 있습니다.

 

반응형
LIST