brunch

You can make anything
by writing

C.S.Lewis

by Master Seo Aug 30. 2021

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

실습 4탄 = 5/17

<1> 서비스 확인

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

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

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

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

<10> 다음편 , 실습4-6. EKS 서비스,CLB, NLB 실습




<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로 분산 된다.




<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-view  설치  안됨. 아래버전 안됨.


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


기존에 한번 설치했다면 다른 이름으로  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분 소요)



웹브라우저로  접속

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









7

proxy pod는 어디 있는지 확인?


proxy 라고 조회



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




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=3

kubectl scale deployment nginx-deployment --replicas=30




7

명령 서버에서 pending 확인 ?

kubectl get pods | grep Pending


2개가 Pending 되어 있다.

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

-> 2개 pending


(t6-admin@myeks:default) [root@myeks-host ~]# kubectl get pods | grep Pending

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

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




8

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



9

이유 확인 ?

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

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


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.





10

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

IP부족한 경우이다. 

기타 , 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> 사용하지 않으면 디플로이먼트 삭제



디플로이 먼트 삭제

kubectl delete deploy nginx-deployment



2

사용하지 않으면 kube-ops-view 삭제

helm delete kube-ops-view




<10> 다음은  실습6. EKS 서비스,CLB, NLB 실습



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



감사합니다.

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