brunch

EKS 4탄-5. Pod 외부 통신,최대Pod-5/17

실습 4탄 = 5/17

by Master Seo

<1> 서비스 확인

<2> Pod의 외부 통신법 이해

<3> 실습1 - 최대 몇개의 pod가 생성 가능한지 보자 - kube-ops-view 설치

<4> 실습2 - 인스턴스 타입 별 최대 파드 수 확인

<5> 사용하지 않으면 디플로이먼트 삭제





<1> 서비스 확인


1

서비스

고정적인 외부 단일 진입점

L4라고 생각하면 된다.

서비스 접근하면 iptable 분산 룰에 의해 분산 된다.



2

서비스 확인

명령 ec2에서


kubectl get svc,ep -A

NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

default service/kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 4h51m

kube-system service/kube-dns ClusterIP 10.100.0.10 <none> 53/UDP,53/TCP 4h51m


NAMESPACE NAME ENDPOINTS AGE

default endpoints/kubernetes 192.168.1.27:443,192.168.2.121:443 4h51m

kube-system endpoints/kube-dns 192.168.2.156:53,192.168.2.74:53,192.168.2.156:53 + 1 more... 4h51m


쿠버네스 서비스

kube-dns 서비스

10.100.0.1 로 접속 하면 192.168.1.27 , 192.168.2.121 로 간다.

10.100.0.10으로 접속하면 192.168.2.156 , 192.168.2.74 간다.



3

워커 노드에서 작업 ?


10.100.0.1 은 뭔가?

10.100.0.1 로 culr 해본다.

버전을 본다.

버전은 안막혀 있다.

ping은 막혀 있다.

쿠버네티스 컨트롤 플래인 IP = 10.100.0.1


curl -s -k https://10.100.0.1/version

{

"major": "1",

"minor": "21+",

"gitVersion": "v1.21.2-eks-0389ca3",

"gitCommit": "8a4e27b9d88142bbdd21b997b532eb6d493df6d2",

"gitTreeState": "clean",

"buildDate": "2021-07-31T01:34:46Z",

"goVersion": "go1.16.5",

"compiler": "gc",

"platform": "linux/amd64"

}[root@ip-192-168-1-90 ~]#



4

라우팅 테이블에 없다.

그러나, iptalble로 처리해 준다.


[root@ip-192-168-1-90 ~]# route -n

Kernel IP routing table

Destination Gateway Genmask Flags Metric Ref Use Iface

0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0

169.254.169.254 0.0.0.0 255.255.255.255 UH 0 0 0 eth0

192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0

192.168.1.11 0.0.0.0 255.255.255.255 UH 0 0 0 eni83dbd022cd5

192.168.1.121 0.0.0.0 255.255.255.255 UH 0 0 0 enifbd243bfedd


iptables -t nat -S | grep 10.100.0.1/32

[root@ip-192-168-1-90 ~]# iptables -t nat -S | grep 10.100.0.1/32

-A KUBE-SERVICES -d 10.100.0.1/32 -p tcp -m comment --comment "default/kubernetes:https cluster IP" -m tcp --dport 443 -j KUBE-SVC-NPX46M4PTMTKRN6Y



5

2개의 SEP 확인이 된다. 서비스 엔드포인트


iptables -t nat -S | grep KUBE-SVC-NPX46M4PTMTKRN6Y

[root@ip-192-168-1-90 ~]# iptables -t nat -S | grep KUBE-SVC-NPX46M4PTMTKRN6Y

-N KUBE-SVC-NPX46M4PTMTKRN6Y

-A KUBE-SERVICES -d 10.100.0.1/32 -p tcp -m comment --comment "default/kubernetes:https cluster IP" -m tcp --dport 443 -j KUBE-SVC-NPX46M4PTMTKRN6Y

-A KUBE-SVC-NPX46M4PTMTKRN6Y -m comment --comment "default/kubernetes:https" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-MW4G2CK35L7KAHVW

-A KUBE-SVC-NPX46M4PTMTKRN6Y -m comment --comment "default/kubernetes:https" -j KUBE-SEP-UYES2HJ7BEZOI3HM



6

SEP 확인

iptables -t nat -S | grep KUBE-SEP-UYES2HJ7BEZOI3HM


[root@ip-192-168-1-90 ~]# iptables -t nat -S | grep KUBE-SEP-UYES2HJ7BEZOI3HM

-N KUBE-SEP-UYES2HJ7BEZOI3HM

-A KUBE-SEP-UYES2HJ7BEZOI3HM -s 192.168.2.121/32 -m comment --comment "default/kubernetes:https" -j KUBE-MARK-MASQ

-A KUBE-SEP-UYES2HJ7BEZOI3HM -p tcp -m comment --comment "default/kubernetes:https" -m tcp -j DNAT --to-destination 192.168.2.121:443

-A KUBE-SVC-NPX46M4PTMTKRN6Y -m comment --comment "default/kubernetes:https" -j KUBE-SEP-UYES2HJ7BEZOI3HM


ip 192.168.2.121 가 확인 된다.

192.168.2.121 는 default 엔드포인트 ip 와 같다.



7

명령어 서버 에서 확인

kubectl get svc,ep -A

(t6-admin@myeks:default) [root@myeks-host ~]# kubectl get svc,ep -A

NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

default service/kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 5h4m

kube-system service/kube-dns ClusterIP 10.100.0.10 <none> 53/UDP,53/TCP 5h4m


NAMESPACE NAME ENDPOINTS AGE

default endpoints/kubernetes 192.168.1.27:443,192.168.2.121:443 5h4m

kube-system endpoints/kube-dns 192.168.2.156:53,192.168.2.74:53,192.168.2.156:53 + 1 more... 5h4m



8

결론

컨트롤 패널의 iptable에 의해 각 node로 분산 된다.

140 pod service.png




<2> Pod의 외부 통신법 이해



1

pod가 외부로 나갈때는 node ip로 마스커레이딩 되어 나간다.


iptables -t nat -S | grep 'A AWS-SNAT-CHAIN'


[root@ip-192-168-1-90 ~]# iptables -t nat -S | grep 'A AWS-SNAT-CHAIN'

-A AWS-SNAT-CHAIN-0 ! -d 192.168.0.0/16 -m comment --comment "AWS SNAT CHAIN" -j AWS-SNAT-CHAIN-1

-A AWS-SNAT-CHAIN-1 ! -o vlan+ -m comment --comment "AWS, SNAT" -m addrtype ! --dst-type LOCAL -j SNAT --to-source 192.168.1.90 --random-fully


// chain0과 chain1을 탄다.



2

watch로 확인한다.

watch -d 'iptables -v --numeric --table nat --list AWS-SNAT-CHAIN-0; echo ; iptables -v --numeric --table nat --list AWS-SNAT-CHAIN-1; echo ; iptables -v --numeric --table nat --list KUBE-POSTROUTING'



3

Pod에서

kubectl exec -it pod-1 -- zsh

ping 8.8.8.8


watch에서 패킷 카운터가 늘어나는것 확인





<3> 실습1 - 최대 몇개의 pod가 생성 가능한지 보자 - kube-ops-view 설치



명령 서버에서


1

# Helm 설치


curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash

helm version --short

helm repo add stable https://charts.helm.sh/stable



2

# kube-ops-view 설치


https://brunch.co.kr/@topasvga/1653




# 기존에 한번 설치했다면 다른 이름으로 kube-ops-view2 으로 설치


helm install kube-ops-view2 stable/kube-ops-view --set service.type=LoadBalancer --set rbac.create=True



3

# 차트 설치 확인


helm list

NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION

kube-ops-view default 1 2021-08-30 18:46 +09 KST deployed kube-ops-view-1.2.4 20.4.0



4

kubectl get svc kube-ops-view

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

kube-ops-view LoadBalancer 10.100.154.244 a8fb8210.ap-northeast-2.elb.amazonaws.com 80:32458/TCP 3m6s



5

AWS 콘솔에 가면 CLB가 자동 생성되어 있다.(CLB가 배포되는데 5분 소요)



6

웹브라우저로 접속

a8fac4b27fe0c2-2086998210.ap-northeast-2.elb.amazonaws.com



160 opsview2.png




150 ops-view1.png




7

proxy pod는 어디 있는지 확인?


proxy 라고 조회

170 proxy.png



8

참고

https://www.eksworkshop.com/beginner/080_scaling/install_kube_ops_view/




<4> 실습2 - 인스턴스 타입 별 최대 파드 수 확인



보통 인스턴스 별로 30개 미만의 pod 사용한다고 보면 된다.



1

모니터링

watch -d 'kubectl get svc,ns,pod -A'



2

현재 Pod 수 확인 9개

node2,dns2,porxy2 - 기본 6



kubectl get pod -A

NAMESPACE NAME READY STATUS RESTARTS AGE

default kube-ops-view-5557846b44-5rwwj 1/1 Running 0 14m

default pod-1 1/1 Running 0 165m

default pod-2 1/1 Running 0 165m

kube-system aws-node-b74nt 1/1 Running 0 5h30m

kube-system aws-node-g842k 1/1 Running 0 5h30m

kube-system coredns-6dbb778559-7hkhs 1/1 Running 0 5h41m

kube-system coredns-6dbb778559-bv9xm 1/1 Running 0 5h41m

kube-system kube-proxy-d8ztj 1/1 Running 0 5h30m

kube-system kube-proxy-g6jt9 1/1 Running 0 5h30m


160 opsview2.png



3

codedns를 1개로 줄임 (기본 2개)

kubectl scale deployment -n kube-system coredns --replicas=1

deployment.apps/coredns scaled


8개

(t6-admin@myeks:default) [root@myeks-host ~]# kubectl get pod -A

NAMESPACE NAME READY STATUS RESTARTS AGE

default kube-ops-view-5557846b44-5rwwj 1/1 Running 0 18m

default pod-1 1/1 Running 0 169m

default pod-2 1/1 Running 0 169m

kube-system aws-node-b74nt 1/1 Running 0 5h34m

kube-system aws-node-g842k 1/1 Running 0 5h34m

kube-system coredns-6dbb778559-pkkt2 1/1 Running 0 18s

kube-system kube-proxy-d8ztj 1/1 Running 0 5h34m

kube-system kube-proxy-g6jt9 1/1 Running 0 5h34



4

인스턴스 타입별 할당 가능 IP와 ENI수 ?


aws ec2 describe-instance-types --filters Name=instance-type,Values=t3.* --query "InstanceTypes[].{Type: InstanceType, MaxENI: NetworkInfo.MaximumNetworkInterfaces, IPv4addr: NetworkInfo.Ipv4AddressesPerInterface}" --output table


--------------------------------------

| DescribeInstanceTypes |

+----------+----------+--------------+

| IPv4addr | MaxENI | Type |

+----------+----------+--------------+

| 6 | 3 | t3.medium |

| 12 | 3 | t3.large |

| 15 | 4 | t3.2xlarge |

| 15 | 4 | t3.xlarge |

| 2 | 2 | t3.micro |

| 2 | 2 | t3.nano |

| 4 | 3 | t3.small |

+----------+----------+--------------+


t3.medium은 (6-1) * 3 + 2 = 총 17개 가능

최대 3개 ENI 사용가능

ip는 6개씩 할당 가능

1개씩은 사용하여 6-1

+2 는 CNI와 Kube-proxy 용


t3.medium 2대 = 2개 노드면 = 30개 미만 Pod 생성 가능.




참고

https://github.com/awslabs/amazon-eks-ami/blob/master/files/eni-max-pods.txt





4

확인 ?


# 디플로이먼트로 웹서버 생성


cat <<EOF | kubectl create -f -

apiVersion: apps/v1

kind: Deployment

metadata:

name: nginx-deployment

labels:

app: nginx

spec:

replicas: 2

selector:

matchLabels:

app: nginx

template:

metadata:

labels:

app: nginx

spec:

containers:

- name: nginx

image: nginx:alpine

ports:

- containerPort: 80

EOF




5

node에서 이더넷 증가 모니터링 ?



watch -d "ip link | egrep 'eth|eni'"


eth1

eth2

eth3 늘어난다.

eth당 6개가능 = 1개 기본 + 5개 추가시 eth1으로 늘어난다.





6

명령 서버에서

kubectl scale deployment nginx-deployment --replicas=10

kubectl scale deployment nginx-deployment --replicas=30

kubectl scale deployment nginx-deployment --replicas=1




7

명령 서버에서 pending 확인 ?


kubectl get pods | grep Pending

nginx-deployment-7fb7fd49b4-ftrsb 0/1 Pending 0 91s

nginx-deployment-7fb7fd49b4-hgg7k 0/1 Pending 0 91s


2개가 Pending 되어 있다.

34개 가능 = 30개 + 기본 6개 (proxy 2, dns 1 , ops-view1, node 2)

-> 2개 pending





8

kubectl describe pod <Pending 파드> | grep Events: -A5


kubectl describe pod nginx-deployment-f576985cc-cp57w |grep Events: -A5



9

이유 확인 ?


kubectl describe pod nginx-deployment-7fb7fd49b4-hgg7k | grep Events: -A5


Events:

Type Reason Age From Message

---- ------ ---- ---- -------

Warning FailedScheduling 52s (x4 over 3m13s) default-scheduler 0/2 nodes are available: 2 Too many pods.


Too many pods. = IP부족한 경우이다.

서버가 제공가능한 네트워크를 초과하여 발생 된 경우






10

Too many pods 해결법 ?


클러스터 서버를 늘리거나 타입을 변경


또는


아래 3개 사이트 참고


https://lcc3108.github.io/articles/2021-08/eks-too-many-pod



https://aws-diary.tistory.com/146

https://aws.amazon.com/ko/blogs/containers/amazon-vpc-cni-increases-pods-per-node-limits/




<5> 사용하지 않으면 디플로이먼트 삭제



1

디플로이 먼트 삭제

kubectl delete deploy nginx-deployment




다음


실습6. EKS 서비스,CLB, NLB 실습



https://brunch.co.kr/@topasvga/1868


keyword
매거진의 이전글EKS 4탄-4. Amazon EKS 네트워크-4/17