kubernetes

Kubernetes Headless Service

mingming_96 2023. 9. 27. 16:57

Headless Service 

  ClusterIP가 없는 서비스로 단일 진입점이 필요 없을 때 사용

  Service와 연결된 Pod 의 endpoint로 DNS 레코드가 생성됨

  Pod의 DNS 주소 : coreDNS 에 DNS 등록

pod-ip-addr.namesapce.pod.cluster.local

  Pod의 endpoint를 DNS resolving Service로 요청가능 

 

headless service.yaml

apiVersion: v1
kind: Service
metadata:
  name: headless-service
spec:
  type: ClusterIP
  clusterIP: None
  selctor:
    app: webui
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

 

Cluster IP 가 할당되지 않은 Service가 생성되었습니다. headless service는 별도의 타입으로 존재하는 것이 아닌 ClusterIP type에서 IP를 할당 받지 않은 것을 의미합니다.

root@master:~/sample# kubectl get svc
NAME               TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
headless-service   ClusterIP   None         <none>        80/TCP    3s
kubernetes         ClusterIP   10.96.0.1    <none>        443/TCP   3h26m

 

nginx-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: webui
  template:
    metadata:
      labels:
        app: webui
    spec:
      containers:
      - image: nginx:1.14
        name: nginx

세개의 replica를 갖는 nginx deployment를 생성해 줍니다.

kubectl apply -f nginx-deployment.yaml
root@master:~/sample# kubectl get pods -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP          NODE      NOMINATED NODE   READINESS GATES
nginx-5b59c5ffcf-6jlcj   1/1     Running   0          37s   10.44.0.5   worker    <none>           <none>
nginx-5b59c5ffcf-wkndw   1/1     Running   0          37s   10.44.0.4   worker    <none>           <none>
nginx-5b59c5ffcf-wxcpn   1/1     Running   0          37s   10.47.0.4   worker2   <none>           <none>

 

coreDNS에 레코드가 기록이 되는지 확인해봅니다.

 

테스트를 위한 pod가 필요합니다.

kubectl run testpod -it --image=centos:7 /bin/bash

 

테스트 파드에 접속된 상태에서 /etc/resolv.conf 를 확인해 dns 서버를 확인해 줍니다.

[root@testpod /]# cat /etc/resolv.conf 
search default.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.96.0.10
options ndots:5

 

curl 명령어로 coredns에 기록된 dns를 이용해 정보를 받아올 수 있는지 확인 해보겠습니다.

curl 10-44-0-5.default.pod.cluster.local

 

정상적으로 dns를 통한 pod접근이 가능하 것은 확인할 수 있습니다.

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

 

headless service는 pod의 이름이 자주 바뀌는 service 보다는 statefulset 처럼 pod의 이름이 보존되는 service에서 사용하기 용이합니다.

 

Kube-Proxy

  - Kubernetes Service의 backend 구현

  - endpoint 연결을 위한 iptables 구성

  - nodePort로의 접근과 Pod 연결을 구현 ( iptables 구성 )

  - kube-proxy는 daemonset 형태로 배포되어 각 노드에 동작하고 있습니다. 

 

worker node 접속 후 iptables 확인

root@worker:~# iptables -t nat -S | grep 80
-A KUBE-SEP-FFUXEE3XZULEO6CI -p tcp -m comment --comment "prometheus/prometheus-kube-state-metrics:http" -m tcp -j DNAT --to-destination 10.47.0.3:8080
-A KUBE-SERVICES -d 10.106.121.129/32 -p tcp -m comment --comment "prometheus/grafana:service cluster IP" -m tcp --dport 80 -j KUBE-SVC-PSMKGKNYWLLFMILY
-A KUBE-SERVICES -d 192.168.56.242/32 -p tcp -m comment --comment "prometheus/grafana:service loadbalancer IP" -m tcp --dport 80 -j KUBE-EXT-PSMKGKNYWLLFMILY
-A KUBE-SERVICES -d 10.107.71.23/32 -p tcp -m comment --comment "prometheus/prometheus-server:http cluster IP" -m tcp --dport 80 -j KUBE-SVC-TDXCKHDUO2IKBXDX
-A KUBE-SERVICES -d 192.168.56.241/32 -p tcp -m comment --comment "prometheus/prometheus-server:http loadbalancer IP" -m tcp --dport 80 -j KUBE-EXT-TDXCKHDUO2IKBXDX
-A KUBE-SERVICES -d 10.97.219.1/32 -p tcp -m comment --comment "prometheus/prometheus-kube-state-metrics:http cluster IP" -m tcp --dport 8080 -j KUBE-SVC-PJJGJ2RDLXYSILDN
-A KUBE-SVC-PJJGJ2RDLXYSILDN ! -s 10.32.0.0/12 -d 10.97.219.1/32 -p tcp -m comment --comment "prometheus/prometheus-kube-state-metrics:http cluster IP" -m tcp --dport 8080 -j KUBE-MARK-MASQ
-A KUBE-SVC-PJJGJ2RDLXYSILDN -m comment --comment "prometheus/prometheus-kube-state-metrics:http -> 10.47.0.3:8080" -j KUBE-SEP-FFUXEE3XZULEO6CI
-A KUBE-SVC-PSMKGKNYWLLFMILY ! -s 10.32.0.0/12 -d 10.106.121.129/32 -p tcp -m comment --comment "prometheus/grafana:service cluster IP" -m tcp --dport 80 -j KUBE-MARK-MASQ
-A KUBE-SVC-TDXCKHDUO2IKBXDX ! -s 10.32.0.0/12 -d 10.107.71.23/32 -p tcp -m comment --comment "prometheus/prometheus-server:http cluster IP" -m tcp --dport 80 -j KUBE-MARK-MASQ

 

kube proxy의 두가지 역할

  - iptables 생성 및 관리 

  - nodeport로 오픈한 port listen 

 

kube-proxy mode 

userspasce

  클라이언트의 서비스 요청을 iptables를 거쳐 kube-proxy가 받아서 연결 

  kubernetes 초기버전에 잠깐 사용 

 

iptables ( 현재 사용중 )

  default kubernetes network mode

  kube-proxy는 service API 요청 시 iptables rule이 생성 

  클라이언트 연결은 kube-proxy가 받아서 iptables 룰을 통해 연결 

 

IPVS

  리눅스 커널이 지원하는 L4 로드밸런싱 기술을 이용

  별도의 ipvs 지원 모듈을 설정한 후 적용 가능

  지원 알고리즘 : rr ( round robin ) , lc ( least connection ) , dh ( destination hashing ), sh ( source hashing ) , sed ( shortest expected delay )