kubernetes

[따배쿠] Headless Service, Kube-Proxy

bbiyak2da 2024. 12. 8. 11:25

Headless Service

  • 클러스터 내에서 Pod에 대한 DNS 이름을 제공하지만, ClusterIP를 할당하지 않는 서비스
  • 주로 StatefulSet과 같은 상태 저장 애플리케이션에서 사용되며, 파드 간의 직접적인 통신을 가능하게 합니다.
  • Pod IP에 대해 DNS resolving service도 제공
    • Service가 연결된 Pod의 endpoint로 DNS 레코드가 생성됨
    • Pod의 DNS 주소 : pod-ip-addr.namespace.pod.cluster.local
  • type은 ClusterIP이나 clusterIP는 None

특징

  • ClusterIP 없음
    • headless 서비스는 ClusterIP를 가지지 않으며, 대신 각 파드의 IP 주소를 직접 반환합니다. 이를 통해 클라이언트는 특정 파드에 직접 연결할 수 있습니다.
  • DNS 레코드
    • headless 서비스는 DNS 쿼리를 통해 각 파드의 IP 주소를 반환합니다. 예를 들어, 서비스 이름이 my-service이고, 네임스페이스가 my-namespace인 경우, DNS 쿼리를 통해 my-service.my-namespace.svc.cluster.local로 요청하면 해당 서비스에 연결된 모든 파드의 IP 주소 목록이 반환됩니다.
  • 로드 밸런싱 없음
    • 헤드리스 서비스는 로드 밸런싱을 제공하지 않으며, 클라이언트는 반환된 IP 주소 중 하나를 선택하여 직접 연결해야 합니다.

예시

 

# Deployment로 Pod 생성 및 확인

root@master:~/Getting-Start-Kubernetes/7# vi deploy-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: webui
spec:
  replicas: 3
  selector:
    matchLabels:
      app: webui
  template:
    metadata:
      name: nginx-pod
      labels:
        app: webui
    spec:
      containers:
      - name: nginx-container
        image: nginx:1.14
root@master:~/Getting-Start-Kubernetes/7# kubectl create -f deploy-nginx.yaml
deployment.apps/webui created
root@master:~/Getting-Start-Kubernetes/7# kubectl get pods -o wide
NAME                    READY   STATUS    RESTARTS      AGE     IP                NODE    NOMINATED NODE   READINESS GATES
testpod                 1/1     Running   1 (14m ago)   17h     192.168.104.2     node2   <none>           <none>
webui-5f67dcf6d-7rkcd   1/1     Running   0             4m13s   192.168.104.3     node2   <none>           <none>
webui-5f67dcf6d-nr2qj   1/1     Running   0             4m13s   192.168.104.4     node2   <none>           <none>
webui-5f67dcf6d-zfhlm   1/1     Running   0             4m13s   192.168.166.165   node1   <none>           <none>

 

# headless-nginx 파일 생성 및 배포

root@master:~/Getting-Start-Kubernetes/7# vi headless-nginx.yaml
apiVersion: v1
kind: Service
metadata:
  name: headless-service
spec:
  type: ClusterIP
  clusterIP: None
  selector:
    app: webui
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
root@master:~/Getting-Start-Kubernetes/7# kubectl create -f headless-nginx.yaml
service/headless-service created

 

# 확인

root@master:~/Getting-Start-Kubernetes/7# kubectl describe svc headless-service
Name:              headless-service
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=webui
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                None
IPs:               None
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         192.168.104.3:80,192.168.104.4:80,192.168.166.165:80
Session Affinity:  None
Events:            <none>

 

app=webui이라는 label을 가지는 pod 3개에 대해 headless service를 제공한다.

 

예시2

 

# pod 생성 (테스트 용도)

root@master:~/Getting-Start-Kubernetes/7# kubectl run testpod -it --image=centos:7 /bin/bash
If you don't see a command prompt, try pressing enter.

 

# pod의 DNS 서버 확인

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

 

10.96.0.10이 해당 pod의 DNS 서버임을 확인가능 (= master가 제공해주는 Core DNS의 IP)

 

