본문 바로가기

Kubernetes

[Kubernetes] Headless Service와 Kube Proxy

반응형

Headless Service

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

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

 - Pod의 DNS 주소 : pod-ip-addr.namespace.pod.cluster.local

 - DNS resolving Service로 요청 가능

 - Pod들의 endpoint에 DNS resolving Service 지원

 

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

 

deploy-nginx.yaml 실행

# kubectl create -f deploy-nginx.yaml
deployment.apps/webui created

# kubectl get pods -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP          NODE                NOMINATED NODE   READINESS GATES
webui-5cfbcf5f65-6qmb4   1/1     Running   0          10s   10.36.0.1   node1.example.com   <none>           <none>
webui-5cfbcf5f65-gxc2x   1/1     Running   0          10s   10.44.0.1   node2.example.com   <none>           <none>
webui-5cfbcf5f65-pwbhc   1/1     Running   0          10s   10.44.0.2   node2.example.com   <none>           <none>

 

headless-nginx.yaml

 - 클러스터로 pod 들을 묶어주는데 IP는 필요 없음 (clusterIP: None)

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

 

clusterip-nginx.yaml , headless-nginx.yaml 실행 후 비교해면 headless-service는 CLUSTER-IP가 None으로 확인

# kubectl create -f clusterip-nginx.yaml 
service/clusterip-service created

# kubectl get svc
NAME                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
clusterip-service   ClusterIP   10.100.100.100   <none>        80/TCP    3s
kubernetes          ClusterIP   10.96.0.1        <none>        443/TCP   4h55m

# kubectl create -f headless-nginx.yaml
service/headless-service created

# kubectl get svc
NAME                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
clusterip-service   ClusterIP   10.100.100.100   <none>        80/TCP    29s
headless-service    ClusterIP   None             <none>        80/TCP    7s
kubernetes          ClusterIP   10.96.0.1        <none>        443/TCP   4h56m

# 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:         10.36.0.1:80,10.44.0.1:80,10.44.0.2:80
Session Affinity:  None
Events:            <none>

 

테스트 pod 실행 후 pod에 바로 접근 후 resolv.conf 정보 확인

# kubectl run testpod -it --image=centos:7 /bin/bash
If you don't see a command prompt, try pressing enter.
[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 명령어로 특정 pod에 연결 (pod 의 DNS 정보를 CoreDNS에 등록하여 resolv 될 수 있도록함)

[root@testpod /]# curl 10-36-0-1.default.pod.cluster.local
<!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>

 

Kube-Proxy

 - Kubernetes Servcie의 backend 구현

 - endpoint 연결을 위한 iptables 구성

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

 

--all-namespaces를 이용하여 kube-proxy 확인

# kubectl get pods --all-namespaces 
NAMESPACE     NAME                                         READY   STATUS    RESTARTS       AGE
default       testpod                                      1/1     Running   1 (22s ago)    10m
default       webui-5cfbcf5f65-6qmb4                       1/1     Running   0              22m
default       webui-5cfbcf5f65-gxc2x                       1/1     Running   0              22m
default       webui-5cfbcf5f65-pwbhc                       1/1     Running   0              22m
kube-system   coredns-565d847f94-k9kvr                     1/1     Running   12 (27m ago)   20d
kube-system   coredns-565d847f94-tdhmn                     1/1     Running   12 (27m ago)   20d
kube-system   etcd-master.example.com                      1/1     Running   12 (27m ago)   20d
kube-system   kube-apiserver-master.example.com            1/1     Running   12 (27m ago)   20d
kube-system   kube-controller-manager-master.example.com   1/1     Running   12 (27m ago)   20d
kube-system   kube-proxy-6529g                             1/1     Running   12 (27m ago)   20d
kube-system   kube-proxy-skhgb                             1/1     Running   12 (27m ago)   20d
kube-system   kube-proxy-x5gsk                             1/1     Running   12 (28m ago)   20d
kube-system   kube-scheduler-master.example.com            1/1     Running   12 (27m ago)   20d
kube-system   weave-net-bwqrp                              2/2     Running   26 (27m ago)   20d
kube-system   weave-net-r8v7n                              2/2     Running   26 (26m ago)   20d
kube-system   weave-net-t92nl                              2/2     Running   24 (27m ago)   20d

 

각각의 노드, 마스터에서 kube-proxy가 동작하고 clusterip-service, headless-service 요청시 backend에서 kube-proxy가 동작하여 각각의 노드에 있는 kube-proxy는 iptables에 룰을 만들어서 clusterip에 해당하는 각각의 pod에 접근할 수 있는 iptables 룰을 만듬

 

노드 서버에 접근하여 iptables 확인

root@node1:~# iptables -t nat -S | grep 80
-A KUBE-MARK-DROP -j MARK --set-xmark 0x8000/0x8000
-A KUBE-SEP-HRLSFD7UJD73STE6 -p tcp -m comment --comment "default/clusterip-service" -m tcp -j DNAT --to-destination 10.44.0.1:80
-A KUBE-SEP-KJJCEWDGN43ZNMPN -p tcp -m comment --comment "default/clusterip-service" -m tcp -j DNAT --to-destination 10.44.0.2:80
-A KUBE-SEP-KPNE4OMUFKEDG6YL -p tcp -m comment --comment "default/clusterip-service" -m tcp -j DNAT --to-destination 10.36.0.1:80
-A KUBE-SERVICES -d 10.100.100.100/32 -p tcp -m comment --comment "default/clusterip-service cluster IP" -m tcp --dport 80 -j KUBE-SVC-KUSV3H3OUX7H3MDQ
-A KUBE-SVC-KUSV3H3OUX7H3MDQ -m comment --comment "default/clusterip-service -> 10.36.0.1:80" -m statistic --mode random --probability 0.33333333349 -j KUBE-SEP-KPNE4OMUFKEDG6YL
-A KUBE-SVC-KUSV3H3OUX7H3MDQ -m comment --comment "default/clusterip-service -> 10.44.0.1:80" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-HRLSFD7UJD73STE6
-A KUBE-SVC-KUSV3H3OUX7H3MDQ -m comment --comment "default/clusterip-service -> 10.44.0.2:80" -j KUBE-SEP-KJJCEWDGN43ZNMPN

 

kube-proxy mode

 1. userspace

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

  - kubernetes 초기 버전에 잠깐 사용

 2. iptables (default)

  - default kubernetes network mode

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

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

 3. IPVS

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

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

  - 지원 알고리즘 : rr(round-robin), lc(least connection), dh(destination hashing), sh(source hashing), nc(network queue),

     sed(shortest expected delay)

 

 

[참고]

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

반응형