AEWS 4기 2주차(2) - K8s 서비스와 Loadbalancer Controller

2026. 3. 23. 11:09AWS 4기

본 글은 공식 문서 및 서종호(가시다)님의 AWS EKS 워크샵 내용을 기반으로 참고하여 학습 목적으로 작성하였습니다.
주관적인 해석이 포함되어 있어 사실과 다르거나 오류가 있을 수 있으니 참고용으로만 읽어주시기 바랍니다.

이전 글에서 서비스를 사용하는 이유에 대해서는 명시해드렸습니다.(Pod간 통신 시 문제 확인)

오늘 기재할 글에 내용은 K8s 서비스에 종류와 AWS VPC CNI의 Loadbalancer Controller를 통해서 어떤식으로 서비스를 연동할 수 있는지 학습한 내용입니다.

 

K8s 서비스 종류 - 참고

쿠버네티스 서비스 종류

항목 설명 용도
Cluster IP 클러스터 내부에서 서비스 접속 가능 Cluster IP 및 Port를 통해 서비스 호출
NodePort 클러스터 외부에서도 노드의 IP와 파드와 매핑된 포트를 통해 접속 가능(Cluster IP 서비스 기능을 포함) Node IP 및 Port를 통해 서비스 호출
Loadbalancer CSP에서 제공하는 로드밸런서 서비스 or MetalLB 등과 같은 서비스를 노드에 IP 및 포트와 매핑시켜 외부에서도 접속이 가능(Cluster IP, NodePort 서비스 기능을 포함) Loadbalancer IP와 Port를 통해 서비스 호출
ExternalName 쿠버네티스의 DNS에 기능을 담당하며, 서비스 도메인으로 접속 시 해당 엔드포인트 도메인과 연결된 정보를 확인하여 Pod로 접속이 가능할 수 있도록 하는 기능 외부, 내부 서비스 도메인에 CNAME 값을 반환하여 서비스 호출

 

쿠버네티스 Kube-proxy 모드 종류

kube-proxy는 API 서버를 지속적으로 감시하여 서비스 및 엔드포인트에서 변경 사항이 발생하면 설정된 프록시 모드에 대해서 정책을 업데이트 하는 역할을 수행합니다.

kube-proxy 모드 설명 동작 모드
iptables Kernel netfilter 보조 시스템과 iptables API를 사용하여 패킷포워딩 규칙 설정 및 Service Proxy 역할을 수행 클러스터 내부에서 서비스 및 엔드포인트에 변경 사항이 발생하면 API 서버를 지속적으로 감시하고 있던 각 노드의 kube-proxy가 이를 직접 감지합니다.
변경된 트래픽 경로를 확인한 kube-proxy는 리눅스 커널의 네트워크 방화벽 도구인 iptables의 Routing Rule을 업데이트 합니다.

kube-proxy는 정책 업데이트만 수행하며, 실제 트래픽은 netfilter에서 수행합니다.
ipvs Linux 커널에서 제공하는 L4 Loadbalancer인 IPVS가 Service Proxy 역할을 수행 iptables 모드와 달리 IPVS 모드의 kube-proxy는 리눅스 커널의 L4 로드밸런싱 전용 기술인 IPVS의 해시 테이블(Hash Table)을 업데이트합니다. 이를 통해 규칙을 하나씩 순서대로 읽지 않고 수만 개의 서비스 중에서도 단번에 목적지를 찾아내어 병목 현상 없이 높은 속도로 통신 트래픽을 분기 처리하도록 설정합니다.
nftables Kernel netfilter 보조 시스템에 nftables를 사용하여 패킷 포워딩을 설정하는 역할을 수행
iptables를 대체하는 최신 방화벽 기술로, 라우팅 규칙을 시스템 부담 없이 아주 빠르게 업데이트합니다.

Linux OS를 사용하는 노드에서만 사용 가능하며, 5.13커널 버전보다 높을때 사용 가능합니다.
리눅스 커널의 최신 네트워크 필터링 프레임워크인 nftables에 라우팅 규칙을 설정합니다. 기존 iptables가 규칙 하나만 바뀌어도 전체 목록을 통째로 덮어써야 했던 것과 달리, nftables는 변경된 라우팅 규칙만 업데이트하여 노드의 CPU 리소스 소모를 대폭 줄이고 트래픽 설정 지연을 방지합니다.
eBPF(Cilium) 이 방식은 기존의 엔드포인트,서비스에 변경이 발생하여도 kube-proxy 프로세스를 아예 사용하지 않습니다. 클러스터 내 서비스 및 엔드포인트 변경 사항이 API 서버에 발생하면 각 노드에 배포된 eBPF 기반 CNI 에이전트(예: Cilium)가 이를 직접 감지합니다. 에이전트는 무거운 리눅스 OS 네트워크 방화벽 계층(iptables 등)을 거치는 대신, 트래픽이 발생하는 파드의 소켓(Socket)이나 네트워크 카드(NIC) 단에 직접 eBPF 프로그램(커널 샌드박스 프로그램)을 주입하여, 패킷이 출발하자마자 가장 빠른 최단 거리로 목적지 파드에 꽂히도록 라우팅 처리를 수행합니다.

 


EKS - Loadbalancer Controller(with IRSA) - 참고

AWS 로드 밸런서 컨트롤러는 Kubernetes 클러스터에 서비스로 프로비저닝된 AWS Elastic Load Balancer를 관리합니다. 컨트롤러를 사용하여 클러스터 내에서 실행 중인 애플리케이션을 인터넷에 노출할 수 있습니다. 로드밸런서 컨트롤러는 클러스터 Service 또는 Ingress 리소스를 가리키는 AWS 로드 밸런서를 프로비저닝합니다. 다시 말해 컨트롤러는 클러스터의 여러 파드를 가리키는 단일 IP 주소 또는 DNS 이름을 생성합니다.

 

[출처] - 외부 클라이언트 ALB를 통해 EKS 클러스터 내 애플리케이션 접속

 

로드밸런서 컨트롤러는 Kubernetes Ingress or Service 리소스를 감시합니다. 이에 대한 응답으로 해당 AWS Elastic Load Balancing 리소스를 생성합니다. Kubernetes 리소스에 주석을 적용하여 로드 밸런서의 특정 동작을 구성할 수 있습니다.

 

Load Balancer Controller 동작 방식 - 참고

[출처] - https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/how-it-works/

  • 1. 로드밸런서 컨트롤러는 API 서버에서 인그레스 이벤트를 감시합니다. 요구 사항을 충족하는 인그레스 리소스를 발견하면 AWS 리소스(ELB)를 생성합니다.
  • 2. 새 인그레스 리소스에 대한 ALB(ELBv2)가 AWS에 생성되며, 해당 ALB는 인터넷이나 내부에서 노출되고 Annotation을 사용하여 원하는 서브넷 대역에 LB를 생성할 수 있습니다.
  • 3. Target Group들은 Ingress 리소스에 정의된 각 쿠버네티스 서비스로 생성됩니다.
  • 4. Ingress 리소스 Annotationdp 명시된 모든 포트에 대한 리스너가 생성되며, 포트를 지정하지 않았을 경우 기본값(80,443)이 사용됩니다. 어노테이션을 통해 TLS 인증서 등록도 가능합니다.
  • 5. Ingress 리소스에 지정된 각 경로에 대한 규칙이 생성되고 이를 통해 특정 경로로 향하는 트래픽이 알맞은 서비스로 라우팅됩니다. ex) www.abc.com/products URL은 ServiceB(NodePort B)와 연결
주의사항 : EKS에서 정의된 Ingress 리소스를 삭제 시 AWS로 생성된 ELB도 삭제될 수 있어 신중히 삭제하는 것에 대해서 검토해야 한다.


Load Balancer Controller 권한 방식(IRSA vs EKS Pod Identity)

로드밸런서 컨트롤러에서 AWS 리소스를 생성하기 위해서는 해당 컨트롤러 파드에서 LB를 생성할 수 있는 정책 설정이 필요합니다. 대표적으로 사용할 수 있는 두가지 방식 IRSA(IAM Roles for Service Accounts)EKS Pod Identity입니다.

 

비교 IRSA Pod Identity
정의 IRSA는 OIDC(OpenID Connect) 기술을 기반으로 Kubernetes의 서비스 어카운트(Service Account)에 AWS IAM 역할을 매핑하는 전통적인 방식 EKS Pod Identity는 2023년 말에 AWS가 새롭게 출시한 기능으로, 기존 IRSA의 OIDC 관리 복잡성을 없애고 권한 부여를 획기적으로 단순화한 방식입니다.
작동 방식 EKS 클러스터에 대한 OIDC 자격 증명 공급자를 AWS IAM 콘솔에 생성합니다.

로드밸런서 컨트롤러용 IAM 역할을 생성하고, 신뢰 정책(Trust Policy)에 해당 OIDC를 통해 권한을 획득할 수 있도록 설정합니다.(Pod마다 Secondary IP를 부여받아 Policy도 개별로 적용 가능)

Kubernetes 서비스 어카운트에 IAM 역할의 ARN을 어노테이션(Annotation)으로 기입합니다.

Pod가 실행되면 OIDC 토큰이 컨테이너에 주입되고, 애플리케이션(AWS SDK)은 이 토큰을 AWS STS에 보내 임시 자격 증명을 받아옵니다.
EKS 클러스터에 'EKS Pod Identity Agent'라는 공식 애드온을 설치합니다 (노드마다 백그라운드 에이전트로 실행됨).

로드밸런서 컨트롤러용 IAM 역할을 생성합니다. 이때 신뢰 정책의 대상(Principal)을 pods.eks.amazonaws.com으로 아주 단순하게 설정합니다.

EKS 콘솔이나 AWS CLI를 통해 '어떤 클러스터의 어떤 네임스페이스/서비스 어카운트가 어떤 IAM 역할을 쓸 것인지' 직접 연결(Association)해 줍니다.

Pod Identity Agent가 컨테이너의 권한 요청을 중간에서 가로채서 안전하게 임시 자격 증명을 제공합니다.
장점 별도의 에이전트 설치 없이 EKS 기본 기능과 IAM OIDC 연동만으로 노드에 리소스를 사용하는 일이 없습니다.

기존 EKS에서 사용하던 방식으로 많은 레퍼런스 자료 존재
OIDC 자격 증명 공급자를 생성하고 관리할 필요가 전혀 없습니다.

하나의 IAM 역할을 만들어두면 여러 클러스터에서 쉽게 재사용할 수 있어 관리가 매우 편합니다.
단점 클러스터마다 고유한 OIDC 공급자가 있으므로, 클러스터를 새로 만들 때마다 OIDC를 연동하는 번거로움 존재

IAM 신뢰 정책을 복잡하게 수정해야 하는 번거로움
이 있습니다.
애드온 및 리소스 관리(버전 등) 필요

 

사전 확인

# OIDC Provider
aws iam list-open-id-connect-providers

aws eks describe-cluster --name myeks \
  --query "cluster.identity.oidc.issuer" \
  --output text
https://oidc.eks.ap-northeast-2.amazonaws.com/id/1BB80004FADD0C9E59C6641F386155BD

# public subnet 찾기
aws ec2 describe-subnets --filters "Name=tag:kubernetes.io/role/elb,Values=1" --output table

# private subnet 찾기
aws ec2 describe-subnets --filters "Name=tag:kubernetes.io/role/internal-elb,Values=1" --output table

 

AWS IAM Policy 생성

# IAM Policy json 파일 다운로드 
curl -o aws_lb_controller_policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/refs/heads/main/docs/install/iam_policy.json
cat aws_lb_controller_policy.json | jq

# Policy 생성
aws iam create-policy \
    --policy-name AWSLoadBalancerControllerIAMPolicy \
    --policy-document file://aws_lb_controller_policy.json

# 확인
ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)
aws iam get-policy --policy-arn arn:aws:iam::$ACCOUNT_ID:policy/AWSLoadBalancerControllerIAMPolicy | jq
아래 사항은 LBC 파드에서 AWS 서비스를 제어하기 위해 필요한 Policy입니다

 

정책 생성 확인

IRSA 생성

# IRSA 생성 : cloudforamtion 를 통해 IAM Role 생성
CLUSTER_NAME=myeks
eksctl get iamserviceaccount --cluster $CLUSTER_NAME
kubectl get serviceaccounts -n kube-system aws-load-balancer-controller

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

# 확인
eksctl get iamserviceaccount --cluster $CLUSTER_NAME

# k8s 에 SA 확인
# Inspecting the newly created Kubernetes Service Account, we can see the role we want it to assume in our pod.
kubectl get serviceaccounts -n kube-system aws-load-balancer-controller -o yaml
IRSA 생성 확인
IRSA 설정에서 IAM 역할을 참조(ARN)하고 있는 것을 확인할 수 있어야 합니다.

 

LBC Pod 배포 및 AWS Loadbalancer 프로비저닝

# Helm Chart Repository 추가
helm repo add eks https://aws.github.io/eks-charts
helm repo update

# Helm Chart - AWS Load Balancer Controller 설치
# https://artifacthub.io/packages/helm/aws/aws-load-balancer-controller
# https://github.com/aws/eks-charts/blob/master/stable/aws-load-balancer-controller/values.yaml
helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --version 3.1.0 \
  --set clusterName=$CLUSTER_NAME \
  --set serviceAccount.name=aws-load-balancer-controller \
  --set serviceAccount.create=false

# 확인
helm list -n kube-system

# 파드 상태 실패 확인
kubectl get pod -n kube-system -l app.kubernetes.io/name=aws-load-balancer-controller

# 로그 확인 : vpc id 정보 획득 실패!
kubectl logs -n kube-system deployment/aws-load-balancer-controller

 

VPC ID 정보 획득에 실패하여 LBC 서비스를 배포 실패가 발생하였습니다.

 

terraform show -json | jq -r '.values.root_module.child_modules[] | select(.address == "module.vpc") | .resources[] | select(.address == "module.vpc.aws_vpc.this[0]") | .values.id'


# helm chart 재배포
helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --version 3.1.0 \
  --set clusterName=myeks \
  --set serviceAccount.name=aws-load-balancer-controller \
  --set serviceAccount.create=false \
  --set region=ap-northeast-2 \
  --set vpcId=vpc-xxxxxxxxxxxxx
IMDSv2 필수 설정 확인 (메타데이터 옵션을 1 > 2 수정)
노드 > 노드 : Hop 1
노드 > 파드 : Hop 2 ( 노드 > 노드 - 파드 )
1로 설정 시 노드에 네트워크 인터페이스까지만 도달할 뿐 파드로 정상적으로 접속이 불가능합니다.
# 디플로이먼트 리스타트!
kubectl rollout restart -n kube-system deploy aws-load-balancer-controller

# 파드 상태 확인
kubectl get pod -n kube-system -l app.kubernetes.io/name=aws-load-balancer-controller

# crd 확인
kubectl get crd | grep -E 'elb|gateway'

kubectl explain ingressclassparams.elbv2.k8s.aws
kubectl explain ingressclassparams.elbv2.k8s.aws.spec
kubectl explain ingressclassparams.elbv2.k8s.aws.spec.listeners
kubectl explain targetgroupbindings.elbv2.k8s.aws.spec
kubectl explain albtargetcontrolconfigs.elbv2.k8s.aws.spec

# AWS Load Balancer Controller 확인
kubectl get deployment -n kube-system aws-load-balancer-controller
kubectl describe deploy -n kube-system aws-load-balancer-controller
kubectl describe deploy -n kube-system aws-load-balancer-controller | grep 'Service Account'

# 클러스터롤, 롤 확인
kubectl describe clusterrolebindings.rbac.authorization.k8s.io aws-load-balancer-controller-rolebinding
kubectl describe clusterroles.rbac.authorization.k8s.io aws-load-balancer-controller-role

 

서비스 및 파드 배포

# 모니터링
watch -d kubectl get pod,svc,ep,endpointslices

# 디플로이먼트 & 서비스 생성
cat << EOF > echo-service-nlb.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-echo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: deploy-websrv
  template:
    metadata:
      labels:
        app: deploy-websrv
    spec:
      terminationGracePeriodSeconds: 0
      containers:
      - name: aews-websrv
        image: k8s.gcr.io/echoserver:1.10 
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: svc-nlb-ip-type
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
    service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
    service.beta.kubernetes.io/aws-load-balancer-healthcheck-port: "8080"
    service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
spec:
  allocateLoadBalancerNodePorts: false
  ports:
    - port: 80
      targetPort: 8080
      protocol: TCP
  type: LoadBalancer
  selector:
    app: deploy-websrv
EOF

kubectl apply -f echo-service-nlb.yaml


# 확인
aws elbv2 describe-load-balancers --query 'LoadBalancers[*].State.Code' --output text
kubectl get deploy,pod
kubectl get svc,ep,ingressclassparams,targetgroupbindings
kubectl get targetgroupbindings -o json
네트워크 로드밸런서 프로비저닝 확인
노드 내 Pod와 NLB에 타겟그룹으로 매핑된 것을 확인할 수 있다.

 

EKS - Ingress

인그레스는 클러스터 내부의 서비스인 Cluster IP, NodePort, Loadbalancer를 외부로 노출시키는 Web Proxy 역할을 수행합니다.

AWS VPC CNI에서의 Ingress가 Pod IP로 직접 통신

Ingress Traffic 모드

  • Instance 모드 : 기본 모드로 동작하며 Ingress Traffic은 ALB에서 시작하여 각 서비스의 NodePort를 통해 쿠버네티스 노드에 도달합니다. 즉, 인그레스 리소스에서 참조되는 서비스는 ALB에 접근할 수 있도록 type:NodePort가 노출되어야 합니다.
  • IP 모드 : 해당 모드에서 Ingress Traffic은 ALB에서 시작하여 Kubernetes Pod에 직접 도달합니다. CNI는 ENI의 Secondary IP를 통해 Pod IP에 접근할 수 있도록 지원해야 합니다.(AWS VPC CNI를 기본 네트워크 구성으로 사용하여 가능)

 

Ingress annotations - 참고

 

Annotations - AWS Load Balancer Controller

Ingress annotations You can add annotations to kubernetes Ingress and Service objects to customize their behavior. Annotation keys and values can only be strings. Advanced format should be encoded as below: boolean: 'true' integer: '42' stringList: s1,s2,s

kubernetes-sigs.github.io

 

Annotataion 명칭 유형 기본 설정 값
(Default)
Location MergeBehavior
alb.ingress.kubernetes.io/load-balancer-name string N/A Ingress Exclusive
alb.ingress.kubernetes.io/group.name string N/A Ingress N/A
alb.ingress.kubernetes.io/group.order integer 0 Ingress N/A
alb.ingress.kubernetes.io/tags stringMap N/A Ingress,Service Merge
alb.ingress.kubernetes.io/ip-address-type ipv4 | dualstack | dualstack-without-public-ipv4 ipv4 Ingress Exclusive
alb.ingress.kubernetes.io/scheme internal | internet-facing internal Ingress Exclusive
alb.ingress.kubernetes.io/subnets stringList N/A Ingress Exclusive
alb.ingress.kubernetes.io/security-groups stringList N/A Ingress Exclusive
alb.ingress.kubernetes.io/manage-backend-security-group-rules boolean N/A Ingress Exclusive
alb.ingress.kubernetes.io/customer-owned-ipv4-pool string N/A Ingress Exclusive
alb.ingress.kubernetes.io/load-balancer-attributes stringMap N/A Ingress Exclusive
alb.ingress.kubernetes.io/wafv2-acl-arn string N/A Ingress Exclusive
alb.ingress.kubernetes.io/waf-acl-id string N/A Ingress Exclusive
alb.ingress.kubernetes.io/shield-advanced-protection boolean N/A Ingress Exclusive
alb.ingress.kubernetes.io/listen-ports json '[{"HTTP": 80}]' | '[{"HTTPS": 443}]' Ingress Merge
alb.ingress.kubernetes.io/ssl-redirect integer N/A Ingress Exclusive
alb.ingress.kubernetes.io/inbound-cidrs stringList 0.0.0.0/0, ::/0 Ingress Exclusive
alb.ingress.kubernetes.io/security-group-prefix-lists stringList pl-00000000, pl-1111111 Ingress Exclusive
alb.ingress.kubernetes.io/certificate-arn stringList N/A Ingress Merge
alb.ingress.kubernetes.io/ssl-policy string ELBSecurityPolicy-2016-08 Ingress Exclusive
alb.ingress.kubernetes.io/target-type instance | ip instance Ingress,Service N/A
alb.ingress.kubernetes.io/backend-protocol HTTP | HTTPS HTTP Ingress,Service N/A
alb.ingress.kubernetes.io/backend-protocol-version string HTTP1 Ingress,Service N/A
alb.ingress.kubernetes.io/target-group-attributes stringMap N/A Ingress,Service N/A
alb.ingress.kubernetes.io/healthcheck-port integer | traffic-port traffic-port Ingress,Service N/A
alb.ingress.kubernetes.io/healthcheck-protocol HTTP | HTTPS HTTP Ingress,Service N/A
alb.ingress.kubernetes.io/healthcheck-path string / | /AWS.ALB/healthcheck Ingress,Service N/A
alb.ingress.kubernetes.io/healthcheck-interval-seconds integer '15' Ingress,Service N/A
alb.ingress.kubernetes.io/healthcheck-timeout-seconds integer '5' Ingress,Service N/A
alb.ingress.kubernetes.io/healthy-threshold-count integer '2' Ingress,Service N/A
alb.ingress.kubernetes.io/unhealthy-threshold-count integer '2' Ingress,Service N/A
alb.ingress.kubernetes.io/success-codes string '200' | '12' Ingress,Service N/A
alb.ingress.kubernetes.io/auth-type none|oidc|cognito none Ingress,Service N/A
alb.ingress.kubernetes.io/auth-idp-cognito json N/A Ingress,Service N/A
alb.ingress.kubernetes.io/auth-idp-oidc json N/A Ingress,Service N/A
alb.ingress.kubernetes.io/auth-on-unauthenticated-request authenticate|allow|deny authenticate Ingress,Service N/A
alb.ingress.kubernetes.io/auth-scope string openid Ingress,Service N/A
alb.ingress.kubernetes.io/auth-session-cookie string AWSELBAuthSessionCookie Ingress,Service N/A
alb.ingress.kubernetes.io/auth-session-timeout integer '604800' Ingress,Service N/A
alb.ingress.kubernetes.io/jwt-validation json N/A Ingress N/A
alb.ingress.kubernetes.io/actions.${action-name} json N/A Ingress N/A
alb.ingress.kubernetes.io/transforms.${transforms-name} json N/A Ingress N/A
alb.ingress.kubernetes.io/conditions.${conditions-name} json N/A Ingress N/A
alb.ingress.kubernetes.io/use-regex-path-match boolean N/A Ingress false
alb.ingress.kubernetes.io/target-node-labels stringMap N/A Ingress,Service N/A
alb.ingress.kubernetes.io/mutual-authentication json N/A Ingress Exclusive
alb.ingress.kubernetes.io/multi-cluster-target-group boolean N/A Ingress, Service N/A
alb.ingress.kubernetes.io/listener-attributes.${Protocol}-${Port} stringMap N/A Ingress Merge
alb.ingress.kubernetes.io/minimum-load-balancer-capacity stringMap N/A Ingress Exclusive
alb.ingress.kubernetes.io/ipam-ipv4-pool-id string N/A Ingress Exclusive
alb.ingress.kubernetes.io/enable-frontend-nlb boolean false Ingress Exclusive
alb.ingress.kubernetes.io/frontend-nlb-scheme internal | internet-facing internal Ingress Exclusive
alb.ingress.kubernetes.io/frontend-nlb-subnets stringList N/A Ingress Exclusive
alb.ingress.kubernetes.io/frontend-nlb-security-groups stringList N/A Ingress Exclusive
alb.ingress.kubernetes.io/frontend-nlb-listener-port-mapping stringMap N/A Ingress Merge
alb.ingress.kubernetes.io/frontend-nlb-healthcheck-port integer | traffic-port traffic-port Ingress N/A
alb.ingress.kubernetes.io/frontend-nlb-healthcheck-protocol HTTP | HTTPS HTTP Ingress N/A
alb.ingress.kubernetes.io/frontend-nlb-healthcheck-path string / Ingress N/A
alb.ingress.kubernetes.io/frontend-nlb-healthcheck-interval-seconds integer 15 Ingress N/A
alb.ingress.kubernetes.io/frontend-nlb-healthcheck-timeout-seconds integer 5 Ingress N/A
alb.ingress.kubernetes.io/frontend-nlb-healthcheck-healthy-threshold-count integer 3 Ingress N/A
alb.ingress.kubernetes.io/frontend-nlb-healthcheck-unhealthy-threshold-count integer 3 Ingress N/A
alb.ingress.kubernetes.io/frontend-nlb-healthcheck-success-codes string 200 Ingress N/A
alb.ingress.kubernetes.io/frontend-nlb-tags stringMap N/A Ingress Exclusive
alb.ingress.kubernetes.io/frontend-nlb-eip-allocations stringList 200 Ingress N/A
alb.ingress.kubernetes.io/target-control-port.${serviceName}.${servicePort} integer N/A Ingress N/A

 

