728x90
- Amazon EKS로 클러스터 구성 시 일반적으로 고가용성을 위해서 모든 가용 영역(Availability Zone, AZ)에 워커 노드배치
- Pod들 또한 모든 AZ 에 배포되도록 설정하면 높은 가용성을 확보
- 여러 AZ에 걸쳐 Pod 간 통신이 이루어지는데, 이를 Cross-AZ 통신이라고 합니다.
- Amazon VPC 내에서 Cross-AZ 통신이 발생하더라도 통신량에 비례하여 통신 비용이 발생
- Cross-AZ 통신이 많은 경우 예상치 못한 비용이 발생 할 수 있음
- 대량의 Cross-AZ 통신으로 인한 비용을 절감하기 위한 기법 → Topology Aware Routing
- 실습을 위한 디플로이먼트&서비스 배포
# 현재 노드 AZ 배포 확인
kubectl get node --label-columns=topology.kubernetes.io/zone
NAME STATUS ROLES AGE VERSION ZONE
ip-192-168-1-225.ap-northeast-2.compute.internal Ready <none> 70m v1.24.11-eks-a59e1f0 ap-northeast-2a
ip-192-168-2-248.ap-northeast-2.compute.internal Ready <none> 70m v1.24.11-eks-a59e1f0 ap-northeast-2b
ip-192-168-3-228.ap-northeast-2.compute.internal Ready <none> 70m v1.24.11-eks-a59e1f0 ap-northeast-2c
# 테스트를 위한 디플로이먼트와 서비스 배포
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-echo
spec:
replicas: 3
selector:
matchLabels:
app: deploy-websrv
template:
metadata:
labels:
app: deploy-websrv
spec:
terminationGracePeriodSeconds: 0
containers:
- name: websrv
image: registry.k8s.io/echoserver:1.5
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: svc-clusterip
spec:
ports:
- name: svc-webport
port: 80
targetPort: 8080
selector:
app: deploy-websrv
type: ClusterIP
EOF
# 확인
kubectl get deploy,svc,ep,endpointslices
kubectl get pod -owide
kubectl get svc,ep svc-clusterip
kubectl get endpointslices -l kubernetes.io/service-name=svc-clusterip
kubectl get endpointslices -l kubernetes.io/service-name=svc-clusterip -o yaml
# 접속 테스트를 수행할 클라이언트 파드 배포
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: netshoot-pod
spec:
containers:
- name: netshoot-pod
image: nicolaka/netshoot
command: ["tail"]
args: ["-f", "/dev/null"]
terminationGracePeriodSeconds: 0
EOF
# 확인
kubectl get pod -owide
- netshoot-pod가 AZ1에 생성된 것을 확인
- 테스트 파드(netshoot-pod)에서 ClusterIP 접속 시 부하분산 확인 : AZ(zone) 상관없이 랜덤 확률 부하분산 동작
# 디플로이먼트 파드가 배포된 AZ(zone) 확인
kubectl get pod -l app=deploy-websrv -owide
# 테스트 파드(netshoot-pod)에서 ClusterIP 접속 시 부하분산 확인
kubectl exec -it netshoot-pod -- curl svc-clusterip | grep Hostname
# 100번 반복 접속 : 3개의 파드로 AZ(zone) 상관없이 랜덤 확률 부하분산 동작
kubectl exec -it netshoot-pod -- zsh -c "for i in {1..100}; do curl -s svc-clusterip | grep Hostname; done | sort | uniq -c | sort -nr"
※이렇게 AZ간 통신이 발생하게 되면 통신 비용 발생 → AZ2(netshoot-pod)에서 AZ1, AZ2, AZ3 통신
- iptables rule 확인 → 부하분산 이유
ssh ec2-user@$N1 sudo iptables -t nat -nvL
ssh ec2-user@$N1 sudo iptables -v --numeric --table nat --list PREROUTING
ssh ec2-user@$N1 sudo iptables -v --numeric --table nat --list KUBE-SERVICES
305 18300 KUBE-SVC-KBDEBIL6IU6WL7RF tcp -- * * 0.0.0.0/0 10.100.155.216 /* default/svc-clusterip:svc-webport cluster IP */ tcp dpt:80
...
# 노드1에서 SVC 정책 확인 : SEP(Endpoint) 파드 3개 확인 >> 즉, 3개의 파드로 랜덤 확률 부하분산 동작
ssh ec2-user@$N1 sudo iptables -v --numeric --table nat --list KUBE-SVC-KBDEBIL6IU6WL7RF
Chain KUBE-SVC-KBDEBIL6IU6WL7RF (1 references)
pkts bytes target prot opt in out source destination
108 6480 KUBE-SEP-WC4ARU3RZJKCUD7M all -- * * 0.0.0.0/0 0.0.0.0/0 /* default/svc-clusterip:svc-webport -> 192.168.1.240:8080 */ statistic mode random probability 0.33333333349
115 6900 KUBE-SEP-3HFAJH523NG6SBCX all -- * * 0.0.0.0/0 0.0.0.0/0 /* default/svc-clusterip:svc-webport -> 192.168.2.36:8080 */ statistic mode random probability 0.50000000000
82 4920 KUBE-SEP-H37XIVQWZO52OMNP all -- * * 0.0.0.0/0 0.0.0.0/0 /* default/svc-clusterip:svc-webport -> 192.168.3.13:8080 */
- with Hints인 경우, 대상이 있는 Zone으로만 통신
- without Hints인 경우, 랜덤으로 통신
- Topology Aware Routing 설정
# Topology Aware Routing 설정 : 서비스에 annotate에 아래처럼 추가
kubectl annotate service svc-clusterip "service.kubernetes.io/topology-mode=auto"
# endpointslices 확인 시, 기존에 없던 hints 가 추가되어 있음 >> 참고로 describe로는 hints 정보가 출력되지 않음
kubectl get endpointslices -l kubernetes.io/service-name=svc-clusterip -o yaml
apiVersion: v1
items:
- addressType: IPv4
apiVersion: discovery.k8s.io/v1
endpoints:
- addresses:
- 192.168.3.13
conditions:
ready: true
serving: true
terminating: false
hints:
forZones:
- name: ap-northeast-2c
nodeName: ip-192-168-3-228.ap-northeast-2.compute.internal
targetRef:
kind: Pod
name: deploy-echo-7f67d598dc-hg995
namespace: default
uid: c1ce0e9c-14e7-417d-a1b9-2dfd54da8d4a
zone: ap-northeast-2c
- addresses:
- 192.168.2.65
conditions:
ready: true
serving: true
terminating: false
hints:
forZones:
- name: ap-northeast-2b
nodeName: ip-192-168-2-248.ap-northeast-2.compute.internal
targetRef:
kind: Pod
name: deploy-echo-7f67d598dc-h9vst
namespace: default
uid: 77af6a1b-c600-456c-96f3-e1af621be2af
zone: ap-northeast-2b
- addresses:
- 192.168.1.240
conditions:
ready: true
serving: true
terminating: false
hints:
forZones:
- name: ap-northeast-2a
nodeName: ip-192-168-1-225.ap-northeast-2.compute.internal
targetRef:
kind: Pod
name: deploy-echo-7f67d598dc-45trg
namespace: default
uid: 53ca3ac7-b9fb-4d98-a3f5-c312e60b1e67
zone: ap-northeast-2a
kind: EndpointSlice
...
# 100번 반복 접속 : 테스트 파드(netshoot-pod)와 같은 AZ(zone)의 목적지 파드로만 접속
kubectl exec -it netshoot-pod -- zsh -c "for i in {1..100}; do curl -s svc-clusterip | grep Hostname; done | sort | uniq -c | sort -nr"
- hints 설정 후, 동일하게 netshoot-pod에서 svc-clusterip 통신을 수행하는 경우, 동일 AZ에 있는 pod로만 통신하는 것을 확인!
- 노드에서 SVC 정책 확인 : SEP(Endpoint) 파드 1개 확인(해당 노드와 같은 AZ에 배포된 파드만 출력) >> 동일 AZ간 접속
- 파드 갯수를 1개로 줄여서 같은 AZ에 목적지 파드가 없을 경우
# 파드 갯수를 1개로 줄이기
kubectl scale deployment deploy-echo --replicas 1
# 동일 AZ일 경우 0 -> 1 시도
kubectl scale deployment deploy-echo --replicas 0
kubectl scale deployment deploy-echo --replicas 1
# 파드 AZ 확인 : 아래 처럼 현재 다른 AZ에 배포
kubectl get pod -owide
- 현재 netshoot-pod는 AZ1, echo pod는 AZ2에 구성
# 100번 반복 접속 : 다른 AZ이지만 목적지파드로 접속됨!
kubectl exec -it netshoot-pod -- zsh -c "for i in {1..100}; do curl -s svc-clusterip | grep Hostname; done | sort | uniq -c | sort -nr"
ssh ec2-user@$N1 sudo iptables -v --numeric --table nat --list KUBE-SERVICES
ssh ec2-user@$N2 sudo iptables -v --numeric --table nat --list KUBE-SVC-KBDEBIL6IU6WL7RF
ssh ec2-user@$N3 sudo iptables -v --numeric --table nat --list KUBE-SVC-KBDEBIL6IU6WL7RF
# endpointslices 확인 : hint 정보 없음
kubectl get endpointslices -l kubernetes.io/service-name=svc-clusterip -o yaml
- 파드 수가 감소함에 따라, hints가 자동으로 현재 배포되어 있는 pod의 az로 통신할 수 있게 자동 설정!!
- 배포되어 있는 pod로 정상 통신 확인
- hints 설정 제거 확인
728x90
'2025_AEWS Study' 카테고리의 다른 글
3주차 - EKS Storage & Managed Node Groups(2)(Kubestr 모니터링 및 성능 측정 확인) (0) | 2025.02.19 |
---|---|
3주차 - EKS Storage & Managed Node Groups(1)(스토리지) (0) | 2025.02.19 |
2주차 - EKS Networking(5)(Ingress & ExternalDNS) (0) | 2025.02.15 |
2주차 - EKS Networking(4)(Service & AWS LoadBalancer Controller) (0) | 2025.02.15 |
2주차 - EKS Networking(3)(노드 내 파드 생성 갯수 제한) (0) | 2025.02.15 |