Amazon EKS 네트워킹 둘러보기

1. Amazon EKS 네트워킹

[Amazon EKS 네트워킹 설명 장표]

2. Amazon EKS 네트워킹 둘러보기

우리가 배포한 Amzon EKS 클러스터의 network-testing 네임스페이스에는 Network MultiTool이라는 컨테이너가 포함된 Pod가 실행되어 있습니다. 이 컨테이너는 네트워크 관련 유틸리티를 포함하고 있어서 네트워크 테스트를 수행할 때 유용합니다.

또한 이 포드에 외부에서 접근할 수 있도록 ServiceIngress 리소스를 생성하였습니다. 이를 통해 외부에서 Network MultiTool에 접근할 수 있습니다.

이번 섹션에서는 Network MultiTool을 통해 외부 <-> 내부 트래픽 (aka. North-South Traffic)이 리눅스 커널 객체인 Netfilter Iptables Rule를 통해 어떻게 처리되는지 살펴보겠습니다.

우선 해당 사항을 확인하기 쉽게 도와주는 LoadBalancer 타입의 Service 객체를 생성하도록 하겠습니다. LoadBalancer 타입의 Service 객체는 자동으로 NodePort 타입의 Service 객체를 생성하고, 이를 통해 외부에서 Pod에 접근할 수 있도록 해 주는데 이를 위해 Netfilter Iptables Rule을 노드 레벨로 생성해 줍니다.

3. LoadBalancer 타입의 Service 생성 및 테스트

  1. LoadBalancer 타입의 Service 생성 아래 명령을 실행하여 LoadBalancer 타입의 Service를 생성합니다.

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
  name: network-multitool-lb
  namespace: network-testing
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: external
    service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: instance
    service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
spec:
  externalTrafficPolicy: Local
  type: LoadBalancer
  selector:
    app: network-multitool
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
EOF

위 명령이 정상적으로 실행되면 LoadBalancer 타입의 Service가 생성되고, Network MultiTool에 접근할 수 있는 DNS Name을 가진 Network Load Balancer가 생성됩니다.

  • LoadBalancer 타입의 Service 생성을 확인합니다.

  • Network MultiTool에 접근할 수 있는 DNS Name을 확인합니다.

  1. 생성된 ServiceNetwork Load Balancer를 통해 Network MultiTool 접속 확인 아래 명령으로 해당 Network Load Balancer를 통해 서비스에 정상적으로 접속되는지 확인합니다.

# "LoadBalancer" 타입의 서비스의 DNS Name을 확인하고 "EXTERNAL-IP" 필드의 값을 추출합니다.
export NETWORK_TOOL_SERVER=`kubectl get service network-multitool-lb -n network-testing -o json | jq --raw-output '.status.loadBalancer.ingress[0].hostname'`
echo "NETWORK_TOOL_SERVER: ${NETWORK_TOOL_SERVER}"

watch -n 1 'curl -s http://${NETWORK_TOOL_SERVER} | grep "Praqma Network MultiTool (with NGINX)"'

위의 watch 명령을 실행해 둔 상태로 다음 과정을 진행합니다.

  1. (Optional) Network Load BalancerENIPrivate IP 정보 확인 아래는 위에서 externalTrafficPolicy: Cluster로 설정하였거나 명시하지 않았을 경우 필요한 정보를 확인합니다.

# Get the ARN of the load balancer
LB_ARN=$(aws elbv2 describe-load-balancers --names "k8s-networkt-networkm-20eddd665b" --query 'LoadBalancers[0].LoadBalancerArn' --output text) && echo $LB_ARN
# Extract 3rd and 4th field delimited by "/".
LB_ARN_FOR_ENI=$(echo $LB_ARN | cut -d'/' -f3-4) && echo $LB_ARN_FOR_ENI

# Get the network interfaces of the load balancer
ENI_IDS=$(aws ec2 describe-network-interfaces --filters Name=description,Values="ELB net/${LB_ARN_FOR_ENI}*" --query 'NetworkInterfaces[].NetworkInterfaceId' --output text) && echo $ENI_IDS

