블로그 불러오는 중...
문의 보내기
남겨주면 블로그 주인에게 바로 전달돼요.
오늘은 EKS Workshop 실습을 해 본다.
공식 워크샵 링크를 클릭하면 실습을 따라 해 볼 수 있다.
하지만 처음에 이 링크만 보고 바로 시작하려다 보니 많이 헤맸다. 본격적인 실습에 앞서 먼저 환경 셋팅을 진행해야 한다.
본인의 AWS 계정으로 자원을 만들어 실습하는 기본적인 방법은 아래 가이드 링크에서 확인할 수 있다.
아래는 가이드 페이지의 캡쳐 사진이다

나는 하단의 링크를 통해 실습용 자원을 직접 생성했다. (us-west-2 리전 기준)
👉 us-west-2 리전 생성: Launch Stack
AWS에 로그인한 상태에서 위 링크를 클릭하면 CloudFormation 생성 화면이 나온다.

화면 하단에서 동의에 체크하고 스택을 생성한다. 내 경우 스택이 모두 만들어지는 데 약 8분 정도가 소요되었다.
자원 생성이 완료되었으면, CloudFormation의 '출력(Outputs)' 탭에 들어가서 출력된 결과를 확인한다.

출력된 키값 중에서 IdePasswordSecret이라고 적힌 Secrets Manager 링크를 클릭하여 접속한다.

해당 링크로 접속 시 나오는 보안 암호 값을 복사한다. (빨간 상자로 표시된 복사 버튼을 누르면 된다.)
이후 다시 CloudFormation 출력 탭으로 돌아와, 이번에는 IdeUrl이라고 적힌 링크로 접속한 뒤 방금 복사한 비밀번호를 입력해 준다.

비밀번호를 입력하고 들어가면 웹 브라우저 화면에 VS Code가 나타난다. 이제 하단 터미널에 아래 명령어를 입력하여 EKS 쿠버네티스 환경을 셋팅한다.
export EKS_CLUSTER_NAME=eks-workshop
curl -fsSL https://raw.githubusercontent.com/aws-samples/eks-workshop-v2/stable/cluster/eksctl/cluster.yaml | \
envsubst | eksctl create cluster -f -
위 사진과 같이 입력해 준 다음 클러스터 생성이 완료 될 때가지 기다린다(약 20분 소요) 여기까지 잘 따라왔다면 EKS Workshop을 진행하기 위한 기본 셋팅은 모두 마무리되었다.
이제 본격적인 실습을 진행해 보면 된다.
https://www.eksworkshop.com/docs/troubleshooting/alb/ 페이지로 접속 해 본다.
시작 전 명령어를 입력하라고 한다, 우리도 입력해서 실습 환경을 구축한다.
prepare-environment troubleshooting/alb해당 명령어를 입력하게 되면 아래와 같은 사진이 나오면서 기본 환경을 셋팅 해 준다.

AWS 로드 밸런서 컨트롤러가 인그레스 리소스에 대한 애플리케이션 로드 밸런서(ALB)를 생성하지 못하는 이유를 조사하는 것이 이번 실습의 목표이다.

kubectl get pod -n ui 명령어를 이용해 ui 네임스페이스에 pod 를 확인해 본다.
ec2-user:~/environment:$ kubectl get pod -n ui
NAME READY STATUS RESTARTS AGE
ui-5989474687-nlgj6 1/1 Running 0 72s파드는 정상적으로 동작중인 것을 볼 수 있다.
kubectl get ingress/ui -n ui 명령어를 이용해 ingress 도 확인 해 본다.
ec2-user:~/environment:$ kubectl get ingress/ui -n ui
NAME CLASS HOSTS ADDRESS PORTS AGE
ui alb * 80 113s정상적인 경우엔 주소에 alb 주소가 나와야 하는데 나오지 않아 문제가 있는 것을 확인 할 수 있다.
kubectl describe ingress/ui -n ui 명령어를 이용해 상태를 확인한다.
문제의 원인은 로드밸런서가 생성될 서브넷은 태그가 있어야 하는데, 찾지를 못해서 생기는 이슈이다.
aws ec2 describe-subnets --filters "Name=tag:alpha.eksctl.io/cluster-name,Values=${EKS_CLUSTER_NAME}" --query 'Subnets[].SubnetId[]' 명령어로 서브넷을 확인해 본다.
ec2-user:~/environment:$ aws ec2 describe-subnets --filters "Name=tag:alpha.eksctl.io/cluster-name,Values=${EKS_CLUSTER_NAME}" --query 'Subnets[].SubnetId[]'
[
"subnet-097baf0c8c8fd6492",
"subnet-00f89ccad467dcfb4",
"subnet-0d25b9ede0b0ccead",
"subnet-03601fc2cd885d785",
"subnet-0aa1a833fa35e9c21",
"subnet-08e2092879cd35dfd"
]어느 서브넷이 Public subnet 인지 확인 해본다. 아래 명령어로 확인한다.
for subnet_id in $(aws ec2 describe-subnets --filters "Name=tag:alpha.eksctl.io/cluster-name,Values=${EKS_CLUSTER_NAME}" --query 'Subnets[].SubnetId[]' --output text); do \
echo "Subnet: ${subnet_id}"; \
aws ec2 describe-route-tables --filters "Name=association.subnet-id,Values=${subnet_id}" \
--query 'RouteTables[].Routes[].[DestinationCidrBlock,GatewayId]' --output text; \
done
위 사진과 같은 결과가 나오는데, 0.0.0.0/0 이 igw 로 연결된 것이 퍼블릭 서브넷이다.
태그가 있는지 한번 확인 해 본다
aws ec2 describe-subnets --filters 'Name=tag:kubernetes.io/role/elb,Values=1' --query 'Subnets[].SubnetId'
해당 태그가 있는 서브넷이 없다. 아래와 같이 태그 값을 만들어 준다. 위의 public subnet 값을 변경해서 입력하도록 한다.
aws ec2 create-tags --resources subnet-097baf0c8c8fd6492 subnet-0d25b9ede0b0ccead subnet-0aa1a833fa35e9c21 \
--tags 'Key="kubernetes.io/role/elb",Value=1'aws ec2 describe-subnets --filters 'Name=tag:kubernetes.io/role/elb,Values=1' --query 'Subnets[].SubnetId' 로 확인한다.
ec2-user:~/environment:$ aws ec2 describe-subnets --filters 'Name=tag:kubernetes.io/role/elb,Values=1' --query 'Subnets[].SubnetId'
[
"subnet-097baf0c8c8fd6492",
"subnet-0d25b9ede0b0ccead",
"subnet-0aa1a833fa35e9c21"
]정상 적용이 된 것을 확인 가능하다.
kubectl -n kube-system rollout restart deploy aws-load-balancer-controller 로 재시작한다.
추가로 다시 ingress 확인한다. kubectl describe ingress/ui -n ui 명령어를 입력한다.
위와 같이 권한 문제가 나왔다. 권한 문제를 아래서 해결 해 보자.
kubectl get serviceaccounts -n kube-system -l app.kubernetes.io/name=aws-load-balancer-controller -o yaml 명령어를 기용해 ServiceAccount 를 확인한다.
ec2-user:~/environment:$ kubectl get serviceaccounts -n kube-system -l app.kubernetes.io/name=aws-load-balancer-controller -o yaml
apiVersion: v1
items:
- apiVersion: v1
automountServiceAccountToken: true
kind: ServiceAccount
metadata:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::975372933996:role/alb-controller-20260418125456121100000003
meta.helm.sh/release-name: aws-load-balancer-controller
meta.helm.sh/release-namespace: kube-system
creationTimestamp: "2026-04-18T12:55:00Z"
labels:
app.kubernetes.io/instance: aws-load-balancer-controller
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: aws-load-balancer-controller
app.kubernetes.io/version: v2.7.1
helm.sh/chart: aws-load-balancer-controller-1.7.1
name: aws-load-balancer-controller-sa
namespace: kube-system
resourceVersion: "3195"
uid: f636d808-c433-432c-9b4a-37b97d2b55b2
kind: List
metadata:
resourceVersion: ""eks.amazonaws.com/role-arn: arn:aws:iam::975372933996:role/alb-controller-20260418125456121100000003 해당 롤을 가지고 있는데, 해당 롤에 권한이 없다.
사전 정의 된 환경변수가 있어서 아래 명령어를 사용해서 role 에 policy 를 붙여 준다.
aws iam attach-role-policy \
--role-name ${LOAD_BALANCER_CONTROLLER_ROLE_NAME} \
--policy-arn ${LOAD_BALANCER_CONTROLLER_POLICY_ARN_FIX}kubectl -n kube-system rollout restart deploy aws-load-balancer-controller 로 ALB Controller 를 재시작한다.
ALB 생성까지는 시간이 조금 소요되므로, 조금 기다렸다가 kubectl get ingress -n ui 명령어를 입력해 ALB 가 제대로 바인딩 되었는지 확인한다.
해당 트러블 슈팅은 다음과 같이 마무리 되었다.
위에 alb 주소로 접속하게 되면 아래와 같은 사진을 볼 수 있다. 뭔가 정상적이지 않다.

