월루를 꿈꾸는 대학생

KNAS Service (ClusterIP & NodePort) 본문

Server&Network/Kubernets_Dokcer

KNAS Service (ClusterIP & NodePort)

하즈시 2022. 2. 12. 03:55
728x90

 

실습 환경

- 클러스터와 다른 네트워크인 pc가 rtr을 통해서 접속 

- 테스트 단말 용도 

 

서비스

- 파드가 증가하면 ip도 변경되는데 그걸 aws의 eip처럼 고정 ip주는 서비스를 제공하기도함

- 동일한 애플리케이션의 다수의 파드의 접속을 용이하게 하기 위한 서비스에 접속

- 노드포트 : 보통 파드가 랜덤으로 포트가 열리는데 노드포트로 포트포워딩 느낌으로 파드와 외부를 연결해준다 

 

- 종류 : cluster ip , node port , lb

 


 

 

Cluster IP = L4

- 클라이언트(TestPod)가 'CLUSTER-IP' 접속 시 해당 노드의 iptables 룰(랜덤 분산)에 의해서 DNAT 처리가 되어 목적지(backend) 파드와 통신

- 부하 분산을 시켜준다 . 하나의 cluster ip로 여러 명이 접속시 하나는 pod1 , 하나는 pod3 이런 느낌

 

cat <<EOT> svc-clusterip.yaml
apiVersion: v1
kind: Service
metadata:
  name: svc-clusterip
spec:
  ports:
    - name: svc-webport
      port: 9000
      targetPort: 80
  selector:
    app: webpod
  type: ClusterIP
EOT

 

 

# 서비스는 10~ 대역은 서브넷팅해서 서비스인 cluster ip에 할당 

# 그래서 clusterip 서비스는 10.96.76.231 할당 받음 

# pod ip인 cluster 172~ 대역은 calico의 ipam의해 설정 

#port 

#targetport

#endpoint는 각 파드의 ip를 나타냄 - webpod쪽  endpoint가 서비스에 매칭된 레이블 app에 해당하는 파드를 모니터링 // 파드의ip와 포트가 있음 

 

# 서비스의 clusterip에 직접적으로 연결 시 아무것도 안 나옴

# cluster ip의 상세정보에 있는 port 9000번으로 접근시 응답

# host: 서비스 클러스터 ip

# remote address = 목적지 파드에 접근한 놈ip : net-pod 의 ip 

 

# 서비스의 ip에 접근할 때 가상포트인 9000번을 이용하면 백엔드 쪽 endpoint가 모니터링 중인 파드의 ip와 타겟포트 쪽으로 부하분산을 해준다

# 타겟포트가 대상포트 

 

 

# l4처럼 부하분산이 되는 걸 확인 3개의 포트에 나눠서 접근

 

# 마스터노드에 있는 testpod가 클러스터ip로 접근하니 iptables의 룰에 의해서 pod1 pod2 pod3 나눠서 랜덤으로 부하분산되어 접근됨 

 

# 동작을 이해하자! = 매운맛 

 


IPTABLES 정책 확인 

 

# rule 갯수 확인

 

 

# 규칙 패킷 바이트 카운트 초기화

iptables -t filter --zero; iptables -t nat --zero; iptables -t mangle --zero

 

# prerouting 체인 내용

# PREROUTING 안에 서브체인으로 cali-PREROUTING이 있음 

# 체인을 계속해서 따라간다!! 

# PREROUTING 안에 KUBE-SERVICES 체인으로 이동 

# KUBE-SERVICES 안에 있는 IP대역 중 CLUSTER IP의 대역 체인으로 또 이동 

# 목적지IP의 9000번 포트 매칭이 되면 해당 서브체인 따라감 

 

# 3개 중 하나로 보내는데 그 중 하나를 따라가 보면 파드의 IP를 DNAT한다고 나옴 

# 첫번째 들어갈 확률 33퍼

# 두번째 세번째 중 하나 들어갈 확률 50퍼

# 세번째만 남으니 100퍼 이런식으로 부하분산 

# 정리

# 10.96.76.231 서비스의 IP와 9000번 포트로 들어오면 SEP로 부하분산이 되고 SEP 정보를 따라가면 DNAT 처리가 되고 해당 파드 IP로 DNAT이 됨

1) 트래픽이 가장 처음 거쳐가는 훅 PREROUTING 

2) KUBE-SERVICES에서 모든게 매칭중 

3) CLUSTER IP와 포트에 매칭되는 것들은 해당 체인으로 이동 

4) 확률에 따라 해당되는 곳으로 이동 

5) 파드 IP와 포트가 나오고 최종 동작은 DNAT 

가시다님 노션

# 출발지 ip 처리 

# POSTROUTING 마지막 처리되는 훅 빠져나갈 때 처리됨 

# KUBEPOSTROUTING에서 NODEPORT와 CLUSTER IP의 처리가 다름

# CLUSTER IP는 RETURN에 해당되어 밑으로 내려가서 MARK , MASQUERADE 되는 게 아니라 상위로 올라가버림 IP가 변환되지 않고 POD IP가 유지되어서 상대방 POD로 간다 = 출발지 IP가 안 바뀐다

# NODE PORT는 출발지 IP가 변경될 예정 

