02-07 15:46
반응형
250x250
Recent Posts
Recent Comments
Link
관리 메뉴

DevOps Tasks

[K8S] AWS Load Balancer Controller 본문

Kubernetes

[K8S] AWS Load Balancer Controller

데밥스 2024. 8. 4. 20:27
728x90
반응형

AWS Load Balancer Controller는 Kubernetes 클러스터의 AWS Elastic Load Balancer를 관리한다.

AWS ALB Ingress Controller 로 알려져 있지만 최근에 AWS Load Balancer Controller로 변경되었다.

수신 리소스는 ALB를 구성하여 HTTP 또는 HTTPS 트래픽을 클러스터 내 다른 포드로 라우팅 한다.

ALB 수신 컨트롤러는 Amazon EKS 클러스터에서 실행 중인 프로덕션 워크로드에서 지원된다.

 

 

  1. ALB-Ingress-Controller는 API 서버의 수신 이벤트를 감시하며 요구 사항을 충족하는 수신 리소스를 찾으면 AWS 리소스 생성을 시작한다.
  2. 새로운 수신 리소스에 대해서 ELB 가 AWS에 생성된다. 해당 ELB는 internet-facing 이거나 internal 일 수 있고 annotation을 통해서 생성되는 서브넷을 지정할 수 있다.
  3. 수신 리소스에 정의된 각 고유한 Kubernetes 서비스에 대해서 Target Group 이 AWS에 생성된다.
  4. 수신 리소스 주석에 자세히 설명된 모든 포트에 대해서 리스너가 생성된다. 인증서 또한 annotation을 통해서 지정할 수 있다.
  5. 포트를 지정하지 않으면 default 값으로 80, 443 포트로 생성된다.
  6. 수신 리소스에 지정된 각 경로에 대해서 규칙이 생성된다. 이렇게 하면 특정 경로 및 규칙에 의해 트래픽이 정해진 Kubernetes 서비스로 라우팅 된다.

 

Ingress Traffic

AWS Load Balancer Controller는 2 가지 트래픽 모드를 지원한다.

  • Instance Mode
  • IP Mode

기본적으로 인스턴스 모드가 사용되며 사용자는 annotation을 통해서 모드를 명시적으로 선택할 수 있다.

alb.ingress.kubernetes.io/target-type

 

Instance Mode

수신 트래픽은 ALB에서 시작하여 각 서비스의 NodePort를 통해 Kubernetes 노드에 도달한다.

이는 수신 리소스에서 참조되는 서비스가 type:NodePort ALB에 도달하기 위해 노출되어야 함을 의미한다.

 

IP Mode

수신 트래픽은 ALB에서 시작하여 Kubernetes Pod에 직접 도달한다. CNI는 ENI의 보조 IP 주소를 통해 직접 액세스 가능한 Pod IP를 지원해야 한다.

 


 

ALB Ingress & AWS Load Balancer Controller Traffic Flow

 

  • Client는 ALB DNS A Record:Port 번호로 접근하게 된다.
  • ALB는 각 Node로 트래픽을 Load Balancing 한다.
  • Kube-API에 의해 업데이트된 정보를 가지고 ALB에서 Load Balancing 처리를 한다.

 

AWS Load Balancer Controller 구축

IAM OIDC Provider 생성

AWS IAM에서는 OIDC를 사용하여 연동 자격 증명을 지원한다.

해당 기능을 사용하여 지원되는 자격 증명 공급자를 통해 AWS API 호출을 인증하고 유효한 OIDC JWT를 수신할 수 있다.

해당 토큰을 AWS STS API 작업에 전달하고 IAM 임시 역할 자격 증명을 획득하여 AWS 서비스 자원들을 Kubernetes 자원들이 사용할 수 있다.

IAM OIDC Provider는 기본적으로 활성화되어 있지 않다. eksctl을 사용하여 IAM OIDC Provider를 생성한다.

# Weaveworks Homebrew Tap Install
$ brew tap weaveworks/tap

# eksctl install
$ brew install weaveworks/tap/eksctl

# eksctl upgrade
$ brew upgrade eksctl & brew link --overwrite eksctl

# Verify the eksctl version
$ eksctl version
# 자격증명으로 컨트롤 플레인 접속
aws eks --region ${AWS_REGION} update-kubeconfig --name ${EKS_CLUSTER_NAME}

# 클러스터의 IAM OIDC 제공업체 생성
eksctl utils associate-iam-oidc-provider \\
--cluster ${EKS_CLUSTER_NAME} \\
--region ${AWS_REGION}
--approve

 

AWS LoadBalancer Controller IAM Policy

$ curl -o iam-policy.json <https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.2.1/docs/install/iam_policy.json>

# Create Policy
$ aws iam create-policy \\
    --policy-name AWSLoadBalancerControllerIAMPolicy \\
    --policy-document file://iam-policy.json

 

Create AWS Load Balancer Controller IAM Role & Service Account

$ eksctl create iamserviceaccount \\
--cluster=${EKS_CLUSTER_NAME} \\
--namespace=kube-system \\
--name=aws-load-balancer-controller \\
--attach-policy-arn=arn:aws:iam::${ACCOUNT_ID}:policy/AWSLoadBalancerControllerIAMPolicy \\
--override-existing-serviceaccounts \\
--region ${AWS_REGION} \\
--approve

# Service Account 등록 확인
$ kubectl get serviceaccounts -n kube-system aws-load-balancer-controller -o yaml

AWS Load Balancer Controler에 대한 Service Account를 생성하고 이전에 생성한 IAM Role을 연결한다.

 

EKS Cluster에 Controller 추가

# helm 에 EKS Chart 저장소 추가
$ helm repo add eks <https://aws.github.io/eks-charts>

# aws-load-balancer-controller 설치
$ helm install aws-load-balancer-controller eks/aws-load-balancer-controller \\
  -n kube-system \\
  --set clusterName=${EKS_CLUSTER_NAME} \\
  --set serviceAccount.create=false \\
  --set serviceAccount.name=aws-load-balancer-controller \\
  --set image.repository=602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/amazon/aws-load-balancer-controller \\
  --set region=${AWS_REGION} \\
  --set vpcId=${VPC_ID}

# aws-load-balancer-controller 설치 확인
$ kubectl get deployment -n kube-system aws-load-balancer-controller

# Helm으로 설치된 AWS-Load-Balancer-Controller 삭제
$ helm delete aws-load-balancer-controller -n kube-system

alb.yaml

apiVersion: elbv2.k8s.aws/v1beta1
kind: IngressClassParams
metadata:
  name: ${IngressClassParams_Name}
  namespace: ${NameSpace}
spec:
	# ELB Types (internal or internet-facing)
  scheme: ${ELB_TYPE}
---
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: ${IngressClass_Name}
  namespace: ${NameSpace}
spec:
  controller: ingress.k8s.aws/alb
  parameters:
    apiGroup: elbv2.k8s.aws
    kind: IngressClassParams
    name: ${IngressClassParams_Name}
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ${ELB_Name}
  namespace: ${NameSpace}
  annotations:
    kingressClassName: alb
    alb.ingress.kubernetes.io/name: ${ELB_Name}
    alb.ingress.kubernetes.io/scheme: ${ELB_TYPE}
    # ip, instance
    alb.ingress.kubernetes.io/target-type: ${ELB_Target_Group_Type}
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
    alb.ingress.kubernetes.io/certificate-arn: ${ACM_ARN}
    alb.ingress.kubernetes.io/security-groups: ${ELB_SG_ID}
    alb.ingress.kubernetes.io/subnets: ${ELB_Subnet}
spec:
  ingressClassName: ${IngressClass_Name}
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: ${Application_SVC}
            port:
              number: 8080
728x90
반응형