Headless Services 簡介
有時不需要或不想要負載均衡,以及單獨的 Service IP。 遇到這種情況,可以通過指定 Cluster IP(spec.clusterIP)的值為 “None” 來創建 Headless Service。
您可以使用 headless Service 與其他服務發現機制進行接口,而不必與 Kubernetes 的實現捆綁在一起。
對這 headless Service 並不會分配 Cluster IP,kube-proxy 不會處理它們,而且平台也不會為它們進行負載均衡和路由。 DNS 如何實現自動配置,依賴於 Service 是否定義了 selector。
Lable Secector:
- 配置 Selector:對定義了 selector 的 Headless Service,Endpoint 控制器在 API 中創建了 Endpoints 記錄,並且修改 DNS 配置返回 A 記錄(地址),通過這個地址直接到達 Service 的後端 Pod上。見下圖:
- 不配置 Selector:對沒有定義 selector 的 Headless Service,Endpoint 控制器不會創建 Endpoints 記錄。
Service(iptables 代理模式)簡介
這種模式,kube-proxy 會監視 Kubernetes 控制節點對 Service 對象和 Endpoints 對象的添加和移除。 對每個 Service,它會安裝 iptables 規則,從而捕獲到達該 Service 的 clusterIP 和端口的請求,進而將請求重定向到 Service 任意一組 backend pod 中。 對於每個 Endpoints 對象,它也會安裝 iptables 規則,這個規則會選擇一個 backend pod 組合。
默認的策略是,kube-proxy 在 iptables 模式下隨機選擇一個 backend pod
下面是一個簡圖:
Headless Services 創建
$ vim headless_service.yaml
$ kubectl apply -f headless_service.yaml
headless_service.yaml 配置如下
apiVersion: v1
kind: Service
metadata:
name: nginx-test
labels:
app: nginx_test
spec:
ports:
- port: 80
name: nginx-web
# clusterIP 設置為 None
clusterIP: None
selector:
app: nginx_test
---
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
name: nginx-web
spec:
serviceName: "nginx-test"
replicas: 2
template:
metadata:
labels:
app: nginx_test
spec:
containers:
- name: nginx-test
image: nginx:1.11
ports:
- containerPort: 80
name: nginx-web
Headless Services 驗證
# 查看 statefulsets nginx-web
$ kubectl get statefulsets nginx-web
NAME READY AGE
nginx-web 2/2 93m
# 查看 pods
$ kubectl get pods -o wide | grep nginx-web
nginx-web-0 1/1 Running 0 96m 192.168.40.103 it-zabbix <none> <none>
nginx-web-1 1/1 Running 0 96m 192.168.40.96 it-zabbix <none> <none>
# 顯示 nginx-test Headless Services 詳細信息
$ kubectl describe svc nginx-test
Name: nginx-test
Namespace: default
Labels: app=nginx_test
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app":"nginx_test"},"name":"nginx-test","namespace":"default"},...
Selector: app=nginx_test
Type: ClusterIP
IP: None
Port: nginx-web 80/TCP
TargetPort: 80/TCP
Endpoints: 192.168.40.103:80,192.168.40.96:80
Session Affinity: None
Events: <none>
# 測試 service 域名是否解析出兩個 pod ip
$ nslookup nginx-test.default.svc.cluster.local 192.168.16.2
Server: 192.168.16.2
Address: 192.168.16.2#53
Name: nginx-test.default.svc.cluster.local
Address: 192.168.40.103
Name: nginx-test.default.svc.cluster.local
Address: 192.168.40.96
# 測試 pod 域名是否解析出對應的 pod ip
$ nslookup nginx-web-0.nginx-test.default.svc.cluster.local 192.168.16.2
Server: 192.168.16.2
Address: 192.168.16.2#53
Name: nginx-web-0.nginx-test.default.svc.cluster.local
Address: 192.168.40.103
$ nslookup nginx-web-1.nginx-test.default.svc.cluster.local 192.168.16.2
Server: 192.168.16.2
Address: 192.168.16.2#53
Name: nginx-web-1.nginx-test.default.svc.cluster.local
Address: 192.168.40.96
Headless Services 應用場景
- 第一種:自主選擇權,有時候
client想自己來決定使用哪個Real Server,可以通過查詢DNS來獲取Real Server的信息。 - 第二種:
Headless Service的對應的每一個Endpoints,即每一個Pod,都會有對應的DNS域名,這樣Pod之間就可以互相訪問。