목차
1. 기본 네트워크 환경 확인
    1.1. 네트워크 기본 정보 확인
    1.2. 워커 노드의 네트워크 정보 확인
    1.3. 테스트용 파드 생성 및 확인
2. 파드 통신 확인
    2.1. 노드 간 파드 통신
    2.2. 파드에서 외부 인터넷 통신 확인
    2.3. 테스트용 파드 삭제
3. 최대 파드 생성 확인
    3.1. kube-ops-view 설치
    3.2. 최대 파드 생성 및 확인


1. 기본 네트워크 환경 확인


이번 실습은 Amazon EKS 원클릭 배포 환경에서 진행합니다.
인프라 배포를 진행하지 않은 경우 링크를 통해 배포 후 복귀 바랍니다.


1.1. 네트워크 기본 정보 확인

Amazon VPC CNI 구성 환경에서 기본적인 네트워크 정보를 확인합니다.


Daemonset 정보 확인

1
2
3
4
5
6
7
8
// kube-system의 daemonset 확인
kubectl get daemonset -n kube-system

// vpc-cni 정보 확인
kubectl describe daemonset aws-node -n kube-system | grep Image | cut -d "/" -f 2

// kube-proxy config 확인
kubectl describe cm -n kube-system kube-proxy-config


워커 노드 IP와 파드 IP 확인

1
2
3
4
5
// 워커 노드 IP 확인
aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,PrivateIPAdd:PrivateIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output table

// 파드 IP 확인
kubectl get pod -n kube-system -o=custom-columns=NAME:.metadata.name,IP:.status.podIP,STATUS:.status.phase



1.2. 워커 노드의 네트워크 정보 확인


워커 노드에 사용할 도구 설치

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//  3대의 워커노드의 Private IP 주소 변수 저장
N1=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2a -o jsonpath={.items[0].status.addresses[0].address})
N2=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2b -o jsonpath={.items[0].status.addresses[0].address})
N3=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2c -o jsonpath={.items[0].status.addresses[0].address})
echo "export N1=$N1" >> /etc/profile
echo "export N2=$N2" >> /etc/profile
echo "export N3=$N3" >> /etc/profile
echo $N1, $N2, $N3

// 3대의 워커 노드에 사용할 도구 설치
ssh ec2-user@$N1 sudo yum install links tree jq tcpdump -y

ssh ec2-user@$N2 sudo yum install links tree jq tcpdump -y

ssh ec2-user@$N3 sudo yum install links tree jq tcpdump -y


워커 노드에 네트워크 정보 확인

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 워커 노드 1에서 vpc-cni 정보 확인
ssh ec2-user@$N1 tree /var/log/aws-routed-eni

ssh ec2-user@$N1 cat /var/log/aws-routed-eni/plugin.log | jq

ssh ec2-user@$N1 cat /var/log/aws-routed-eni/ipamd.log | jq

// 워커 노드 1에서 네트워크 정보 확인
ssh ec2-user@$N1 sudo ip -br -c addr

ssh ec2-user@$N1 sudo ip -c route

// coreDNS 파드 정보 확인
kubectl get pod -n kube-system -l k8s-app=kube-dns -owide

Note: coreDNS 파드가 2개 생성되는데 어느 워커 노드에 생성될지 랜덤합니다. 영상에서는 워커 노드 1, 2에 배포되는 상황인데 혹시 다른 워커 노드에 배포되었다면 아래 실습부터 확인 대상의 워커 노드가 다를 수 있습니다.



1.3. 테스트용 파드 생성 및 확인

테스트용으로 netshoot 파드를 3대 생성하고 관련 정보를 확인합니다.


신규 터미널 3개에 워커 노드 모니터링 수행

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 워커 노드1의 모니터링
ssh ec2-user@$N1

watch -d "ip link | egrep 'eth|eni' ;echo;echo "[ROUTE TABLE]"; route -n | grep eni"

// 워커 노드2의 모니터링
ssh ec2-user@$N2

watch -d "ip link | egrep 'eth|eni' ;echo;echo "[ROUTE TABLE]"; route -n | grep eni"

// 워커 노드3의 모니터링
ssh ec2-user@$N3

watch -d "ip link | egrep 'eth|eni' ;echo;echo "[ROUTE TABLE]"; route -n | grep eni"

Note: 신규 터미널을 3개 추가하고 작업용 인스턴스에 진입한 후 워커 노드 1, 2, 3으로 각각 SSH 접근을 합니다.


테스트용 netshoot 파드 3대 생성

테스트용 파드는 간단한 디버깅이나 테스트를 수행하는 용도의 netshoot이라는 컨테이너 이미지를 사용합니다. 참고 링크: nicolaka/netshoot

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
cat <<EOF | kubectl create -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: netshoot-pod
spec:
  replicas: 3
  selector:
    matchLabels:
      app: netshoot-pod
  template:
    metadata:
      labels:
        app: netshoot-pod
    spec:
      containers:
      - name: netshoot-pod
        image: nicolaka/netshoot
        command: ["tail"]
        args: ["-f", "/dev/null"]
      terminationGracePeriodSeconds: 0