ALB를 통한 Ingress 서비스 노출 및 파드/노드 연결 확인

# 게임 파드와 Service, Ingress 배포
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Namespace
metadata:
  name: game-2048
---
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: game-2048
  name: deployment-2048
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: app-2048
  replicas: 2
  template:
    metadata:
      labels:
        app.kubernetes.io/name: app-2048
    spec:
      containers:
      - image: public.ecr.aws/l6m2t8p7/docker-2048:latest
        imagePullPolicy: Always
        name: app-2048
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  namespace: game-2048
  name: service-2048
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  type: NodePort
  selector:
    app.kubernetes.io/name: app-2048
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  namespace: game-2048
  name: ingress-2048
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
spec:
  ingressClassName: alb
  rules:
    - http:
        paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: service-2048
              port:
                number: 80
EOF

ALB 프로비저닝 확인
NLB와 다르게 규칙이라는게 있음
규칙 - /로 들어오는 트래픽은 모두 TargetGroup으로 전달

# 모니터링
watch -d kubectl get pod,ingress,svc,ep,endpointslices -n game-2048

# 생성 확인(kubectl)
kubectl get ingressclass
kubectl get ingress,svc,ep,pod -n game-2048
kubectl get-all -n game-2048
kubectl get targetgroupbindings -n game-2048

# ALB 생성 확인(awscli)
aws elbv2 describe-load-balancers --query 'LoadBalancers[?contains(LoadBalancerName, `k8s-game2048`) == `true`]' | jq
ALB_ARN=$(aws elbv2 describe-load-balancers --query 'LoadBalancers[?contains(LoadBalancerName, `k8s-game2048`) == `true`].LoadBalancerArn' | jq -r '.[0]')
aws elbv2 describe-target-groups --load-balancer-arn $ALB_ARN
TARGET_GROUP_ARN=$(aws elbv2 describe-target-groups --load-balancer-arn $ALB_ARN | jq -r '.TargetGroups[0].TargetGroupArn')
aws elbv2 describe-target-health --target-group-arn $TARGET_GROUP_ARN | jq

# Ingress 확인
kubectl describe ingress -n game-2048 ingress-2048
kubectl get ingress -n game-2048 ingress-2048 -o jsonpath="{.status.loadBalancer.ingress[*].hostname}{'\n'}"

ALB 프로비저닝 확인
엔드포인트 확인
타겟그룹 바인딩 확인

# 게임 접속 : ALB 주소로 웹 접속
kubectl get ingress -n game-2048 ingress-2048 -o jsonpath='{.status.loadBalancer.ingress[0].hostname}' | awk '{ print "Game URL = http://"$1 }'

# 파드 IP 확인
kubectl get pod -n game-2048 -owide

ALB Endpoint URL 접속 확인