CloudNetaStudy - Kubernets Networtk 3기 실습 스터디 게시글입니다.
10. Cilium Egress Gateway
- Egress Gateway
- Egress IP Gateway 소개
- 특정 파드들을 특정 Egress GW(특정 IP)를 고정으로 외부(혹은 특정 대역)와 통신을 설정할 수 있다
- Egress IP Gateway 를 활성화하고 Egress SNAT 정책 설정
https://isovalent.com/blog/post/2021-12-release-111#egress-gateway-improvements
- 설정 - 링크
- 요구조건 : The egress gateway requires BPF masquerading, which itself requires BPF NodePort to be enabled.
- 테스트를 위한 웹서버와 파드 생성
- k8s-pc, k8s-rtr 에 웹서버 정보 확인
k8s-pc, k8s-rtr # 웹서버 접근 테스트 curl localhost <h1>Web Server : k8s-pc</h1> # 웹 접속 로그 실시간 출력 tail -f /var/log/apache2/access.log 192.168.10.10 - - [01/Dec/2021:23:35:24 +0000] "GET / HTTP/1.1" 200 264 "-" "curl/7.74.0"
- 파드 생성 및 웹 접속 테스트 ⇒ mediabot 파드는 CRI(containerd) 사용 시 별도의 파일시스템 설치가 필요하여, CRI(docker)로 실습을 권장한다
# 파드 생성 kubectl create -f https://raw.githubusercontent.com/cilium/cilium/1.11.2/examples/kubernetes-dns/dns-sw-app.yaml # 파드 확인 kubectl get pod -o wide # 파드에서 nginx 접속 >> k8s-pc 웹서버 접속 시 클라이언트 IP가 어떻게 찍히나요? kubectl exec mediabot -- curl -s 192.168.20.100 kubectl exec mediabot -- curl -s 192.168.10.254 kubectl exec mediabot -- curl -s wttr.in/seoul # (옵션) 외부 웹서버 접속 테스트 kubectl exec mediabot -- curl -s wttr.in/seoul?format=3 kubectl exec mediabot -- curl -s wttr.in/seoul?format=4 kubectl exec mediabot -- curl -s 'wttr.in/{London,Busan}' kubectl exec mediabot -- curl -s ipinfo.io kubectl exec mediabot -- curl -s ipinfo.io/city kubectl exec mediabot -- curl -s ipinfo.io/loc kubectl exec mediabot -- curl -s ipinfo.io/org
- k8s-pc, k8s-rtr 에 웹서버 정보 확인
- Configure Egress IPs
- 인터페이스 모니터링 걸어두기 (Egress GW 가 생성된 워커노드에)
# k8s-w1 , k8s-w2 watch -d 'ip -4 addr show enp0s8'
- Egress GW 배포 - EGRESS_IPS 범위 지정 : 예시) 192.168.10.240/24 192.168.10.241/24
cat <<EOF | kubectl create -f - apiVersion: apps/v1 kind: Deployment metadata: name: "egress-ip-assign" labels: name: "egress-ip-assign" spec: replicas: 1 selector: matchLabels: name: "egress-ip-assign" template: metadata: labels: name: "egress-ip-assign" spec: affinity: # the following pod affinity ensures that the "egress-ip-assign" pod # runs on the same node as the mediabot pod podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: class operator: In values: - mediabot - key: org operator: In values: - empire topologyKey: "kubernetes.io/hostname" hostNetwork: true containers: - name: egress-ip image: docker.io/library/busybox:1.31.1 command: ["/bin/sh","-c"] securityContext: privileged: true env: - name: EGRESS_IPS value: "192.168.10.240/24 192.168.10.241/24" args: - "for i in \$EGRESS_IPS; do ip address add \$i dev enp0s8; done; sleep 10000000" lifecycle: preStop: exec: command: - "/bin/sh" - "-c" - "for i in \$EGRESS_IPS; do ip address del \$i dev enp0s8; done" EOF
# 설정 후 k8s-w2 확인 ip -c -4 addr show enp0s8 3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 inet 192.168.10.102/24 brd 192.168.10.255 scope global enp0s8 valid_lft forever preferred_lft forever inet 192.168.10.240/24 scope global secondary enp0s8 valid_lft forever preferred_lft forever inet 192.168.10.241/24 scope global secondary enp0s8 valid_lft forever preferred_lft forever # iptables nat 에 특별한 chain/rule 이 없다 iptables -t nat -S
- 인터페이스 모니터링 걸어두기 (Egress GW 가 생성된 워커노드에)
- Create Egress NAT Policy
- 192.168.20.100/32 목적지와 통신 할 때는 egressSourceIP 를 192.168.10.240 를 사용!
- 참고로 destinationCIDRs: 가 0.0.0.0/0 일 경우 모든 네트워크를 의미한다
cat <<EOF | kubectl apply -f - apiVersion: cilium.io/v2alpha1 kind: CiliumEgressNATPolicy metadata: name: egress-sample spec: egress: - podSelector: matchLabels: org: empire class: mediabot io.kubernetes.pod.namespace: default destinationCIDRs: - 192.168.20.100/32 egressSourceIP: "192.168.10.240" EOF
- 통신 확인 및 추가 테스트
# 파드에서 nginx 접속 : policy 에 맞게 지정된 ip가 출력 kubectl exec mediabot -- curl -s 192.168.20.100 ## 로그 확인 root@k8s-pc:~# tail -f /var/log/apache2/access.log 172.16.2.242 - - [28/Feb/2022:12:32:37 +0000] "GET / HTTP/1.1" 200 256 "-" "curl/7.52.1" 192.168.10.200 - - [29/Nov/2021:17:48:26 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.52.1" # 파드에서 nginx 접속 : policy 에 정의된 목적지가 아니여서 파드 ip 출력 kubectl exec mediabot -- curl -s 192.168.10.254 ## 로그 확인 root@k8s-rtr:~# tail -f /var/log/apache2/access.log 127.0.0.1 - - [28/Feb/2022:12:30:27 +0000] "GET / HTTP/1.1" 200 257 "-" "curl/7.74.0" 172.16.2.238 - - [29/Nov/2021:17:45:06 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.52.1" 172.16.2.238 - - [29/Nov/2021:17:45:06 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.52.1" # 파드에서 외부 접속 kubectl exec mediabot -- curl -s wttr.in/busan kubectl exec mediabot -- curl -s wttr.in/busan?format=4
- 신규 추가 파드로 테스트
cat <<EOF | kubectl create -f - apiVersion: v1 kind: Pod metadata: name: net-pod labels: org: empire class: mediabot spec: nodeName: k8s-w1 containers: - name: netshoot-pod image: nicolaka/netshoot command: ["tail"] args: ["-f", "/dev/null"] terminationGracePeriodSeconds: 0 EOF
- 신규 파드(워커노드1번 배치, labes 설정)로 접속 테스트
# 파드에서 nginx 접속 : policy 에 맞게 지정된 ip가 출력 kubectl exec net-pod -- curl -s 192.168.20.100 # 파드에서 nginx 접속 : policy 에 정의된 목적지가 아니여서 파드 ip 그래도 출력 kubectl exec net-pod -- curl -s 192.168.10.254 # (옵션) egress 파드가 있는 노드(예시. k8s-w2)에서 패킷덤프 >> 트래픽이 egress 를 항상 경유하는지, 아니면 파드에서 바로 목적지로 가는지 확인해보자! tcpdump -eni any tcp port 80 -q tcpdump -eni any tcp port 80 -q -v # 파드에서 외부 접속 kubectl exec net-pod -- curl -s wttr.in/busan?format=4 # (옵션) 외부 웹서버 접속 테스트
- 기존정책을 삭제하고 destinationCIDRs: 가 0.0.0.0/0 정책으로 생성
# 기존정책을 삭제 kubectl delete ciliumegressnatpolicies egress-sample # destinationCIDRs: 가 0.0.0.0/0 정책으로 생성 cat <<EOF | kubectl create -f - apiVersion: cilium.io/v2alpha1 kind: CiliumEgressNATPolicy metadata: name: egress-sample spec: egress: - podSelector: matchLabels: org: empire class: mediabot io.kubernetes.pod.namespace: default destinationCIDRs: - 0.0.0.0/0 egressSourceIP: "192.168.10.241" EOF
- 접속 테스트
- 예를 들면 0.0.0.0/0 설정 시, 특정 파드는 무조건 egressSourceIP 경유하는 통신을 하게 되므로 통신 트래픽 경로와 대역폭 등을 잘 고려하자. (심지어, 동일 노드 내의 파드 끼리도 모든 통신이 egressSourceIP 경유하게 될까요? 아닐까요?)# 파드에서 nginx 접속 : egressSourceIP 가 찍임! kubectl exec net-pod -- curl -s 192.168.20.100 # 파드에서 nginx 접속 : egressSourceIP 가 찍임! kubectl exec net-pod -- curl -s 192.168.10.254 kubectl exec mediabot -- curl -s 192.168.10.254 # 파드에서 외부 접속 kubectl exec mediabot -- curl -s http://ipinfo.io/ kubectl exec mediabot -- curl -s http://ipinfo.io/city # (옵션) egress 파드가 있는 노드(예시. k8s-w2)에서 패킷덤프 >> 트래픽이 egress 를 항상 경유하는지, 아니면 파드에서 바로 목적지로 가는지 확인해보자! tcpdump -eni any tcp port 80 -q tcpdump -eni any tcp port 80 -q -v
- 삭제
kubectl delete ciliumegressnatpolicies egress-sample kubectl delete deploy egress-ip-assign kubectl delete pod --all
'Kubernetes' 카테고리의 다른 글
[ Kans 3 Study - 9w ] 2. Service & AWS LoadBalancer Controller / Ingress (1) | 2024.11.02 |
---|---|
[ Kans 3 Study - 9w ] 1. AWS VPC CNI (6) | 2024.10.29 |
[ Kans 3 Study - 8w ] 2. Direct Server Return (DSR) / Network Policy (L3, L4, L7) / Bandwidth Manager / L2 Announcements / L2 Aware LB (Beta) (2) | 2024.10.27 |
[ Kans 3 Study - 8w ] 1. Cilium (2) | 2024.10.27 |
[ Kans 3 Study - 8w ] 실습 환경 구성 (0) | 2024.10.27 |