EOF


테스트용 파드 이름 변수 저장

1
2
3
4
5
6
// 파드 이름을 변수에 저장
PODNAME1=$(kubectl get pods -o custom-columns=:.metadata.name,PodIP:status.podIP | grep 192.168.1. | cut -c -29)

PODNAME2=$(kubectl get pods -o custom-columns=:.metadata.name,PodIP:status.podIP | grep 192.168.2. | cut -c -29)

PODNAME3=$(kubectl get pods -o custom-columns=:.metadata.name,PodIP:status.podIP | grep 192.168.3. | cut -c -29)


테스트용 파드 exec 접속 후 네트워크 정보 확인

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 테스트용 파드 1에 zsh 접근
kubectl exec -it $PODNAME1 -- zsh

// 테스트용 파드에 인터페이스 및 IP 확인
kubectl exec -it $PODNAME1 -- ip -br -c addr

kubectl exec -it $PODNAME2 -- ip -br -c addr

kubectl exec -it $PODNAME3 -- ip -br -c addr

// 테스트용 파드 1에서 다른 파드로 ping 테스트
kubectl exec -it $PODNAME1 -- ping -c 2 [POD-2_IP]

kubectl exec -it $PODNAME1 -- ping -c 2 [POD-3_IP]




2. 파드 통신 확인


앞서 생성한 파드에서 다른 노드에 위치한 파드로 통신하거나 외부 인터넷 구간으로 통신할 때 동작을 실습으로 확인합니다.


2.1. 노드 간 파드 통신


파드 IP 변수 지정

1
2
3
4
5
6
7
8
9
10
11
// 생성된 각 파드의 IP 주소를 변수로 지정
PODIP1=$(kubectl get pods -o custom-columns=:.metadata.name,PodIP:status.podIP | grep 192.168.1. | cut -c 33-)

PODIP2=$(kubectl get pods -o custom-columns=:.metadata.name,PodIP:status.podIP | grep 192.168.2. | cut -c 33-)

PODIP3=$(kubectl get pods -o custom-columns=:.metadata.name,PodIP:status.podIP | grep 192.168.3. | cut -c 33-)

// 파드 IP 확인 및 변수 호출
kubectl get pods -o custom-columns=PodNAME:.metadata.name,PodIP:status.podIP

echo $PODIP1, $PODIP2, $PODIP3


신규 터미널 3개에 tcpdump 수행

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 워커 노드1의 모든 인터페이스에 tcpdump
ssh ec2-user@$N1

sudo tcpdump -i any -nn icmp

// 워커 노드2의 모든 인터페이스에 tcpdump
ssh ec2-user@$N2

sudo tcpdump -i any -nn icmp

// 워커 노드3의 모든 인터페이스에 tcpdump
ssh ec2-user@$N3

sudo tcpdump -i any -nn icmp


파드 간 ping 테스트

1
2
3
4
5
6
7
8
// 파드1에서 파드2로 ping
kubectl exec -it $PODNAME1 -- ping -c 2 $PODIP2

// 파드1에서 파드3으로 ping
kubectl exec -it $PODNAME1 -- ping -c 2 $PODIP3

// 파드2에서 파드3으로 ping
kubectl exec -it $PODNAME2 -- ping -c 2 $PODIP3


파드와 노드의 라우팅 확인

1
2
3
4
5
6
7
8
9
// 파드 1에서 라우팅 확인
kubectl exec -it $PODNAME1 -- ip -br addr

kubectl exec -it $PODNAME1 -- ip route show table main

// 워커 노드에서 라우팅 확인
ssh ec2-user@$N1 sudo ip route show table main

ssh ec2-user@$N3 sudo ip route show table main


2.2. 파드에서 외부 인터넷 통신 확인


신규 터미널에 tcpdump 수행

1
2
3
4
// 워커 노드1의 모든 인터페이스에 tcpdump
ssh ec2-user@$N1

sudo tcpdump -i any -nn icmp


파드 1에서 외부 인터넷 통신

1
2
// google.com으로 ping
kubectl exec -it $PODNAME1 -- ping -c 1 www.google.com


파드와 워커 노드의 공인 IP 확인

1
2
3
4
5
// 파드 1의 공인 IP 주소 확인
kubectl exec -it $PODNAME1 -- curl -s ipinfo.io/ip ; echo

// 워커 노드 1의 공인 IP 주소 확인
ssh ec2-user@$N1 curl -s ipinfo.io/ip ; echo


워커 노드 1의 NAT 테이블 확인

