systemctl stop firewalld 하면 서비스 접속이 되고, 올리면 안 된다. 443 을 열어 뒀는데도 마찬가지다.
kubectl get svc 출력의 PORT(S) 를 정확히 읽어야 한다.
ingress-nginx ingress-nginx-controller NodePort 10.96.123.45 <none> 80:31234/TCP,443:32443/TCP
443:32443 은 "서비스 포트 443, 노드 포트 32443" 이라는 뜻이다. 클러스터 밖에서 들어오는 트래픽은 노드의 32443 으로 들어온다. 443 은 클러스터 내부에서만 의미가 있는 번호이므로 방화벽에서 443 을 열어도 통과하지 못한다.
NodePort 는 기본 범위가 30000-32767 이며 kube-apiserver 의 --service-node-port-range 로 정해진다.
kubectl get svc -A | grep NodePort
ss -lntp | grep 32443
ss 에 해당 포트를 여는 프로세스(kube-proxy 또는 컨트롤러)가 보이는지까지 확인하면 서비스 쪽 문제와 방화벽 문제를 구분할 수 있다.
# 실제로 쓰는 포트만 여는 방식
firewall-cmd --permanent --add-port=32443/tcp
firewall-cmd --permanent --add-port=31234/tcp
# 운영 편의를 위해 범위를 통째로 여는 방식
firewall-cmd --permanent --add-port=30000-32767/tcp
firewall-cmd --reload
firewall-cmd --list-all
zone 을 확인한다. 규칙을 넣은 zone 과 인터페이스가 속한 zone 이 다르면 아무 효과가 없다.
firewall-cmd --get-active-zones
firewall-cmd --zone=public --permanent --add-port=32443/tcp
UDP 서비스는 프로토콜을 따로 지정해야 한다. 이름이 정의된 서비스는 포트 대신 이름을 쓸 수 있다.
firewall-cmd --permanent --add-port=53/udp
firewall-cmd --permanent --add-service=https
firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=10.0.0.0/8 port port=32443 protocol=tcp accept'
--permanent 없이 넣은 규칙은 --reload 나 재시작에 사라진다. 반대로 --permanent 로만 넣고 --reload 를 하지 않으면 지금은 적용되지 않는다. 시험할 때는 임시로 넣어 확인하고, 되면 --permanent 로 다시 넣는 순서가 안전하다.
80:80/TCP, 443:443/TCP 처럼 양쪽이 같으면 NodePort 구조가 아니다. 컨트롤러 파드가 hostNetwork: true 이거나 hostPort 로 노드의 포트를 직접 잡고 있는 것이다.
kubectl -n ingress-nginx get deploy ingress-nginx-controller -o yaml | egrep -i 'hostNetwork|hostPort'
이 구조에서는 노드의 80 · 443 을 그대로 열면 된다.
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload
특징을 알고 선택해야 한다. 사용자가 포트 번호 없이 접속할 수 있어 편하지만, 노드 한 대의 포트를 점유하므로 같은 노드에 컨트롤러 복제본을 둘 수 없고 그 노드가 죽으면 진입점이 사라진다. 앞단에 L4 로드밸런서나 MetalLB 를 두면 NodePort 를 쓰면서도 사용자에게는 443 만 노출할 수 있다.
포트 문제와 별개로, firewalld 가 재시작되면서 kube-proxy 나 CNI 가 넣어 둔 iptables 규칙이 밀려나 파드 사이 통신이 끊기는 경우가 있다. 노드 전체가 이상해졌다면 규칙 순서를 확인하고 kube-proxy 를 다시 띄워 규칙을 재생성시킨다.
iptables -t nat -L -n | grep 32443
kubectl -n kube-system rollout restart daemonset kube-proxy
클러스터 노드에서 firewalld 와 CNI 를 함께 쓰는 구성은 배포판 · CNI 조합에 따라 권장 여부가 다르다. 설치 문서가 특정 포트 목록을 제시한다면 그쪽을 따른다.