Public Cloud의 Kubernetes(예: AWS AKS, Azure AKS, Oracle OKE 등)을 사용하다보면,
Public Network에서 들어오는 UDP 트래픽을 Network LB(NLB)가 처리하지 못하는 것처럼 보일 때가 있다.
예를 들어 아래와 같은 Service Manifest를 적용했다고 가정해보자.
apiVersion: v1
kind: Service
metadata:
name: almighty
annotations:
oci.oraclecloud.com/load-balancer-type: "nlb" # <- 이 내용을 추가해야 한다.
spec:
selector:
app: almighty
ports:
- name: myweb
protocol: TCP
port: 8080
targetPort: 8080
- name: yourweb
protocol: TCP
port: 80
targetPort: 80
- name: myudp
protocol: UDP # <- 테스트를 위해 UDP를 추가한다.
port: 9090
targetPort: 9090
type: LoadBalancer # <- Service Type을 LoadBalancer로 설정한다.
위 Service Manifest를 적용하면, External-IP 항목이 Public IP 값으로 설정되지만 실제로 Pod로 UDP 트래픽이 전달되지 못하는 현상이 생길 것이다.
왜 이런 문제가 생길까?
Public Network에서 유입되는 UDP 트래픽이 Pod에 전달되지 못하는 정확한 원인은 아래와 같다.
Public Cloud Service 제공사가 제공하는 NLB(Network Load Balancer)는 제대로 UDP 트래픽을 처리한 것이 맞다.
단지, Cloud Infra가 제공하는 K8S Node의 Security Rule에 의해서 UDP 트래픽이 Block되는 것이다.
따라서 Security Rule에 UDP 트래픽이 Pass 되도록 Rule을 추가하기만 하면 된다. (즉, Linux Firewall 설정 하듯이~)
AWS AKS, Azure AKS, Oracle OKE 모두 비슷하게 NLB가 UDP 트래픽을 처리하고 Security Rule도 비슷하기 때문에 Oracle의 OCI OKE만 이용해서 설명하면 아래와 같다.
아래의 순서로 메뉴/화면을 찾아서 들어간다.
[ Kubernetes Clusters (OKE) ]
-> Clusters 화면에서 특정 Cluster의 VCN을 선택/클릭한다.
-> VCN을 클릭하면, 여러개의 Subnets이 목록이 보여지는데 oke-svclbsubnet-xxxx과 oke-nodesubnet-yyyy을 선택하여 Security Lists를 확인한다.
-> [ Security Lists ] 화면에 있는 Rule 이름을 선택한다.
-> [ Ingress Rules ]와 [ Egress Rules ] 화면에서 UDP, TCP 트래픽을 모두 허용하도록 Rule을 추가한다.
예를 들어, 115.33.55.0/24, 특정 UDP 포트(예: 9090), 특정 TCP 포트(예: 8080) 허용으로 설정하면 된다.
아래 화면을 참고~~~
이렇게 Security Rule을 추가하고, 다시 Public IP와 UDP 포트를 이용하여 트래픽을 보내보면, Pod 내부까지 UDP 트래픽이 잘 전달되는 것을 확인할 수 있다.
조심해야 할 사항:
Security Rule 설정하고, 40초 후에 Traffic Test해야 한다.
Node Security Rule이 적용되기 까지 40초가 걸리기 때문에 그 이후에 Traffic Test를 해야 제대로 Traffic이 Pod까지 전달된다.
생각해볼 내용:
Node Security List에 TCP Rule을 추가할 때, 왜 Egress Rule도 추가해야 하는지 잘 이해가 안 된다.
Cluster 외부에서 Ingress Rule에 따라 TCP Traffic을 허용해주면, ConnTrack DB에 Pin Hole 같은게 생기면서
TCP의 응답 패킷도 알아서 Pass(Forward)시켜주는게 일반적인 Traffic 처리가 아닐까라고 생각했는데... 이게 아닌가 보다.
아무튼 귀찮지만 Ingress에 추가한 Rule을 Egress에도 꼭 추가해야 한다. (잊지 말자 !!!)
참고하면 좋은 Web Docs
Oracle OCI Network Load Balancer 사용하기
https://thekoguryo.github.io/release-notes/20220315-support-for-oci-network-load-balancers/
위 문서는 간단하게 사용법 위주로 설명되어 있고, 아래 문서는 내부 동작에 관해 자세하게 내용을 다루고 있다.
특히, Service Manifest의 externalTrafficPolicy: local 방식에 관해 궁금하다면 아래 문서를 보는 것이 좋다.
https://blogs.oracle.com/cloud-infrastructure/post/network-load-balancer-support-on-oracle-kubernetes-engine
더 자세히 파고 들어가고 싶다면, Oracle 공식 Web Docs를 보길~~~
https://docs.oracle.com/en-us/iaas/Content/ContEng/Tasks/contengcreatingloadbalancer.htm