목차
AWS Ingress Controller 설치
- 서브넷에 태그달기
- AWS loadBalancer Controller가 사용할 IAM 정책과 역할 만들기
- EKS Cluster 반영
- 확인해보기
ALB 생성 확인해보기
- ALB 생성 트러블 슈팅
- NLB를 생성해보자
- 노드그룹과 fargate의 차이
AWS Ingress Controller 설치
AWS loadBalancer Controller 를 설치하면 pod 의 형태로 컨트롤러가 생성되는데, 얘가 설치되는 건 문제가 안되지만 LB 를 만드는 동작을 하는데 권한과 lb 가 올라갈 서브넷 등에 설정이 필요하기 때문에 선행작업으로 진행 후 eks 에 AWS loadBalancer Controller 를 설치하도록 한다.
설치 과정
- 서브넷에 태그달기
- AWS loadBalancer Controller가 사용할 IAM 정책과 역할 만들기
- EKS에 IAM 적용하고 컨트롤러 설치하기
AWS 공식 가이드
AWS Load Balancer Controller 추가 기능 설치 - Amazon EKS
AWS Load Balancer Controller 추가 기능 설치 - Amazon EKS
배포된 차트는 보안 업데이트를 자동으로 수신하지 않습니다. 새 차트가 사용 가능해지면 수동으로 업그레이드해야 합니다. 업그레이드 시 이전 명령에서 install을 upgrade로 변경하되, 이전 명령
docs.aws.amazon.com
서브넷에 태그달기
컨트롤러가 NLB 혹은 ALB 가 올라갈 서브넷을 확인할 수 있게 서브넷에 태그를 아래와 같이 달아주어야 한다.
기본
- 키 - kubernetes.io/cluster/*my-cluster*
- 값 - shared 또는 owned
퍼블릭 서브넷
- 키 - kubernetes.io/role/elb
- 값 - 1
프라이빗 서브넷
- 키 - kubernetes.io/role/internal-elb
- 값 - 1
예시)

AWS loadBalancer Controller가 사용할 IAM 정책과 역할 만들기
AWS Loadbalancer Controller 정책 생성
# 정책 이름 예시 : AWSLoadBalancerControllerIAMPolicy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iam:CreateServiceLinkedRole",
"ec2:DescribeAccountAttributes",
"ec2:DescribeAddresses",
"ec2:DescribeInternetGateways",
"ec2:DescribeVpcs",
"ec2:DescribeSubnets",
"ec2:DescribeSecurityGroups",
"ec2:DescribeInstances",
"ec2:DescribeNetworkInterfaces",
"ec2:DescribeAvailabilityZones",
"ec2:DescribeTags",
"ec2:GetCoipPoolUsage",
"ec2:DescribeCoipPools",
"elasticloadbalancing:DescribeLoadBalancers",
"elasticloadbalancing:DescribeLoadBalancerAttributes",
"elasticloadbalancing:DescribeListeners",
"elasticloadbalancing:DescribeListenerCertificates",
"elasticloadbalancing:DescribeSSLPolicies",
"elasticloadbalancing:DescribeRules",
"elasticloadbalancing:DescribeTargetGroups",
"elasticloadbalancing:DescribeTargetGroupAttributes",
"elasticloadbalancing:DescribeTargetHealth",
"elasticloadbalancing:DescribeTags",
"elasticloadbalancing:AddTags"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"cognito-idp:DescribeUserPoolClient",
"acm:ListCertificates",
"acm:DescribeCertificate",
"iam:ListServerCertificates",
"iam:GetServerCertificate",
"waf-regional:GetWebACL",
"waf-regional:GetWebACLForResource",
"waf-regional:AssociateWebACL",
"waf-regional:DisassociateWebACL",
"wafv2:GetWebACL",
"wafv2:GetWebACLForResource",
"wafv2:AssociateWebACL",
"wafv2:DisassociateWebACL",
"shield:GetSubscriptionState",
"shield:DescribeProtection",
"shield:CreateProtection",
"shield:DeleteProtection"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ec2:AuthorizeSecurityGroupIngress",
"ec2:RevokeSecurityGroupIngress"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ec2:CreateSecurityGroup"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ec2:CreateTags"
],
"Resource": "arn:aws:ec2:*:*:security-group/*",
"Condition": {
"StringEquals": {
"ec2:CreateAction": "CreateSecurityGroup"
},
"Null": {
"aws:RequestTag/elbv2.k8s.aws/cluster": "false"
}
}
},
{
"Effect": "Allow",
"Action": [
"ec2:CreateTags",
"ec2:DeleteTags"
],
"Resource": "arn:aws:ec2:*:*:security-group/*",
"Condition": {
"Null": {
"aws:RequestTag/elbv2.k8s.aws/cluster": "true",
"aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
}
}
},
{
"Effect": "Allow",
"Action": [
"ec2:AuthorizeSecurityGroupIngress",
"ec2:RevokeSecurityGroupIngress",
"ec2:DeleteSecurityGroup"
],
"Resource": "*",
"Condition": {
"Null": {
"aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
}
}
},
{
"Effect": "Allow",
"Action": [
"elasticloadbalancing:CreateLoadBalancer",
"elasticloadbalancing:CreateTargetGroup"
],
"Resource": "*",
"Condition": {
"Null": {
"aws:RequestTag/elbv2.k8s.aws/cluster": "false"
}
}
},
{
"Effect": "Allow",
"Action": [
"elasticloadbalancing:CreateListener",
"elasticloadbalancing:DeleteListener",
"elasticloadbalancing:CreateRule",
"elasticloadbalancing:DeleteRule"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"elasticloadbalancing:AddTags",
"elasticloadbalancing:RemoveTags"
],
"Resource": [
"arn:aws:elasticloadbalancing:*:*:targetgroup/*/*",
"arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*",
"arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*"
],
"Condition": {
"Null": {
"aws:RequestTag/elbv2.k8s.aws/cluster": "true",
"aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
}
}
},
{
"Effect": "Allow",
"Action": [
"elasticloadbalancing:ModifyLoadBalancerAttributes",
"elasticloadbalancing:SetIpAddressType",
"elasticloadbalancing:SetSecurityGroups",
"elasticloadbalancing:SetSubnets",
"elasticloadbalancing:DeleteLoadBalancer",
"elasticloadbalancing:ModifyTargetGroup",
"elasticloadbalancing:ModifyTargetGroupAttributes",
"elasticloadbalancing:DeleteTargetGroup"
],
"Resource": "*",
"Condition": {
"Null": {
"aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
}
}
},
{
"Effect": "Allow",
"Action": [
"elasticloadbalancing:RegisterTargets",
"elasticloadbalancing:DeregisterTargets"
],
"Resource": "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*"
},
{
"Effect": "Allow",
"Action": [
"elasticloadbalancing:SetWebAcl",
"elasticloadbalancing:ModifyListener",
"elasticloadbalancing:AddListenerCertificates",
"elasticloadbalancing:RemoveListenerCertificates",
"elasticloadbalancing:ModifyRule"
],
"Resource": "*"
}
]
}
alb 를 생성하고 태그를 조절하는 등의 권한이 포함되어 있다.
AWS 에서 제안하는 정책을 다운받는 경우, 가끔 ec2:DescribeAvailabilityZones 권한이나 elasticloadbalancing:AddTags 권한이 없다고 에러가 날 수 있다. 그런 경우 IAM 정책에서 슬쩍 추가해주면 문제가 해결된다.
만약 콘솔에서 만들기가 귀찮다면, 위 내용을 파일명 iam_policy.json로 만들고, 아래 명령어로 생성가능하다.
생성 명령어
aws iam create-policy \
--policy-name AWSLoadBalancerControllerIAMPolicy \
--policy-document file://iam_policy.json
AWS Loadbalancer Controller 역할 생성
이제 클러스터가 aws 에 접근해서 동작할 때 적용될 역할을 생성할 차례이다.
클러스터 콘솔에 가서 oidc를 확인한다.

그리고 IAM 콘솔에서 role 생성을 진행하는데, Web Identity → 에서 위에서 확인한 oidc 를 체크한다.

아까 생성한 정책을 가지고 role 을 생성하면 된다.

신뢰관계에서 내용을 조금 수정한다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::111122223333:oidc-provider/oidc.eks.region-code.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.region-code.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:aud": "sts.amazonaws.com",
"oidc.eks.region-code.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:sub": "system:serviceaccount:kube-system:aws-load-balancer-controller"
}
}
}
]
}
신뢰관계에서 보면, aud와 sub 이 있다.
- aud (audience) : 토큰이 발급된 대상이다. 여기선 aws 가 토큰을 발급한 대상이며, 이 토큰은 aws sts에 대한 요청을 인증하는 데 사용된다.
- sub (subject) : 토큰의 주체이다. k8s 시스템의 ns= kube-system 이며, 이름이 aws-load-balancer-controller 인 serviceaccount 가 접근하는 경우에 허용한다.
IAM Role ARN 복사
serviceaccount 에 적용하기 위하여 생성이 완료된 역할의 arn 을 복사해 둔다.
EKS Cluster 반영
service account 생성
이제 클러스터에 접근해서 만들어둔 role 이 클러스터에서 사용되는 계정으로 적용되게끔 serviceaccount 를 생성해 준다. 이때 위에서 복사했던 arn 을 붙여준다.
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/name: aws-load-balancer-controller
name: aws-load-balancer-controller
namespace: kube-system
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::111122223333:role/AmazonEKSLoadBalancerControllerRole
Helm 으로 컨트롤러 설치
만약 헬름이 설치 되어 있지 않다면 먼저 설치 해준다.
아래 명령어로 생성할 수 있다.
helm repo add eks https://aws.github.io/eks-charts
helm repo update eks
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=my-cluster \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller
helm ls
helm delete aws-load-balancer-controller
확인해보기
kubectl get deployment -n kube-system aws-load-balancer-controller
kubectl get ingressclass -A # ingressclass 가 alb 로 생성되어 있다.
ALB 생성 확인해보기
위에서 컨트롤러를 설치했다면, 이제 ingress 를 생성하면, 컨트롤러가 alb 를 aws 에 생성해 줄 것이다. 맞게 설정이 되어 있는지 한번 생성해서 테스트 해보자.
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.5.4/docs/examples/2048/2048_full.yaml
위 경로의 상세 내용은 아래와 같다.
---
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: 5
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: 80kubectl apply -f 2048_full.yaml
이 내용에서 포인트를 몇개 집어보자면,
- Namespace 생성 → Deployment가 생성한 Namespace에 생성된다. → Service는 Deployment에서 작성한 Pod의 label를 선택한다. → Ingress 는 생성한 Service로 보낸다.
- 컨트롤러가 Ingress 의 내용을 읽어 ALB 로 만든다. Ingress 의 내용이 http, paths 등으로 룰을 만들어 L7과 같이 분기를 한다.
- service의 내용은 간단.
- Ingress 개수로 alb 가 생성된다.
- Ingress의 타겟타입이 ip인데 service의 타입이 노드포트다. → 생성은 되지만, 사실상 clusterip 와 동일한 구성으로 생성된다.

** 다양한 옵션으로 ALB와 NLB 를 조절할 수 있는데, 그걸 어노테이션으로 조절한다. 어노테이션은 아래 링크에서 자세히 확인할 수 있다.
Annotations - AWS Load Balancer Controller
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
** 샘플 예제 출처 :
Amazon EKS 애플리케이션 로드 밸런싱 - Amazon EKS
Amazon EKS 애플리케이션 로드 밸런싱 - Amazon EKS
IPv6 Pods로 로드 밸런싱하는 경우, 인그레스 사양에 다음 주석을 추가합니다. IPv6를 통해서는 인스턴스 대상이 아닌 IP 대상으로만 로드 밸런싱할 수 있습니다. 이 주석이 없으면 로드 밸런싱은 IPv
docs.aws.amazon.com
ALB 생성 트러블슈팅
AWS LBC 로 LB 생성 이슈가 있을 때, 아래 4가지 경우를 먼저 살펴보자(겪어본 이슈들)
- 권한 문제 → iam
- 서브넷을 찾지 못함 → 태그
- 타겟 매핑을 못함 → 포트
- 맞는 서브넷을 사용하지 못함 → helm 설치시 이름 잘못 기입
NLB 를 생성해보자
NLB를 생성하는 경우에는 Ingress 를 참고하지 않고 service 의 loadbalancer 타입으로 자체적으로 동작해서 service의 어노테이션이 화려해진다.
---
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: 5
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
annotations:
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
type: LoadBalancer
selector:
app.kubernetes.io/name: app-2048
노드그룹과 fargate 의 차이
fargate는 인스턴스 타입이 불가능하다. 따라서 IP 타입만 선택할 수 있다
반면, 노드그룹은 인스턴스 타입과 ip 타입을 모두 선택할 수 있다. 다만, 인스턴스 타입을 선택할 경우 무조건 nodeport 를 사용해야 한다.
'가시다님 AEWS' 카테고리의 다른 글
| [가시다's AEWS] 2주차 EKS Networking (0) | 2024.03.17 |
|---|---|
| [가시다's AEWS] 1주차 Terraform 으로 Fargate Only EKS Cluster 배포해보기 (0) | 2024.03.09 |
| [가시다's AEWS] 1주차 EKS Cluster 소개와 콘솔 설치 (0) | 2024.03.08 |
















