EKS 8탄 - 2주차
본 내용은 CloudNet 주말 스터디 내용을 참고로 작성되었습니다.
https://gasidaseo.notion.site/gasidaseo/CloudNet-Blog-c9dfa44a27ff431dafdd2edacc8a1863
계속 테스트하며 내용과 설명이 업데이트 됩니다.
Service (LoadBalancer Controller) 이해
AWS LoadBalancer Controller 배포
NLB
Ingress (L7)
1
Service (LoadBalancer Controller)
: AWS Load Balancer Controller + NLB IP 모드 동작 with AWS VPC CNI
도메인 ------- 로드밸런서 ---- Pod로 연결된다.
1) 동적으로 변하는 Pod의 정보를 알아야 한다.
Load Balancer Controller 파드가 그 정보를 알아서 지속적인 정보제공을 로드밸런서에 한다.
"대상 타겟에 pod 추가로 생겼어~ "
"Pod삭제 되었네, NLB나 ALB에서 제외하자~"
Load Balancer Controller 파드가 워커 노드에 생성된다.
2) 워커 노드에 로드밸런서를 변경할수 있는 권한을 부여하여 권한 문제를 해결한다.
이해 완료???
2. IP 유형
⇒ 반드시 AWS LoadBalancer 컨트롤러 파드 및 정책 설정이 필요함!
1) `Proxy Protocol v2 비활성화`
⇒ NLB에서 바로 파드로 인입, 단 ClientIP가 NLB로 SNAT 되어 Client IP 확인 불가능
2) `Proxy Protocol v2 활성화`
⇒ NLB에서 바로 파드로 인입 및 ClientIP 확인 가능(→ 단 PPv2 를 애플리케이션이 인지할 수 있게 설정 필요)
1
클러스터에는 OpenID Connect(OIDC) 발급자 URL이 연결되어 있습니다.
서비스 계정에 AWS Identity and Access Management(IAM) 역할을 사용하려면 클러스터의 OIDC 발급자 URL에 IAM OIDC 제공업체가 있어야 합니다.
https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/enable-iam-roles-for-service-accounts.html
2
IRSA (IAM role for Service Account ) ?
EKS Cluster안에서 동작하는 kubernetes Pod에 IAM Role을 줄 때 사용한다.
EKS Cluster 내부에서 pod에게 IAM Role권한을 주는 방식 IRSA 입니다
EKS에 있는 Pod가 IAM role을 얻어서 , AWS 리소스를 사용할수 있게 하는것이다.
예) Pod가 role을 얻어 AWS S3를 사용하는것.
https://brunch.co.kr/@topasvga/1885
3
https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/aws-load-balancer-controller.html
4
# OIDC 확인
aws eks describe-cluster --name $CLUSTER_NAME --query "cluster.identity.oidc.issuer" --output text
aws iam list-open-id-connect-providers | jq
5
# IAM Policy (AWSLoadBalancerControllerIAMPolicy) 생성
curl -o iam_policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.4.7/docs/install/iam_policy.json
aws iam create-policy --policy-name AWSLoadBalancerControllerIAMPolicy --policy-document file://iam_policy.json
6
# 생성된 IAM Policy Arn 확인
aws iam list-policies --scope Local
aws iam get-policy --policy-arn arn:aws:iam::$ACCOUNT_ID:policy/AWSLoadBalancerControllerIAMPolicy
aws iam get-policy --policy-arn arn:aws:iam::$ACCOUNT_ID:policy/AWSLoadBalancerControllerIAMPolicy --query 'Policy.Arn'
7
# AWS Load Balancer Controller를 위한 ServiceAccount를 생성
>> 자동으로 매칭되는 IAM Role 을 CloudFormation 으로 생성됨!
8
# IAM 역할 생성
AWS Load Balancer Controller의 kube-system 네임스페이스에 aws-load-balancer-controller라는 Kubernetes 서비스 계정을 생성하고, IAM 역할의 이름으로 Kubernetes 서비스 계정에 주석을 답니다.
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
(2분 걸림)
9
## IRSA 정보 확인
eksctl get iamserviceaccount --cluster myeks
10
## 서비스 어카운트 확인
kubectl get serviceaccounts -n kube-system aws-load-balancer-controller -o yaml | yh
11
# Helm Chart 설치
helm repo add eks https://aws.github.io/eks-charts
helm repo update
helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=$CLUSTER_NAME --set serviceAccount.create=false --set serviceAccount.name=aws-load-balancer-controller
12
CustomResourceDefinition (CRD) = 고객 리소스 정의.
## 설치 확인
kubectl get crd
NAME CREATED AT
eniconfigs.crd.k8s.amazonaws.com 2023-04-30T11:09:13Z
ingressclassparams.elbv2.k8s.aws 2023-05-01T11:50:13Z
securitygrouppolicies.vpcresources.k8s.aws 2023-04-30T11:09:15Z
targetgroupbindings.elbv2.k8s.aws 2023-05-01T11:50:13Z
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'
Service Account: aws-load-balancer-controller
13
# 클러스터롤, 롤 확인
kubectl describe clusterrolebindings.rbac.authorization.k8s.io aws-load-balancer-controller-rolebinding
kubectl describe clusterroles.rbac.authorization.k8s.io aws-load-balancer-controller-role
이해 완료??
1
# 모니터링
watch -d 'kubectl get deploy,rs,svc,ep,pods,ingress,targetgroupbindings -o wide'
2
# 작업용 EC2 - 디플로이먼트 & 서비스 생성
curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/2/echo-service-nlb.yaml
cat echo-service-nlb.yaml | yh
kubectl apply -f echo-service-nlb.yaml
3
# 확인
kubectl get deploy,pod
kubectl get svc,ep,ingressclassparams,targetgroupbindings
kubectl get targetgroupbindings -o json | jq
# AWS ELB(NLB) 정보 확인
aws elbv2 describe-load-balancers | jq
aws elbv2 describe-load-balancers --query 'LoadBalancers[*].State.Code' --output text
# 웹 접속 주소 확인
kubectl get svc svc-nlb-ip-type -o jsonpath={.status.loadBalancer.ingress[0].hostname} | awk '{ print "Pod Web URL = http://"$1 }'
웹 접속시 나오는 정보
# 파드 로깅 모니터링
kubectl logs -l app=deploy-websrv -f
192.168.2.244 - - [01/May/2023:12:08:44 +0000] "GET / HTTP/1.1" 200 691 "-" "curl/7.88.1"
192.168.1.149 - - [01/May/2023:12:08:44 +0000] "GET / HTTP/1.1" 200 691 "-" "curl/7.88.1"
192.168.3.117 - - [01/May/2023:12:08:44 +0000] "GET / HTTP/1.1" 200 691 "-" "curl/7.88.1"
192.168.2.244 - - [01/May/2023:12:08:44 +0000] "GET / HTTP/1.1" 200 691 "-" "curl/7.88.1"
192.168.1.149 - - [01/May/2023:12:08:44 +0000] "GET / HTTP/1.1" 200 691 "-" "curl/7.88.1"
192.168.3.117 - - [01/May/2023:12:08:44 +0000] "GET / HTTP/1.1" 200 691 "-" "curl/7.88.1"
192.168.2.244 - - [01/May/2023:12:08:44 +0000] "GET / HTTP/1.1" 200 691 "-" "curl/7.88.1"
192.168.1.149 - - [01/May/2023:12:08:44 +0000] "GET / HTTP/1.1" 200 691 "-" "curl/7.88.1"
192.168.3.117 - - [01/May/2023:12:08:44 +0000] "GET / HTTP/1.1" 200 691 "-" "curl/7.88.1"
192.168.2.244 - - [01/May/2023:12:08:44 +0000] "GET / HTTP/1.1" 200 691 "-" "curl/7.88.1"
192.168.1.149 - - [01/May/2023:12:08:44 +0000] "GET / HTTP/1.1" 200 691 "-" "curl/7.88.1"
192.168.3.117 - - [01/May/2023:12:08:44 +0000] "GET / HTTP/1.1" 200 691 "-" "curl/7.88.1"
192.168.2.244 - - [01/May/2023:12:08:44 +0000] "GET / HTTP/1.1" 200 691 "-" "curl/7.88.1"
192.168.1.149 - - [01/May/2023:12:08:44 +0000] "GET / HTTP/1.1" 200 691 "-" "curl/7.88.1"
192.168.3.117 - - [01/May/2023:12:08:44 +0000] "GET / HTTP/1.1" 200 691 "-" "curl/7.88.1"
192.168.2.244 - - [01/May/2023:12:08:44 +0000] "GET / HTTP/1.1" 200 691 "-" "curl/7.88.1"
4
# 분산 접속 확인
NLB=$(kubectl get svc svc-nlb-ip-type -o jsonpath={.status.loadBalancer.ingress[0].hostname})
echo $NLB
(eks5-access@myeks:default) [root@myeks-bastion-EC2 ~]# echo $NLB
k8s-default-svcnlbip-d959415c0b-fb49155dc99f1dc2.elb.ap-northeast-2.amazonaws.com
(5분 걸림)
curl -s $NLB
for i in {1..100}; do curl -s $NLB | grep Hostname ; done | sort | uniq -c | sort -nr
(eks5-access@myeks:default) [root@myeks-bastion-EC2 ~]# for i in {1..100}; do curl -s $NLB | grep Hostname ; done | sort | uniq -c | sort -nr
54 Hostname: deploy-echo-5c4856dfd6-6v596
46 Hostname: deploy-echo-5c4856dfd6-b9x4b
5
# 지속적인 접속 시도 : 아래 상세 동작 확인 시 유용(패킷 덤프 등)
while true; do curl -s --connect-timeout 1 $NLB | egrep 'Hostname|client_address'; echo "----------" ; date "+%Y-%m-%d %H:%M:%S" ; sleep 1; done
6
파일
참고
https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/network-load-balancing.html
https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.4/guide/service/nlb/
콘솔에서도 확인하자!!!!
반영 된다.
1
watch -d 'kubectl get deploy,rs,svc,ep,pods,ingress,targetgroupbindings -o wide'
2
# 작업용 EC2 - 파드 1개 설정
kubectl scale deployment deploy-echo --replicas=1
// 콘솔에서 확인하자.
로드밸런서에서 pod에서 1개 pod가 draining됨
# 확인
kubectl get deploy,pod,svc,ep
curl -s $NLB
for i in {1..100}; do curl -s --connect-timeout 1 $NLB | grep Hostname ; done | sort | uniq -c | sort -nr
(eks5-access@myeks:default) [root@myeks-bastion-EC2 ~]# for i in {1..100}; do curl -s --connect-timeout 1 $NLB | grep Hostname ; done | sort | uniq -c | sort -nr
93 Hostname: deploy-echo-5c4856dfd6-b9x4b
3
# 작업용 EC2 - 파드 3개 설정
kubectl scale deployment deploy-echo --replicas=3
# 확인
kubectl get deploy,pod,svc,ep
curl -s $NLB
for i in {1..100}; do curl -s --connect-timeout 1 $NLB | grep Hostname ; done | sort | uniq -c | sort -nr
(eks5-access@myeks:default) [root@myeks-bastion-EC2 ~]# for i in {1..100}; do curl -s --connect-timeout 1 $NLB | grep Hostname ; done | sort | uniq -c | sort -nr
54 Hostname: deploy-echo-5c4856dfd6-b9x4b
23 Hostname: deploy-echo-5c4856dfd6-wf5cw
23 Hostname: deploy-echo-5c4856dfd6-444b5
4
# [AWS LB Ctrl] 클러스터 롤 바인딩 정보 확인
kubectl describe clusterrolebindings.rbac.authorization.k8s.io aws-load-balancer-controller-rolebinding
Name: aws-load-balancer-controller-rolebinding
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.5.1
helm.sh/chart=aws-load-balancer-controller-1.5.2
Annotations: meta.helm.sh/release-name: aws-load-balancer-controller
meta.helm.sh/release-namespace: kube-system
Role:
Kind: ClusterRole
Name: aws-load-balancer-controller-role
Subjects:
Kind Name Namespace
---- ---- ---------
ServiceAccount aws-load-balancer-controller kube-system
5
# [AWS LB Ctrl] 클러스터롤 확인
kubectl describe clusterroles.rbac.authorization.k8s.io aws-load-balancer-controller-role
1
AWS Load Balancer Controller + Ingress (ALB) IP 모드 동작 with AWS VPC CN
2
# 게임 파드와 Service, Ingress 배포
# 모니터링
watch -d kubectl get pod,ingress,svc,ep -n game-2048
curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/3/ingress1.yaml
cat ingress1.yaml | yh
kubectl apply -f ingress1.yaml
# 생성 확인
kubectl get-all -n game-2048
kubectl get ingress,svc,ep,pod -n game-2048
kubectl get targetgroupbindings -n game-2048
NAME SERVICE-NAME SERVICE-PORT TARGET-TYPE AGE
k8s-game2048-service2-e48050abac service-2048 80 ip 87s
# Ingress 확인
kubectl describe ingress -n game-2048 ingress-2048
# 게임 접속 : ALB 주소로 웹 접속
kubectl get ingress -n game-2048 ingress-2048 -o jsonpath={.status.loadBalancer.ingress[0].hostname} | awk '{ print "Game URL = http://"$1 }'
------
Game URL = http://k8s-game2048-ingress2-70d50ce3fd-338465047.ap-northeast-2.elb.amazonaws.com
# 파드 IP 확인
kubectl get pod -n game-2048 -owide
# 터미널1
watch kubectl get pod -n game-2048
# 터미널2 : 파드 3개로 증가
kubectl scale deployment -n game-2048 deployment-2048 --replicas 3
pod가 로드밸런서에 자동 포함되는것을 콘솔에서 확인하자!!
# 터미널2 : 파드 1개로 감소
kubectl scale deployment -n game-2048 deployment-2048 --replicas 1
kubectl delete ingress ingress-2048 -n game-2048
kubectl delete svc service-2048 -n game-2048 && kubectl delete deploy deployment-2048 -n game-2048 && kubectl delete ns game-2048
3
콘솔에서 확인하자!
타겟 그룹의 내용을 확인하자!
이해 완료?????
4
삭제는 필수 !!!!
aws cloudformation delete-stack --stack-name eksctl-$CLUSTER_NAME-addon-iamserviceaccount-kube-system-aws-load-balancer-controller
eksctl delete cluster --name $CLUSTER_NAME && aws cloudformation delete-stack --stack-name $CLUSTER_NAME
// 모두 삭제 될때까지 터미널을 유지해야 한다!!!
// 터미널을 닫으면 삭제가 안된다.
(eks5-access@myeks:game-2048) [root@myeks-bastion-EC2 ~]# eksctl delete cluster --name $CLUSTER_NAME && aws cloudformation delete-stack --stack-name $CLUSTER_NAME
2023-05-02 19:27:23 [ℹ] deleting EKS cluster "myeks"
:
2023-05-02 19:30:38 [ℹ] waiting for CloudFormation stack "eksctl-myeks-nodegroup-ng1"
2023-05-02 19:31:14 [ℹ] waiting for CloudFormation stack "eksctl-myeks-nodegroup-ng1"
2023-05-02 19:32:17 [ℹ] waiting for CloudFormation stack "eksctl-myeks-nodegroup-ng1"
2023-05-02 19:33:58 [ℹ] waiting for CloudFormation stack "eksctl-myeks-nodegroup-ng1"
2023-05-02 19:35:31 [ℹ] waiting for CloudFormation stack "eksctl-myeks-nodegroup-ng1"
2023-05-02 19:36:55 [ℹ] waiting for CloudFormation stack "eksctl-myeks-nodegroup-ng1"
2023-05-02 19:36:56 [ℹ] will delete stack "eksctl-myeks-addon-vpc-cni"
2023-05-02 19:36:56 [ℹ] will delete stack "eksctl-myeks-cluster"
2023-05-02 19:36:56 [✔] all cluster resources were deleted
삭제
로드 밸런서 삭제 확인
VPC 삭제 확인
콘솔 > EC2 가서 삭제 완료 확인.
EC2가 삭제 안되어 있으면 EC2 > 오토스케일링 그룹을 삭제하라.
쿠버네티스 Service 계정이 IAM role 을 사용하려면 클러스터 OIDC URL 이 있어야 한다.
IRSA(IAM Role for Service Account) 는 Pod (LB 컨트롤러 파드)가 Role 을 얻는 것이다.
로드밸런서에 Pod 추가/삭제등 정보를 업데이트 하기 위해 AWS LoadBalancer Controller 가 필요하다.
Pod에 서비스 어카운트를 준다.
정리 : OIDC 필요 , IRSA 필요, 로드밸런서 컨트롤러 필요.
목차
- 1주차 Introduction** - EKS 실습 환경 배포
- 2주차 Networking** - VPC CNI, SG for Pods, AWS LB Controller
- 3주차 Fundamentals** - Storage, Managed Node Groups, Fargate
- 4주차 Observability** - EKS Console, OpenTelemetry/AMP, Kubecost
- 5주차 Autoscaling** - CA, Karpenter, HPA, CPA
- 6주차 Security** - IRSA, Securing Secrets, GuardDuty for EKS
- 7주차 Automation** - GitOps(Flux, Argo CD), ACK, Crossplane
스토리지
https://brunch.co.kr/@topasvga/3233
전체 보기
https://brunch.co.kr/@topasvga/3217
감사합니다.