# Get the internal IP addresses of the network interfaces
for ENI_ID in $ENI_IDS
do
  aws ec2 describe-network-interfaces --network-interface-ids $ENI_ID --query 'NetworkInterfaces[].PrivateIpAddress' --output text
done

(참고) 위 명령을 통해 조회되는 Network Load BalancerENI 정보는 아래 AWS 콘솔 화면을 통해서도 확인할 수 있습니다. Network Load Balancer ENI

  1. Network Multitool Pod에 접근하여 tcpddump 상태 확인 k9skubectl exec 명령을 사용하여 Network MultiTool Pod에 접근하여 tcpdump 상태를 확인합니다. 구동 중인 2개의 포드 모두에 로그인하여 확인합니다.

# 먼저 작업하고 있는 `Cloud9`의 Public IP를 확인합니다.
curl http://checkip.amazonaws.com

#kubectl exec -it <pod-name> -- /bin/bash

tcpdump -i eth0 src <위에서 확인한 Puublic IP 주소> and dst port 80
# 예) tcpdump -i eth0 src 3.35.18.144 and dst port 80
  1. (도전 과제) 위 1에서 externalTrafficPolicy: Local 부분을 주석으로 비활성화하고 적용한 다음 (kubectl apply) 테스트를 수행해 보면 어떻게 될까요?

4. 워커노드에 접근하여 Netfilter Iptables Rule 확인

AWS 콘솔 > EC2 > 인스턴스 > 인스턴스를 속성 또는 태그로 찾기에서 Production을 입력하여 Production 환경의 워커노드 만을 표시 > 하나의 인스턴스를 선택 > 선택 버튼 클릭

Sesson Manager > 연결을 눌러 해당 워커노드에 접속합니다.

접속되면 bash 명령을 입력하여 Bourne Again Shell로 전환합니다.

아래 명령을 실행하면서 Netfilter Iptables Rule을 확인합니다.

  • KUBE-NODEPORT 체인 테이블 확인 KUBE-NODEPORTS 체인 테이블 전체를 확인합니다.

    sudo iptables -t nat -L KUBE-NODEPORTS -n | column -t
  • network-testing/network-multitool-lb 서비스의 External-To-Local 체인 테이블을 확인합니다.

    sudo iptables -t nat -L KUBE-EXT-JUXT5CKLQ4YYVCR4 -n | column -t
  • network-testing/network-multitool-lb 서비스의 Pod 서비스 체인 테이블을 확인합니다.

    sudo iptables -t nat -L KUBE-SVC-JUXT5CKLQ4YYVCR4 -n | column -t

    위에서 표시된 두 개의 IP 주소가 network-multitoolPod의 (2개) IP 주소와 일치하는지 확인합니다.

  • 마지막으로 KUBE-SEP 체인 테이블을 확인합니다.

    sudo iptables -t nat -L KUBE-SEP-UCOTLU3KF2K5ONRC -n | column -t

    위에서 얻어진 iptables 체인 테이블의 맥락에서, DNAT 규칙은 들어오는 트래픽의 목적지 IP 주소를 network-testing/network-multitool-lb 서비스의 포드 IP 주소로 변경하는 데 사용됩니다. 규칙의 to:10.220.5.147:80 부분은 목적지 IP 주소가 10.220.5.147로 변경되고 목적지 포트가 80으로 변경됨을 나타냅니다.

(참고) 전체 Service 객체에 의해 생성된 Netfilter Iptables Rule을 확인하고 위와 유사하게 Drill-Down하여 확인할 수 있습니다.

sudo iptables -t nat -L KUBE-SERVICES -n  | column -t

(참고) 모든 Chain Table 룰을 표시하는 명령어는 다음과 같습니다.

sudo iptables -t nat -L

5. Kubernetes 서비스의 Iptables 예시 - NodePort 타입의 Netfilter Iptables Chain Table

Last updated