본문 바로가기

IT/Container&k8s

K8S Service : NodePort

안녕하세요. Kubernetes Advanced Networking Study(=KANS) 3기 모임에서 스터디한 내용을 정리했습니다. 해당 글에서는 k8s Service 중 NodePort에 대해 자세히 알아보겠습니다. 

 

NodePort 생성 배경

클러스터 외부에서는 서비스(ClusterIP)로 접속이 불가능하여 NodePort 타입으로 외부에서 접속 가능

 

NodePort

- 외부 클라이언트가 '노드IP:NodePort' 접속 시 해당 노드의 iptables Rule에 의해서 SNAT/DNAT 되어 목적지 파드와 통신 후 리턴 트래픽은 최초 인입 노드를 경유해서 외부로 되돌아감

- 모드 노드(마스터 포함)에 iptables rule 설정되므로, 모든 노드에 NodePort 로 접속 시 iptables rule 에 의해서 분산 접속이 됨

 

 

실습 구성

목적지(backend) 디플로이먼트(Pod) 파일 생성 : echo-deploy.yaml

cat <<EOT> echo-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-echo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: deploy-websrv
  template:
    metadata:
      labels:
        app: deploy-websrv
    spec:
      terminationGracePeriodSeconds: 0
      containers:
      - name: kans-websrv
        image: mendhak/http-https-echo
        ports:
        - containerPort: 8080
EOT

 

서비스(NodePort) 파일 생성 : svc-nodeport.yaml

cat <<EOT> svc-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
  name: svc-nodeport
spec:
  ports:
    - name: svc-webport
      port: 9000        # 서비스 ClusterIP 에 접속 시 사용하는 포트 port 를 의미
      targetPort: 8080  # 타킷 targetPort 는 서비스를 통해서 목적지 파드로 접속 시 해당 파드로 접속하는 포트를 의미
  selector:
    app: deploy-websrv
  type: NodePort
EOT

 

생성 및 확인

# 생성
kubectl apply -f echo-deploy.yaml,svc-nodeport.yaml

# 모니터링
watch -d 'kubectl get pod -owide;echo; kubectl get svc,ep svc-nodeport'

# 확인
kubectl get deploy,pod -o wide

NAME                          READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS    IMAGES                    SELECTOR
deployment.apps/deploy-echo   3/3     3            3           78s   kans-websrv   mendhak/http-https-echo   app=deploy-websrv

NAME                               READY   STATUS    RESTARTS   AGE   IP          NODE            NOMINATED NODE   READINESS GATES
pod/deploy-echo-5c689d5454-slrss   1/1     Running   0          78s   10.10.3.3   myk8s-worker3   <none>           <none>
pod/deploy-echo-5c689d5454-szdlb   1/1     Running   0          78s   10.10.2.3   myk8s-worker    <none>           <none>
pod/deploy-echo-5c689d5454-w9rvs   1/1     Running   0          78s   10.10.1.3   myk8s-worker2   <none>           <none>

#아래 30682는 서비스(Nodeport) 정보 
kubectl get svc svc-nodeport

NAME           TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGE
svc-nodeport   NodePort   10.200.1.73   <none>        9000:30682/TCP   82s

# Port , TargetPort , NodePort 각각의 차이점의 의미알
kubectl describe svc svc-nodeport

 

 

서비스(NodePort) 접속 확인

외부 클라이언트(mypc 컨테이너)에서 접속 테스트 & 서비스(NodePort) 부하분산 접속 확인

# NodePort 확인 : 아래 NodePort 는 범위내 랜덤 할당으로 실습 환경마다 다릅니다
kubectl get service svc-nodeport -o jsonpath='{.spec.ports[0].nodePort}'
30682

# NodePort 를 변수에 지정
NPORT=$(kubectl get service svc-nodeport -o jsonpath='{.spec.ports[0].nodePort}')
echo $NPORT

# 현재 k8s 버전에서는 포트 Listen 되지 않고, iptables rules 처리됨
for i in control-plane worker worker2 worker3; do echo ">> node myk8s-$i <<"; docker exec -it myk8s-$i ss -tlnp; echo; done
## (참고) 아래처럼 예전 k8s 환경에서 Service(NodePort) 생성 시, TCP Port Listen 되었었음
root@k8s-m:~# ss -4tlnp | egrep "(Process|$NPORT)"
State     Recv-Q    Send-Q        Local Address:Port        Peer Address:Port   Process
LISTEN    0         4096                0.0.0.0:30466            0.0.0.0:*       users:(("kube-proxy",pid=8661,fd=10))

# 파드 로그 실시간 확인 (웹 파드에 접속자의 IP가 출력)
kubectl logs -l app=deploy-websrv -f


# 외부 클라이언트(mypc 컨테이너)에서 접속 시도를 해보자
kubectl get nodes -owide
NAME                  STATUS   ROLES           AGE    VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                         KERNEL-VERSION      CONTAINER-RUNTIME
myk8s-control-plane   Ready    control-plane   6d4h   v1.31.0   172.18.0.4    <none>        Debian GNU/Linux 12 (bookworm)   5.10.124-linuxkit   containerd://1.7.18
myk8s-worker          Ready    <none>          6d4h   v1.31.0   172.18.0.5    <none>        Debian GNU/Linux 12 (bookworm)   5.10.124-linuxkit   containerd://1.7.18
myk8s-worker2         Ready    <none>          6d4h   v1.31.0   172.18.0.2    <none>        Debian GNU/Linux 12 (bookworm)   5.10.124-linuxkit   containerd://1.7.18
myk8s-worker3         Ready    <none>          6d4h   v1.31.0   172.18.0.3    <none>        Debian GNU/Linux 12 (bookworm)   5.10.124-linuxkit   containerd://1.7.18

# 노드의 IP와 NodePort를 변수에 지정
## CNODE=<컨트롤플레인노드의 IP주소>
## NODE1=<노드1의 IP주소>
## NODE2=<노드2의 IP주소>
## NODE3=<노드3의 IP주소>
CNODE=172.18.0.A
NODE1=172.18.0.B
NODE2=172.18.0.C
NODE3=172.18.0.D
CNODE=172.18.0.4
NODE1=172.18.0.5
NODE2=172.18.0.2
NODE3=172.18.0.3

NPORT=$(kubectl get service svc-nodeport -o jsonpath='{.spec.ports[0].nodePort}')
echo $NPORT

# 서비스(NodePort) 부하분산 접속 확인
docker exec -it mypc curl -s $CNODE:$NPORT | jq # headers.host 주소는 왜 그런거죠?
for i in $CNODE $NODE1 $NODE2 $NODE3 ; do echo ">> node $i <<"; docker exec -it mypc curl -s $i:$NPORT; echo; done

# 컨트롤플레인 노드에는 목적지 파드가 없는데도, 접속을 받아준다! 이유는?
docker exec -it mypc zsh -c "for i in {1..100}; do curl -s $CNODE:$NPORT | grep hostname; done | sort | uniq -c | sort -nr"
docker exec -it mypc zsh -c "for i in {1..100}; do curl -s $NODE1:$NPORT | grep hostname; done | sort | uniq -c | sort -nr"
docker exec -it mypc zsh -c "for i in {1..100}; do curl -s $NODE2:$NPORT | grep hostname; done | sort | uniq -c | sort -nr"
docker exec -it mypc zsh -c "for i in {1..100}; do curl -s $NODE3:$NPORT | grep hostname; done | sort | uniq -c | sort -nr"

# 아래 반복 접속 실행 해두자
docker exec -it mypc zsh -c "while true; do curl -s --connect-timeout 1 $CNODE:$NPORT | grep hostname; date '+%Y-%m-%d %H:%M:%S' ; echo ;  sleep 1; done"


# NodePort 서비스는 ClusterIP 를 포함
# CLUSTER-IP:PORT 로 접속 가능! <- 컨트롤노드에서 아래 실행 해보자
kubectl get svc svc-nodeport
NAME           TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
svc-nodeport   NodePort   10.111.1.238   <none>         9000:30158/TCP   3m3s

CIP=$(kubectl get service svc-nodeport -o jsonpath="{.spec.clusterIP}")
CIPPORT=$(kubectl get service svc-nodeport -o jsonpath="{.spec.ports[0].port}")
echo $CIP $CIPPORT
docker exec -it myk8s-control-plane curl -s $CIP:$CIPPORT | jq

# mypc에서 CLUSTER-IP:PORT 로 접속 가능할까?
docker exec -it mypc curl -s $CIP:$CIPPORT


# (옵션) 노드에서 Network Connection
conntrack -E
conntrack -L --any-nat

# (옵션) 패킷 캡쳐 확인
tcpdump..

 

외부 클라이언트 → 서비스(NodePort) 접속 시 : 3개의 목적지(backend) 파드로 랜덤 부하 분산 접속됨

 

웹 파드에서 접속자의 IP 정보 확인(logs) 시 외부 클라이언트IP 가 아닌, 노드의 IPSNAT 되어서 확인됨

 

 

IPTABLES 정책 확인

iptables 정책 적용 순서 : PREROUTING → KUBE-SERVICES → KUBE-NODEPORTS → KUBE-EXT-#(MARK)KUBE-SVC-# → KUBE-SEP-# ⇒ KUBE-POSTROUTING (MASQUERADE)KUBE-EXT-#(MARK) 규칙 과정 추가됨

 

컨트롤플레인 노드 - iptables 분석 << 정책 확인 : 아래 정책 내용은 핵심적인 룰(rule)만 표시함

docker exec -it myk8s-control-plane bash
----------------------------------------

# 패킷 카운트 초기화
iptables -t nat --zero


PREROUTING 정보 확인
iptables -t nat -S | grep PREROUTING
-A PREROUTING -m comment --comment "kubernetes service portals" -j KUBE-SERVICES
...


# 외부 클라이언트가 노드IP:NodePort 로 접속하기 때문에 --dst-type LOCAL 에 매칭되어서 -j KUBE-NODEPORTS 로 점프
iptables -t nat -S | grep KUBE-SERVICES
-A KUBE-SERVICES -m comment --comment "kubernetes service nodeports; NOTE: this must be the last rule in this chain" -m addrtype --dst-type LOCAL -j KUBE-NODEPORTS
...


# KUBE-NODEPORTS 에서 KUBE-EXT-# 로 점프
## -m nfacct --nfacct-name localhost_nps_accepted_pkts 추가됨 : 패킷 flow 카운팅 - 카운트 이름 지정 
NPORT=$(kubectl get service svc-nodeport -o jsonpath='{.spec.ports[0].nodePort}')
echo $NPORT

iptables -t nat -S | grep KUBE-NODEPORTS | grep <NodePort>
iptables -t nat -S | grep KUBE-NODEPORTS | grep $NPORT
-A KUBE-NODEPORTS -d 127.0.0.0/8 -p tcp -m comment --comment "default/svc-nodeport:svc-webport" -m tcp --dport 30898 -m nfacct --nfacct-name localhost_nps_accepted_pkts -j KUBE-EXT-VTR7MTHHNMFZ3OFS
-A KUBE-NODEPORTS -p tcp -m comment --comment "default/svc-nodeport:svc-webport" -m tcp --dport 30898 -j KUBE-EXT-VTR7MTHHNMFZ3OFS

# (참고) nfacct 확인
nfacct list
## nfacct flush # 초기화


## KUBE-EXT-# 에서 'KUBE-MARK-MASQ -j MARK --set-xmark 0x4000/0x4000' 마킹 및 KUBE-SVC-# 로 점프!
# docker exec -it mypc zsh -c "while true; do curl -s --connect-timeout 1 $CNODE:$NPORT | grep hostname; date '+%Y-%m-%d %H:%M:%S' ; echo ;  sleep 1; done" 반복 접속 후 아래 확인
watch -d 'iptables -v --numeric --table nat --list KUBE-EXT-VTR7MTHHNMFZ3OFS'
iptables -t nat -S | grep "A KUBE-EXT-VTR7MTHHNMFZ3OFS"
-A KUBE-EXT-VTR7MTHHNMFZ3OFS -m comment --comment "masquerade traffic for default/svc-nodeport:svc-webport external destinations" -j KUBE-MARK-MASQ
-A KUBE-EXT-VTR7MTHHNMFZ3OFS -j KUBE-SVC-VTR7MTHHNMFZ3OFS


# KUBE-SVC-# 이후 과정은 Cluster-IP 와 동일! : 3개의 파드로 DNAT 되어서 전달
iptables -t nat -S | grep "A KUBE-SVC-VTR7MTHHNMFZ3OFS -"
-A KUBE-SVC-VTR7MTHHNMFZ3OFS -m comment --comment "default/svc-nodeport:svc-webport" -m statistic --mode random --probability 0.33333333349 -j KUBE-SEP-Q5ZOWRTVDPKGFLOL
-A KUBE-SVC-VTR7MTHHNMFZ3OFS -m comment --comment "default/svc-nodeport:svc-webport" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-MMWCMKTGOFHFMRIZ
-A KUBE-SVC-VTR7MTHHNMFZ3OFS -m comment --comment "default/svc-nodeport:svc-webport" -j KUBE-SEP-CQTAHW4MAKGGR6M2


POSTROUTING 정보 확인
# 마킹되어 있어서 출발지IP를 접속한 노드의 IP 로 SNAT(MASQUERADE) 처리함! , 최초 출발지Port는 랜덤Port 로 변경
iptables -t nat -S | grep "A KUBE-POSTROUTING"
-A KUBE-POSTROUTING -m mark ! --mark 0x4000/0x4000 -j RETURN  # 0x4000/0x4000 되어 있으니 여기에 매칭되지 않고 아래 Rule로 내려감
-A KUBE-POSTROUTING -j MARK --set-xmark 0x4000/0x0
-A KUBE-POSTROUTING -m comment --comment "kubernetes service traffic requiring SNAT" -j MASQUERADE --random-fully


# docker exec -it mypc zsh -c "while true; do curl -s --connect-timeout 1 $CNODE:$NPORT | grep hostname; date '+%Y-%m-%d %H:%M:%S' ; echo ;  sleep 1; done" 반복 접속 후 아래 확인
watch -d 'iptables -v --numeric --table nat --list KUBE-POSTROUTING;echo;iptables -v --numeric --table nat --list POSTROUTING'

exit
----------------------------------------

 

서비스(NodePort) 생성 시 kube-proxy 에 의해서 iptables 규칙이 모든 노드에 추가되는지 확인

#
NPORT=$(kubectl get service svc-nodeport -o jsonpath='{.spec.ports[0].nodePort}')
docker exec -it myk8s-control-plane iptables -t nat -S | grep KUBE-NODEPORTS | grep $NPORT
...

for i in control-plane worker worker2 worker3; do echo ">> node myk8s-$i <<"; docker exec -it myk8s-$i iptables -t nat -S | grep KUBE-NODEPORTS | grep $NPORT; echo; done
...

 

externalTrafficPolicy 설정

- externalTrafficPolicy: Local : NodePort 로 접속 시 해당 노드에 배치된 파드로만 접속됨, 이때 SNAT 되지 않아서 외부 클라이언트 IP가 보존됨

 

설정 및 파드 접속 확인

# 기본 정보 확인
kubectl get svc svc-nodeport -o json | grep 'TrafficPolicy"'
  externalTrafficPolicy: Cluster
  internalTrafficPolicy: Cluster

# 기존 통신 연결 정보(conntrack) 제거 후 아래 실습 진행하자! : (모든 노드에서) conntrack -F
for i in control-plane worker worker2 worker3; do echo ">> node myk8s-$i <<"; docker exec -it myk8s-$i conntrack -F; echo; done
kubectl delete -f svc-nodeport.yaml
kubectl apply -f svc-nodeport.yaml

# externalTrafficPolicy: local 설정 변경
kubectl patch svc svc-nodeport -p '{"spec":{"externalTrafficPolicy": "Local"}}'
kubectl get svc svc-nodeport -o json | grep 'TrafficPolicy"'
	"externalTrafficPolicy": "Local",
  "internalTrafficPolicy": "Cluster",

# 파드 3개를 2개로 줄임
kubectl scale deployment deploy-echo --replicas=2

# 파드 존재하는 노드 정보 확인
kubectl get pod -owide

# 파드 로그 실시간 확인 (웹 파드에 접속자의 IP가 출력)
kubectl logs -l app=deploy-websrv -f


# 외부 클라이언트(mypc)에서 접속 시도

# 노드의 IP와 NodePort를 변수에 지정
## CNODE=<컨트롤플레인노드의 IP주소>
## NODE1=<노드1의 IP주소>
## NODE2=<노드2의 IP주소>
## NODE3=<노드3의 IP주소>
CNODE=172.18.0.A
NODE1=172.18.0.B
NODE2=172.18.0.C
NODE3=172.18.0.D
CNODE=172.18.0.5
NODE1=172.18.0.4
NODE2=172.18.0.3
NODE3=172.18.0.2

## NodePort 를 변수에 지정 : 서비스를 삭제 후 다시 생성하여서 NodePort가 변경되었음
NPORT=$(kubectl get service svc-nodeport -o jsonpath='{.spec.ports[0].nodePort}')
echo $NPORT

# 서비스(NodePort) 부하분산 접속 확인 : 파드가 존재하지 않는 노드로는 접속 실패!, 파드가 존재하는 노드는 접속 성공 및 클라이언트 IP 확인!
docker exec -it mypc curl -s --connect-timeout 1 $CNODE:$NPORT | jq
for i in $CNODE $NODE1 $NODE2 $NODE3 ; do echo ">> node $i <<"; docker exec -it mypc curl -s --connect-timeout 1 $i:$NPORT; echo; done

# 목적지 파드가 배치되지 않은 노드는 접속이 어떻게? 왜 그런가?
docker exec -it mypc zsh -c "for i in {1..100}; do curl -s $CNODE:$NPORT | grep hostname; done | sort | uniq -c | sort -nr"
docker exec -it mypc zsh -c "for i in {1..100}; do curl -s $NODE1:$NPORT | grep hostname; done | sort | uniq -c | sort -nr"
docker exec -it mypc zsh -c "for i in {1..100}; do curl -s $NODE2:$NPORT | grep hostname; done | sort | uniq -c | sort -nr"
docker exec -it mypc zsh -c "for i in {1..100}; do curl -s $NODE3:$NPORT | grep hostname; done | sort | uniq -c | sort -nr"

# 파드가 배치된 노드에 NodePort로 아래 반복 접속 실행 해두자
docker exec -it mypc zsh -c "while true; do curl -s --connect-timeout 1 $NODE1:$NPORT | grep hostname; date '+%Y-%m-%d %H:%M:%S' ; echo ;  sleep 1; done"
혹은
docker exec -it mypc zsh -c "while true; do curl -s --connect-timeout 1 $NODE2:$NPORT | grep hostname; date '+%Y-%m-%d %H:%M:%S' ; echo ;  sleep 1; done"
혹은
docker exec -it mypc zsh -c "while true; do curl -s --connect-timeout 1 $NODE3:$NPORT | grep hostname; date '+%Y-%m-%d %H:%M:%S' ; echo ;  sleep 1; done"

# (옵션) 노드에서 Network Connection
conntrack -E
conntrack -L --any-nat
# 패킷 캡쳐 확인

 

외부 클라이언트 → 각각 노드2,3 접속 시 : 각각 노드에 생성된 파드로만 접속

for i in $CNODE $NODE1 $NODE2 $NODE3 ; do echo ">> node $i <<"; docker exec -it mypc curl -s --connect-timeout 1 $i:$NPORT; echo; done

 

웹 파드에서 접속자의 IP 정보 확인(logs) 시 외부 클라이언트IP 가 그대로 확인됨

 

iptables 정책 적용 확인 : PREROUTING → KUBE-SERVICES → KUBE-NODEPORTS → KUBE-EXT-# → KUBE-SVL-# → KUBE-SEP-#<자신의 노드에 생성된 파드> KUBE-XLB 삭제되고, KUBE-EXT-#, KUBE-SVL-# 과정 추가됨

 

컨트롤플레인 노드 - iptables 분석 << 정책 확인 : 아래 정책 내용은 핵심적인 룰(rule)만 표시함
KUBE-XLB 삭제되고, KUBE-EXT-#, KUBE-SVL-# 과정 추가됨

# (예시) 파드가 배포되어 있는 노드2에서 확인

docker exec -it myk8s-worker1 bash
혹은
docker exec -it myk8s-worker2 bash
혹은
docker exec -it myk8s-worker3 bash

---------------------------------------

iptables -t nat -S
iptables -t nat -S | grep <NodePort>
iptables -t nat -S | grep 31303
-A KUBE-NODEPORTS -d 127.0.0.0/8 -p tcp -m comment --comment "default/svc-nodeport:svc-webport" -m tcp --dport 31303 -m nfacct --nfacct-name  localhost_nps_accepted_pkts -j KUBE-EXT-VTR7MTHHNMFZ3OFS
-A KUBE-NODEPORTS -p tcp -m comment --comment "default/svc-nodeport:svc-webport" -m tcp --dport 31303 -j KUBE-EXT-VTR7MTHHNMFZ3OFS

iptables -t nat -S | grep 'A KUBE-EXT-VTR7MTHHNMFZ3OFS'
-A KUBE-EXT-VTR7MTHHNMFZ3OFS -s 10.10.0.0/16 -m comment --comment "pod traffic for default/svc-nodeport:svc-webport external destinations" -j KUBE-SVC-VTR7MTHHNMFZ3OFS
-A KUBE-EXT-VTR7MTHHNMFZ3OFS -m comment --comment "masquerade LOCAL traffic for default/svc-nodeport:svc-webport external destinations" -m addrtype --src-type LOCAL -j KUBE-MARK-MASQ
-A KUBE-EXT-VTR7MTHHNMFZ3OFS -m comment --comment "route LOCAL traffic for default/svc-nodeport:svc-webport external destinations" -m addrtype --src-type LOCAL -j KUBE-SVC-VTR7MTHHNMFZ3OFS
-A KUBE-EXT-VTR7MTHHNMFZ3OFS -j KUBE-SVL-VTR7MTHHNMFZ3OFS

# 실습 환경에서는 아래처럼 2개의 파드 중 자신의 노드에 생성된 파드 1개만 DNAT 연결됨
iptables -t nat -S | grep 'A KUBE-SVL-VTR7MTHHNMFZ3OFS'
-A KUBE-SVL-VTR7MTHHNMFZ3OFS -m comment --comment "default/svc-nodeport:svc-webport -> 10.10.2.7:8080" -j KUBE-SEP-FBJG45W6XHLV2NA6

iptables -t nat -S | grep 'A KUBE-SEP-FBJG45W6XHLV2NA6'
-A KUBE-SEP-FBJG45W6XHLV2NA6 -s 10.10.2.7/32 -m comment --comment "default/svc-nodeport:svc-webport" -j KUBE-MARK-MASQ
-A KUBE-SEP-FBJG45W6XHLV2NA6 -p tcp -m comment --comment "default/svc-nodeport:svc-webport" -m tcp -j DNAT --to-destination 10.10.2.7:8080

exit
---------------------------------------

 

서비스(NodePort, externalTrafficPolicy: Local) 생성 시 iptables 규칙(KUBE-SVL-#)이 모든 노드에 추가되는지 확인 ⇒ 파드가 있는 노드에만 추가됨을 확인 ← 이전 서비스 실습과는 다르게 이번 경우 부터는 각 노드에 iptables 규칙이 각기 다르게 설정 됨을 확인

# 파드가 배포되어 있는 노드의 경우 KUBE-SVL-# 규칙 존재함을 확인
docker exec -it myk8s-control-plane iptables -t nat -S | grep 'A KUBE-SVL-VTR7MTHHNMFZ3OFS'
...

for i in control-plane worker worker2 worker3; do echo ">> node myk8s-$i <<"; docker exec -it myk8s-$i iptables -t nat -S | grep 'A KUBE-SVL-VTR7MTHHNMFZ3OFS'; echo; done
>> node myk8s-control-plane <<

>> node myk8s-worker <<
-A KUBE-SVL-VTR7MTHHNMFZ3OFS -m comment --comment "default/svc-nodeport:svc-webport -> 10.10.1.4:8080" -j KUBE-SEP-BVGSCXVWMMVKXIKE

>> node myk8s-worker2 <<
-A KUBE-SVL-VTR7MTHHNMFZ3OFS -m comment --comment "default/svc-nodeport:svc-webport -> 10.10.3.3:8080" -j KUBE-SEP-4FWIZRNI676EMNVA

>> node myk8s-worker3 <<

 

노드에 파드가 없을 경우 다른 곳으로 전달하지 못하고 차단됨

 

오브젝트 삭제

kubectl delete svc,deploy --all

 

 

서비스(NodePort) 보완점

- 외부에서 노드의 IP와 포트로 직접 접속이 필요함 → 내부망이 외부에 공개(라우팅 가능)되어 보안에 취약함LoadBalancer 서비스 타입으로 외부 공개 최소화 가능

- 클라이언트 IP 보존을 위해서, externalTrafficPolicy: local 사용 시 파드가 없는 노드 IP로 NodePort 접속 시 실패LoadBalancer 서비스에서 헬스체크(Probe) 로 대응 가능

 

 

참고자료

https://kubernetes.io/ko/docs/concepts/services-networking/service/