REMOTE ADDRESS가 변경되지 않고 그대로 찍혔음 

 

 


#장애 발생시 상태확인 

- 고정적인 IP를 제공해준다 

- 서비스에 묶인 ENDPOINT 중 POD 1개를 장애를 일으키면 통신이 끊기는지 아닌지 확인 

- label selector에 묶여 있는 endpoint의 pod들만 

# 파드 1개 삭제 

- endpoint가 모니터링하는 pod3번 ip가 사라짐

- 부하분산 중 pod3이 사라지고 1과2만 반복 

- 고가용성 확인 

- endpoint가 모니터링을 아주 잘함 

 

# 파드의 레이블 변경 

# 똑같이 ENDPOINT 모니터링에서 벗어남 

# 서비스라는 오브젝트가 관심가지는 것은 레이블에 해당하는 파드뿐 

 

###쿠버네티스의 Endpoint Controller 는 지속적으로 엔드포인트를 Watch 하고 List 에 추가, 삭제를 함###

 


 

sessionAffinity: ClientIP

- 부하분산 말고 로그에 있는 쿠키를 사용해서 처음 접근했던 파드만 계속 접근하고 싶을 때 

- 클라이언트가 접속한 파드에 랜덤이 아니라 고정적인 접속을 지원 -> sessionAffinity 

 

 

 

# sessionAffinity  설정 확인 -> none

 

# sessionAffinity  설정시 처음 접근했던 파드만 접근 

# kubectl get svc svc-clusterip -o yaml | sed -e "s/sessionAffinity: None/sessionAffinity: ClientIP/" | kubectl apply -f -

 

 

Cluster ip 단점 

- 클러스터 외부에서 서비스로 접근 불가 -> NodePort 사용 

- iptables에 파드에 대한 헬스체크 기능이 없어서 문제가 생긴 파드에 연결이 가능하다 ->파드에 readiness probe 설정을 통해 문제 생기면 엔드포인트에서 삭제되도록!

 


NodePort

- 클러스터ip의 외부 접근이 안 되지만 nodeport는 외부접근이 가능한 서비스

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

- 노드포트 할당 범위는 30000-32767

 

노드의 ip에 노드포트 오브젝트를 달고 노드포트의 랜덤포트에 연결하면 dnat걸어서 pod로 연결해줌 

 

 

 

cat <<EOT> svc-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
  name: svc-nodeport
spec:
  ports:
    - name: svc-webport
      port: 9000
      targetPort: 8080
  selector:
    app: deploy-websrv
  type: NodePort
EOT

 

 

파드 3개 배포 

 

#노드포트는 클러스터ip 개념 포함한다

# 포트는 노드포트 / 타겟포트는 파드 

 

 


nodeport 접속 확인 

 

# 외부에서 노드에 접근할 시 부하분산되어 접근됨

# nodeport 선언시 k8s의 모든 노드포트들이 기본적으로 오픈이 된다 

# endpoint에 마스터 노드가 없지만 노드포트가 선언 될 때 모든 노드에서 해당 포트가 열린 상태가 됨 

 

# 노드포트는 소스ip를 바꾼다

 

 


iptables 정책 확인

 

 

#tcp 트래픽으로 이 노드로 들어오는 포트 32422 모든 ip에 대해서 해당 서브체인을 따라라 그렇게 따라가다보면 cluster ip처럼 나옴 

 

 

#마스터 노드 빠져나갈때 소스 ip가 nat 걸림 

#masquerade 출발지 ip를 노드 ip로 변경해서 나가는 거였는데 외부에서 이 마스터로 오고 마스터에서 실제 파드가 있는 노드로 보낼 때 masquerade보내서 출발지 ip가 바뀜snat 

 

# 소스ip가 변경이 되니까 민감한 서비스의 경우 로그를 뜰 수가 없음 

# 클라이언트 ip를 수집하기 위해 externalTrafficPolicy가 필요 

 


externalTrafficPolicy 설정

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

- 소스ip를 nat 안 시킴 

 

 

# 파드가 없으면 접속이 불가 

 

 

# 기본 정보 확인 

 

#local로 변경 

 

 

kubectl scale deployment deploy-echo --replicas=2

- 파드 3이 사라짐 

 

#실시간 로그 기록

kubetail -l app=deploy-websrv -f

 

# 파드3으로 접근이 안 되고

# client ip가 20. 대역으로 snat 안 됨 확인

# 로그 또한 ip가 그대로 찍혀서 수집 가능 

 

 

노드포트 부족한 점 

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

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

- 즉 LB로 보완이 가능하다 

 

 


테트리스 게임 배포 

 

환경

 

클라이언트 ip 보존

 

#외부pc에서 node1에 해당 nodeport 접근 시 클라이언트 ip가 변경되지 않음 

 

 

## 다시 클러스터로 변경했을 때 

## snat 됨 

 

 

 

728x90

'Server&Network > Kubernets_Dokcer' 카테고리의 다른 글

쿠버네티스 API 개념 및 보안 내용 정리  (0) 2022.03.14
CoreDNS & Service (MetalLB)  (0) 2022.02.20
쿠버네티스 대시보드 삽질기  (0) 2022.02.06
KNAS 3주차 _ 2  (0) 2022.02.03
KNAS 3주차_1  (0) 2022.02.02