# 확인

[root@testpod /]# curl 192-168-166-165.default.pod.cluster.local

 

Pod DNS 주소로 curl하면, nginx가 나온다. 

 

Kube-proxy

    • Kube-Proxy Kubernetes에서 네트워크 동작을 관리하는 컴포넌트
    • Kube-Proxy는 모든 Worker Node에 하나씩 위치하고 있는데, Kubernetes의 오브젝트 중 모든 오브젝트에 하나씩 위치하는 오브젝트인 DaemonSet의 형태로 배포
    • 기능
      • Kube-proxy는 새로운 Cluster IP가 생성되거나 Pod이 추가될 때, 자신이 동작하고 있는 Node의 iptables에 룰을 추가하여 줍니다.
      • 따라서, 클라이언트 요청은 kube-proxy가 받아서 iptables 룰을 참고하여 연결
      • kube-proxy는 Service의 IP와 Port로 들어온 접속을 Service와 연결된 여러 Pod들에게 Load Balancing
  • 또한, Node Port와 같은 Service를 통해 외부에 port를 노출시켜야 할 때, 그 port를 Listen하는 역할을 담당합니다.

# 확인

root@master:~/Getting-Start-Kubernetes/7# kubectl get pods --all-namespaces
NAMESPACE     NAME                                       READY   STATUS    RESTARTS       AGE
default       testpod                                    1/1     Running   1 (28s ago)    12m
default       webui-5f67dcf6d-7rkcd                      1/1     Running   0              23m
default       webui-5f67dcf6d-nr2qj                      1/1     Running   0              23m
default       webui-5f67dcf6d-zfhlm                      1/1     Running   0              23m
kube-system   calico-kube-controllers-5b9b456c66-slbt7   1/1     Running   4 (33m ago)    2d19h
kube-system   calico-node-22qcb                          1/1     Running   11 (33m ago)   34d
kube-system   calico-node-7lxq2                          1/1     Running   4 (33m ago)    2d19h
kube-system   calico-node-hqlgk                          1/1     Running   11 (33m ago)   34d
kube-system   coredns-55cb58b774-hn85c                   1/1     Running   4 (33m ago)    2d19h
kube-system   coredns-55cb58b774-wx9q6                   1/1     Running   4 (33m ago)    2d19h
kube-system   etcd-master                                1/1     Running   11 (33m ago)   34d
kube-system   kube-apiserver-master                      1/1     Running   11 (33m ago)   34d
kube-system   kube-controller-manager-master             1/1     Running   11 (33m ago)   34d
kube-system   kube-proxy-4gkx6                           1/1     Running   11 (33m ago)   34d
kube-system   kube-proxy-6xskg                           1/1     Running   4 (33m ago)    2d19h
kube-system   kube-proxy-bbl9f                           1/1     Running   11 (33m ago)   34d
kube-system   kube-scheduler-master                      1/1     Running   11 (33m ago)   34d
product       myweb                                      1/1     Running   6 (33m ago)    4d20h

 

kube-proxy가 3개 배포되어있는데, 이는 master / node1 / node2에서 DaemonSet 형태로 각각 동작한다.

 

kube-proxy mode

  • userspace
    • 클라이언트의 서비스 요청을 iptables를 거쳐 kube-proxy가 받아서 연결
    • k8s 초기 버전에 잠깐 사용
  • iptables (now)
    • default kubernetes network mode
    • kube-proxy는 service API 요청 시(ex. cluster ip 또는 node port 생성 요청), iptables rule 생성 
    • 클라이언트 연결은 kube-proxy가 받아서 iptables 룰을 통해 연결
  • IPVS
    • 리눅스 커널이 지원하는 L4 로드밸런싱 기술을 이용
    • 별도의 ipvs 지원 모듈을 설정한 후 적용 가능
    • 지원 알고리즘 : round-robin, least connection, destination hashing, source hashing, shortest expected delay

참고 영상

https://www.youtube.com/watch?v=ilQSgu8qt0o&list=PLApuRlvrZKohaBHvXAOhUD-RxD0uQ3z0c&index=27