brunch

You can make anything
by writing

C.S.Lewis

by Master Seo May 01. 2023

EKS 8탄-3. EKS-Networking -3/17

EKS 8탄 -  2주차

본 내용은 CloudNet 주말 스터디 내용을 참고로 작성되었습니다.

https://gasidaseo.notion.site/gasidaseo/CloudNet-Blog-c9dfa44a27ff431dafdd2edacc8a1863  

계속 테스트하며  내용과 설명이 업데이트 됩니다.



목표

Service (LoadBalancer Controller) 이해

AWS LoadBalancer Controller 배포

NLB

Ingress (L7)



<1> Service & AWS LoadBalancer Controller 알아보자

<2> AWS LoadBalancer Controller 배포 with IRSA 

<3> 서비스와 파드 배포 테스트 with NLB

<4> 파드 2개 → 1개 → 3개 설정 시 동작

<5> Ingress (L7)

<6> 정리




<1> Service & AWS LoadBalancer Controller 알아보자


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 를 애플리케이션이 인지할 수 있게 설정 필요)




<2> AWS LoadBalancer Controller 배포 with IRSA 


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




이해 완료??






<3> 서비스와 파드 배포 테스트 with NLB


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/




<4> 파드 2개 → 1개 → 3개 설정 시 동작


콘솔에서도 확인하자!!!!

반영 된다.



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







이제 인그레스 , L7 알아보자.



<5> Ingress (L7)


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 > 오토스케일링 그룹을 삭제하라.





<6> 정리


쿠버네티스 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


감사합니다.



                    

브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari