목차

Kubernetes Service (ClusterIP, NodePort, LoadBalancer)

    1. Pod에 문제가 생기면 Kubernetes는 그 Pod를 삭제 후 재생성 한다.
    1. 이때 기존 Pod IP가 같을 확률은 매우 낮다.(Kubernetes 설계 사상: App를 유지 목적, Pod는 언제즌 장에에 의해 Down 될 수 있고 재시작 될 수 있다. )
    1. IP가 새로이 부여 될때마다 Application을 매번 수정해야하는 불편함을 없애기 위해 Service 사용하게 설계되었다.
  • 클라이언트에서 내부에 있는 Pod Application 접근을 위한 단일 진입점 역할을 하며 Proxy(Load Balancer)처럼 연결된 Pod들에 트래픽을 전달하는 object(Servece object)로 Clien요청 트래픽을 각각의 Pod로 포워딩한다.
  • 가상IP와 port를 가지고 생성
  • Kube-proxy를 통해 Service의 가상IP, port를 관리
  • Service object는 Pod를 트래픽에 노출, Endpoint object는 Pod IP, port가 존재
    • 트래픽 ↔ Service object ↔ Endpoint object ↔ IP, port 를 이용하여 Pod 특정
  • Service를 사용하여 Pod를 노출하면 kube-proxy는 Service를 통하여 그룹화된 Pod로 트래픽을 보내는 네트워크 규칙(Rules)생성
    • kube-proxy → Service(Pod:nginx1, Pod:nginx2, Pod:nginx3)
  • kube-proxy는 Service 변경사항 및 Endpoint 모니터링(변경사항)하여 트래픽을 Routing 하기 위한 규칙을 설정된 Mode를 사용하여 생성 및 업데이트 한다
    • Iptable mode(기본): kube-proxy는 iptabels를 관리하는 역할만 수행(트래픽 X), 모든 요청은 iptable를 거쳐 pod로 직접 전달
    • IPVS mode(IP Virtual Server): Netfilter Framework 기반으로 구현된 LInux kernel Level에서 동작하는 Layer4 Load Balancing 도구(모듈: RR, LC, DH, SH, SEC)
    • round-robin
    • least connection
    • destination hashing
    • source hashing
    • shortest expected delay
  • kube-proxy는 DaemonSet object type으로 모든 노드에서 실행
  • 서비스의 정보를 보기위하여 사용
#Seirvice 확인
$ kubectl run dns-pod-verify --image=busybox --restart=Never \\
--rm -it -- nslookup [DNS 주소]

#dnsuitls
#설치
$ kubectl apply -f https://k8s.io/examples/admin/dns/dnsutils.yaml

#사용
$ kubectl exec -it dnsutils -- nslookup [DNS 주소]

$ kubectl exec -it dnsutils -- dig [DNS 주소]
  • ClusterIP 서비스는 외부에 노출 될 필요가 없는 애플리케이션의 내부 통신을 위한 타입
  • type 미지정시 기본값
  • 외부에 노출되지 않아야 하는 내부 Pod간의 데이터 전송 및 테스트를 위해 사용
  • 트래픽분산(Load Balancer)기능 가지고 있음
    • case
    • wordpress to mysql
    • frontend to beckend, DB
    • redis DB의 master to slave
#run으로 바로 실행해도 되지만 파일을 만들고 실행 yaml 구조 파악을 위해 생성된 파일 보는걸 추천
$ kubectl run nginx-pod --image=nginx --port=80 --dry-run=client -o yaml > mynginx-pod.yaml

#실행
$ kubectl apply -f mynginx-pod.yaml

#확인
$ kubectl get po -o wide | grep nginx
pod/nginx-pod                           1/1     Running   0          17m     10.111.156.68   k8s-node1    <none>           <none>

#테스트 위에 적힌 ip로 확인
$ curl 10.111.156.68

#생성 --type=ClusterIP
$ kubectl expose pod nginx-pod --name=nginx-pod-service --type=ClusterIP --port=9000 --target-port=80 --dry-run=client -o yaml > mynginx-pod-svc.yaml

#실행
$ kubectl apply -f mynginx-pod-svc.yaml

#확인
$ kubectl get po,svc -o wide | grep nginx
pod/nginx-pod                           1/1     Running   0          17m     10.111.156.68   k8s-node1    <none>           <none>
service/nginx-pod-service          ClusterIP   10.96.215.57   <none>        9000/TCP         12m     run=nginx-pod

#확인
$ curl 10.96.215.57:9000
  • 애플리케이션에 대한 외부 연결을 활성화 하여 ClusterIP 서비스의 기능을 확장
  • 서비스를 생성하면 모든 클러스터는 특정 포트(30000\~32767)를 사용하여 외부에서 접근 및 생성된 Service의 ClusterIP로 트래픽 Routing
  • 이때 kube-proxy가 이를 forwarding 하도록 netfilter의 chain rule 수정
  • 웹 애플리케이션, API 같이 외부에서 액세스 해야하는 애플리케이션에 적합
  • ClusterIP도 동시에 가지고 있음
    • 구조
    • 외부 → NodePort( → ClusterIP) → Pod
    • 조회 시 ClusterIP도 확인 가능
#run으로 바로 실행해도 되지만 파일을 만들고 실행 yaml 구조 파악을 위해 생성된 파일 보는걸 추천
$ kubectl run nginx2-pod --image=nginx --port=80 --dry-run=client -o yaml > mynginx-pod2.yaml

#실행
$ kubectl apply -f mynginx-pod2.yaml

#확인
$ kubectl get po -o wide | grep nginx2
nginx2-pod                          1/1     Running   0          9s      10.111.156.69   k8s-node1    <none>           <none>

#테스트 위에 적힌 ip로 확인
$ curl 10.111.156.69

#생성 --type=NodePort
$ kubectl expose pod nginx2-pod --name=nginx2-pod-service --type=NodePort --port=9000 --target-port=80 --dry-run=client -o yaml > mynginx2-pod-svc.yaml

#실행
$ kubectl apply -f mynginx2-pod-svc.yaml

#확인
$ kubectl get po,svc -o wide | grep nginx2
pod/nginx2-pod                          1/1     Running   0          2m39s   10.111.156.69   k8s-node1    <none>           <none>
service/nginx2-pod-service          NodePort    10.96.215.57   <none>        9000:30583/TCP   94m     run=nginx2-pod      9000/TCP         12m     run=nginx-pod

#확인 ClusterIp
$ curl 10.96.215.57:9000

#외부 컴퓨터에서 접속 확인 NodePort
#kubernetes가 Node IP로 접속가능
#2대의 pc에 설치되었고 IP가 10.10.10.100, 10.10.10.101일때
#위에서 확인한 NodePort에서 지정한 30583을 통헤 접근
$ curl 10.10.10.100:30583
  • 노드포트 강제 지정
    • run으로 실행시킬땐 사용 불가 YAML로만 가능
    • mynginx2-pod-svc.YAML 아래와 같이 수정하고 실행후 포트 확인 해볼 것
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    run: nginx2-pod
  name: nginx2-pod-service
spec:
  ports:
  - port: 9000
    protocol: TCP
    targetPort: 80
    #set NodePort
    nodePort: 30001

  selector:
    run: nginx2-pod
  type: NodePort
status:
  loadBalancer: {}
  • TrafficPolicy
    • kubectl edit svc [서비스명] 을 통해 편집가능
    • 정책(Cluster, Local)에 따라 트래픽을 어떻게 연결할지 결정

    • 현재 Pod 구성
    • Node1 Pod1, Pod2 —- Node2 Pod3
    • externalTrafficPolicy: Local
    • 클라이언트는 처음 접속 Pod 만 연결
    • kube-proxy는 proxy 요청을 Local endpoint로만 proxy하고 트래픽을 다른 Node로 전달 안함
    • client1 → Pod1
    • client2→ Pod2
    • client3 → Pod3
    • externalTrafficPolicy: Cluster
    • 클라이언트는 모든 Pod로 연결
    • internalTrafficPolicy: Local
    • 클라이언트는 처음 접속 Node 만 연결
    • Service에 그룹화된 Pod 중 동일 Node에 존재하는 Pod 간의 트래픽 정책 임
    • client1 → Node1 (Pod1 또는 Pod2)
    • client2 → Node1 (Pod1)
    • internalTrafficPolicy: Cluster
    • 클라이언트는 모든 Node로 연결
    • 변경 방법
#에디트를 통한 방법
$ kubectl edit nginx2-pod-service
spec:
  clusterIP: 10.96.215.57
  clusterIPs:
  - 10.96.215.57
  externalTrafficPolicy: Cluster #Local또는 Cluster로 변경
  internalTrafficPolicy: Cluster #Local또는 Cluster로 변경
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - nodePort: 30583
    port: 9000
    protocol: TCP
    targetPort: 80
  selector:
    run: nginx2-pod
  sessionAffinity: None
  type: NodePort
#커맨드로 변경
$ kubectl patch svc nginx2-pod-service -p '{\"spec\":{\"externalTrafficPolicy\":\"Local\"}}
  • 참고 확인

$ sudo iptables -t nat --list KUBE-NODEPORTS -n | column -t | grep nginx2-pod-service
KUBE-EXT-VFED4LRSQQENJ3KC  tcp             --   0.0.0.0/0    0.0.0.0/0    /*  default/nginx2-pod-service  */

# KUBE-EXT-VFED4LRSQQENJ3KC 확인
$ sudo iptables -t nat --list KUBE-EXT-VFED4LRSQQENJ3KC -n | column -t | grep nginx2-pod-service
KUBE-MARK-MASQ             all                        --   0.0.0.0/0    0.0.0.0/0    /*  masquerade  traffic  for  default/nginx2-pod-service  external  destinations  */
  • Node앞에 위치해 각 Node들로 트래픽을 분산하는역할
  • L4 LoadBalancer가 생성되고 ClusterIP서비스 및 NodePort 서비스 가 암시적으로 생성됨
  • NodePort(30000\~32767)서비스 위에 적용
  • Public으로 사용 가능한 IP주소 및 DNS주소를 제공을 통해 Private IP 주소 및 NodePort포트로 클러스터의 Node에 트래픽을 Load Balanceing 하고 전달
  • 웹 애플리케이션이나 API와 같이 높은 트래픽 양을 처리햐애 하는 애플리케이션에 유용
  • 클라우드 환경이 아닌 온프레미스(VM)환경에서 LoadBalancer를 사용할경우 Public주소를 제공 할 수 있는 MetalLB(bare metal load balacer)모듈을 설치해주어야 한다.