1
2
3
4
5
6
7
// 워커 노드 1에서 NAT 테이블 확인
ssh ec2-user@$N1 sudo iptables -L -n -v -t nat

// 워커 노드 1에서 NAT Rule List 확인
ssh ec2-user@$N1 sudo iptables -t nat -S

ssh ec2-user@$N1 sudo iptables -t nat -S | grep 'A AWS-SNAT-CHAIN'


2.3. 테스트용 파드 삭제


테스트용 파드 삭제

1
kubectl delete deploy netshoot-pod




3. 최대 파드 생성 확인


앞선 실습 환경에서 다수의 파드를 생성하여 최대 파드 생성 개수를 확인합니다.


3.1. kube-ops-view 설치

실습의 이해를 돕기 위해 kube-ops-view라는 가시성 도구를 설치합니다.
해당 도구를 통해 워커 노드에 구성된 파드 정보를 쉽게 확인할 수 있습니다.


kube-ops-view 설치

1
2
3
4
5
6
7
8
9
// kube-ops-view 설치
helm repo add geek-cookbook https://geek-cookbook.github.io/charts/

helm install kube-ops-view geek-cookbook/kube-ops-view --version 1.2.2 --set env.TZ="Asia/Seoul" --namespace kube-system

kubectl patch svc -n kube-system kube-ops-view -p '{"spec":{"type":"LoadBalancer"}}'

// kube-ops-view 접속 URL 확인 (1.5 배율)
kubectl get svc -n kube-system kube-ops-view -o jsonpath={.status.loadBalancer.ingress[0].hostname} | awk '{ print "KUBE-OPS-VIEW URL = http://"$1":8080/#scale=1.5"}'

Note: 위 출력되는 kube-ops-view URL로 인터넷 브라우저에서 접속합니다.


3.2. 최대 파드 생성 및 확인


워커 노드의 인스턴스 정보 확인

1
2
3
4
5
6
7
8
9
10
11
12
// t3 타입의 인스턴스 정보 (최대 ENI 수량, 최대 IP 수량)
aws ec2 describe-instance-types --filters Name=instance-type,Values=t3.* \
 --query "InstanceTypes[].{Type: InstanceType, MaxENI: NetworkInfo.MaximumNetworkInterfaces, IPv4addr: NetworkInfo.Ipv4AddressesPerInterface}" \
 --output table

// m5 타입의 인스턴스 정보 (최대 ENI 수량, 최대 IP 수량)
aws ec2 describe-instance-types --filters Name=instance-type,Values=m5.* \
 --query "InstanceTypes[].{Type: InstanceType, MaxENI: NetworkInfo.MaximumNetworkInterfaces, IPv4addr: NetworkInfo.Ipv4AddressesPerInterface}" \
 --output table

// 워커 노드의 상세 정보 확인 (Allocatable - pods)
kubectl describe node | grep Allocatable: -A7


최대 파드 생성 관련 모니터링(신규 터미널 2개)

1
2
3
4
5
6
7
// 신규 터미널 1 - 워커 노드 1에서 인터페이스 정보 모니터링
ssh ec2-user@$N1

while true; do ip -br -c addr show && echo "--------------" ; date "+%Y-%m-%d %H:%M:%S" ; sleep 1; done

// 신규 터미널 2 - 작업용 인스턴스에서 파드 정보 모니터링
watch -d 'kubectl get pods -o wide'


최대 파드 생성 작업

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 디플로이먼트 생성 (최초 2대)
curl -s -O https://raw.githubusercontent.com/cloudneta/cnaeblab/master/_data/nginx-dp.yaml

kubectl apply -f nginx-dp.yaml

// 파드 수량 8대로 변경 (replicas)
kubectl scale deployment nginx-deployment --replicas=8

// 파드 수량 30대로 변경 (replicas)
kubectl scale deployment nginx-deployment --replicas=30

// 파드 수량 3대로 변경 (replicas)
kubectl scale deployment nginx-deployment --replicas=3

// 파드 수량 50대로 변경 (replicas)
kubectl scale deployment nginx-deployment --replicas=50


파드 초과 생성으로 대기 중인 파드 확인

1
2
3
4
5
// 대기 중인 파드 확인
kubectl get pods | grep Pending

// 대기 중인 파드 지정하여 정보 확인
kubectl describe pod [대기 파드 이름]


디플로이먼트 삭제

1
2
// 디플로이먼트 삭제
kubectl delete deploy nginx-deployment


Warning: 다음 섹션의 실습을 이어서 진행할 것으로 Amazon EKS 원클릭 배포를 유지합니다. 혹시나 다음 섹션을 진행하지 않을 경우 Amazon EKS 원클릭 배포를 삭제해 주길 바랍니다.



여기까지 2장의 Amazon VPC CNI 실습을 마칩니다.
수고하셨습니다 :)