서비스를 확인 해 본다.
kubectl -n ui get service/ui -o yaml
ec2-user:~/environment:$ kubectl -n ui get service/ui -o yaml
apiVersion: v1
kind: Service
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app.kubernetes.io/component":"service","app.kubernetes.io/created-by":"eks-workshop","app.kubernetes.io/instance":"ui","app.kubernetes.io/managed-by":"Helm","app.kubernetes.io/name":"ui","helm.sh/chart":"ui-0.0.1"},"name":"ui","namespace":"ui"},"spec":{"ports":[{"name":"http","port":80,"protocol":"TCP","targetPort":"http"}],"selector":{"app.kubernetes.io/component":"service","app.kubernetes.io/instance":"ui","app.kubernetes.io/name":"ui-app"},"type":"ClusterIP"}}
creationTimestamp: "2026-04-18T12:52:40Z"
labels:
app.kubernetes.io/component: service
app.kubernetes.io/created-by: eks-workshop
app.kubernetes.io/instance: ui
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: ui
helm.sh/chart: ui-0.0.1
name: ui
namespace: ui
resourceVersion: "3403"
uid: d3713ac0-6eb6-4150-954e-319ab00eedb4
spec:
clusterIP: 172.16.81.69
clusterIPs:
- 172.16.81.69
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
selector:
app.kubernetes.io/component: service
app.kubernetes.io/instance: ui
app.kubernetes.io/name: ui-app
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}인그레스도 확인 해 본다.
kubectl get ingress/ui -n ui -o yaml
ec2-user:~/environment:$ kubectl get ingress/ui -n ui -o yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
alb.ingress.kubernetes.io/healthcheck-path: /actuator/health/liveness
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"networking.k8s.io/v1","kind":"Ingress","metadata":{"annotations":{"alb.ingress.kubernetes.io/healthcheck-path":"/actuator/health/liveness","alb.ingress.kubernetes.io/scheme":"internet-facing","alb.ingress.kubernetes.io/target-type":"ip"},"name":"ui","namespace":"ui"},"spec":{"ingressClassName":"alb","rules":[{"http":{"paths":[{"backend":{"service":{"name":"service-ui","port":{"number":80}}},"path":"/","pathType":"Prefix"}]}}]}}
creationTimestamp: "2026-04-18T12:55:34Z"
finalizers:
- ingress.k8s.aws/resources
generation: 1
name: ui
namespace: ui
resourceVersion: "8271"
uid: e73de185-eb46-43c5-99ac-cef11f54f78b
spec:
ingressClassName: alb
rules:
- http:
paths:
- backend:
service:
name: service-ui
port:
number: 80
path: /
pathType: Prefix
status:
loadBalancer:
ingress:
- hostname: k8s-ui-ui-5ddc3ba496-1821313371.us-west-2.elb.amazonaws.com백엔드 ingress 부분에 서비스 이름이 서비스의 이름과 달라서 매핑이 안되고 있는 상태이다. kubectl edit 으로 수정해도 되고, 실습 내용을 기준으로 똑같이 진행해보려고 한다.
kubectl apply -k ~/environment/eks-workshop/modules/troubleshooting/alb/creating-alb/fix_ingress
해당 파일을 조회 해 보면 결국은 이름을 맞춰 주었다.
ec2-user:~/environment:$ cat ~/environment/eks-workshop/modules/troubleshooting/alb/creating-alb/fix_ingress/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ui
namespace: ui
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/healthcheck-path: /actuator/health/liveness
spec:
ingressClassName: alb
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: ui
port:
number: 80다 될 줄 알았는데, 조회해 보면 503 에러가 발생한다.

kubectl -n ui get endpoints ui 입력한다.
NAME ENDPOINTS AGE
ui <none> 30m엔드포인트가 없다. 디플로이와 서비스를 조회한다.
kubectl -n ui get deploy/ui -o yaml

kubectl -n ui get svc ui -o yaml
해당 서비스는 해당 부분이 ui-app 으로 되어 있다. 그러므로 서비스가 선택이 되지 않은 상태이다.
kubectl apply -k ~/environment/eks-workshop/modules/troubleshooting/alb/creating-alb/fix_ui 명령어로 사전에 수정된 파일을 적용한다.
적용 이후에, 정상적으로 서비스가 접속이 되는 것을 확인 할 수 있다.

delete-environment
eksctl delete cluster $EKS_CLUSTER_NAME --wait
aws cloudformation delete-stack --stack-name eks-workshop-ideeksctl delete cluster $EKS_CLUSTER_NAME --wait aws cloudformation delete-stack --stack-name eks-workshop-ide 나는 해당 명령어가 되지 않아서, root 로 들어가서 콘솔에서 계속 삭제 했다.
실습을 마치면서 페이지에 정리 된 내용을 AI 를 이용해 정리 해 보았다.
보안(Security)
기본 문제 해결(Troubleshooting) 접근법
노드 → 노드 그룹 → Auto Scaling Group(ASG) → 런치 템플릿의 체인을 따라가며 확인한다.운영 모범 사례(Best Practices)
컨트롤러가 애플리케이션 로드 밸런서(ALB)와 어떻게 연동되는지 핵심 구성 요소를 살펴본다.
컨트롤러(Controller) 작동 방식
ALB (Application Load Balancer)
대상 그룹 (Target Group)
리스너 (Listener) & 규칙 (Rules)
ALB 구성 시 자주 발생하는 문제점과 확인해야 할 사항은 다음과 같다.
서브넷(Subnet) 구성
kubernetes.io/role/elb=1 태그가 있어야 한다.kubernetes.io/role/internal-elb=1 태그가 있어야 한다.IAM 권한
서비스(Service) 구성
AWS Load Balancer Controller를 사용할 때 다음 사항들을 권장한다.