目錄
-
Headless Service
示例1.無頭服務解析 -
Service類型中的第四種:ExternalName
示例2:www.baidu.com cname到svc
兩種特殊類型的svc
Headless Service
-
Headless Service
有時不需要或不想要負載均衡,以及單獨的 Service IP 。遇到這種情況,可以通過指定 Cluster IP(spec.clusterIP) 的值為 “None” 來創建 Headless Service 。這類 Service 并不會分配 Cluster IP, kube-
proxy 不會處理它們,而且平臺也不會為它們進行負載均衡和路由每個個體都具有一定程度的獨特性,由其存儲的狀態決定;
Headless Services是一種特殊的service,其spec:clusterIP表示為None,這樣在實際運行時就不會被分配ClusterIP。也被稱為無頭服務。
- headless Service和普通Service的區別
headless不分配clusterIP
headless service可以通過解析service的DNS,返回所有Pod的地址和DNS(statefulSet部署的Pod才有DNS) 普通的service,只能通過解析service的DNS返回service的ClusterIP - statefulSet和Deployment控制器的區別
statefulSet下的Pod有DNS地址,通過解析Pod的DNS可以返回Pod的IP
deployment下的Pod沒有DNS - 普通Service解析service的DNS結果
headless Service 就是沒頭的Service,有什么使用場景呢?
第一種: 自主選擇權,有時候client想自己決定使用哪個Real Server,可以通過查詢DNS來獲取Real Server的信息
第二種: headless service關聯的每個endpoint(也就是Pod),都會有對應的DNS域名;這樣Pod之間就可以互相訪問headless service一般和statefulSet結合使用
為什么要用headless service+statefulSet部署有狀態應用?
- headless service會為關聯的Pod分配一個域
<service name>.$<namespace name>.svc.cluster.local - StatefulSet會為關聯的Pod保持一個不變的Pod Name
statefulset中Pod的hostname格式為$(StatefulSet name)-$(pod序號) - StatefulSet會為關聯的Pod分配一個dnsName
$<Pod Name>.$<service name>.$<namespace name>.svc.cluster.local
示例1.Headless Service無頭服務解析
[root@k8s-master svc]# cat demoapp-headless-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: demoapp-headless-svc
spec:
clusterIP: None #必須為None
selector:
app: demoapp
ports:
- port: 80
targetPort: 80
name: http
[root@k8s-master centos]# kubectl exec centos-deployment-66d8cd5f8b-nrfnv -it -- /bin/bash
root@centos-deployment-66d8cd5f8b-nrfnv /]# nslookup -query=A demoapp-headless-svc #解析到是后端pod IP
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: demoapp-headless-svc.default.svc.cluster.local
Address: 10.244.1.103
Name: demoapp-headless-svc.default.svc.cluster.local
Address: 10.244.2.99
Name: demoapp-headless-svc.default.svc.cluster.local
Address: 10.244.2.97
Name: demoapp-headless-svc.default.svc.cluster.local
Address: 10.244.1.102
[root@centos-deployment-66d8cd5f8b-nrfnv /]# nslookup -query=PTR 10.244.1.103 #對pod IP進行反解 得到所有綁定的SVC
Server: 10.96.0.10
Address: 10.96.0.10#53
103.1.244.10.in-addr.arpa name = 10-244-1-103.demoapp-svc.default.svc.cluster.local.
103.1.244.10.in-addr.arpa name = 10-244-1-103.demoapp-nodeport-svc.default.svc.cluster.local.
103.1.244.10.in-addr.arpa name = 10-244-1-103.demoapp-loadbalancer-svc.default.svc.cluster.local.
103.1.244.10.in-addr.arpa name = 10-244-1-103.demoapp-externalip-svc.default.svc.cluster.local.
103.1.244.10.in-addr.arpa name = 10-244-1-103.demoapp-headless-svc.default.svc.cluster.local.
[root@centos-deployment-66d8cd5f8b-nrfnv /]# curl 10.244.1.103
iKubernetes demoapp v1.0 !! ClientIP: 10.244.1.104, ServerName: demoapp-66db74fcfc-2jf49, ServerIP: 10.244.1.103!
[root@centos-deployment-66d8cd5f8b-nrfnv /]#
[root@centos-deployment-66d8cd5f8b-nrfnv /]#
[root@centos-deployment-66d8cd5f8b-nrfnv /]# curl demoapp-headless-svc #需要注意的是Headless Service只有集群內部能訪問,宿主機上因為無法解析到SVC IP是訪問的
iKubernetes demoapp v1.0 !! ClientIP: 10.244.1.104, ServerName: demoapp-66db74fcfc-5dp5n, ServerIP: 10.244.1.102!
[root@centos-deployment-66d8cd5f8b-nrfnv /]# curl demoapp-headless-svc
iKubernetes demoapp v1.0 !! ClientIP: 10.244.1.104, ServerName: demoapp-66db74fcfc-z682r, ServerIP: 10.244.2.99!
[root@centos-deployment-66d8cd5f8b-nrfnv /]# curl demoapp-headless-svc
iKubernetes demoapp v1.0 !! ClientIP: 10.244.1.104, ServerName: demoapp-66db74fcfc-9wkgj, ServerIP: 10.244.2.97!
[root@centos-deployment-66d8cd5f8b-nrfnv /]# exit
[root@k8s-master svc]# curl demoapp-headless-svc #無法訪問
curl: (6) Could not resolve host: demoapp-headless-svc; Unknown error
Service類型中的第四種:ExternalName
externalName Service是k8s中一個特殊的service類型,它不需要指定selector去選擇哪些pods實例提供服務,而是使用DNS CNAME機制把自己CNAME到你指定的另外一個域名上,你可以提供集群內的名字,比如mysql.db.svc這樣的建立在db命名空間內的mysql服務,也可以指定http://mysql.example.com這樣的外部真實域名。
CNAME是很有用的一個功能,在不同的域名之間搭建橋梁達到明一個域名暗另一個域名,比如github就通過CNAME機制來達到為用戶提供私有域名站點的功能,云服務商也都是使用CNAME為用戶提供各種各樣的服務。作為明域名的所有者,我可以用A云來提供服務,哪天我口味變了,我換成B云提供服務,對我的用戶的來說沒有任何感知。
示例2:www.baidu.com cname到svc
[root@k8s-master svc]# cat externalname-redis-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: externalname-http-svc
namespace: default
spec:
type: ExternalName
externalName: www.baidu.com
ports:
- protocol: TCP
port: 80
targetPort: 80
selector: {}
[root@k8s-master svc]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demoapp-deploy ClusterIP 10.109.159.225 <none> 80/TCP 3d3h
externalname-http-svc ExternalName <none> www.baidu.com 80/TCP 87m
#新增Pod測試
[root@k8s-master storage]# kubectl run pod-$RANDOM --image=ikubernetes/admin-box:latest -it --rm --command -- /bin/sh
root@pod-7813 # nslookup -query=A externalname-http-svc
Server: 10.96.0.10
Address: 10.96.0.10#53
externalname-http-svc.default.svc.cluster.local canonical name = www.baidu.com.
www.baidu.com canonical name = www.a.shifen.com.
Name: www.a.shifen.com
Address: 180.101.49.11
Name: www.a.shifen.com
Address: 180.101.49.12
root@pod-7813 # curl -H "host:www.baidu.com" externalname-http-svc.default.svc.cluster.local
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道
....
root@pod-7813 #
參考鏈接: