kubernetes中常用資源對(duì)象service的詳細(xì)介紹

Kubernetes_New.png

一、Service

對(duì)于kubernetes整個(gè)集群來(lái)說(shuō),Pod的地址也可變的,也就是說(shuō)如果一個(gè)Pod因?yàn)槟承┰蛲顺隽耍捎谄湓O(shè)置了副本數(shù)replicas大于1,那么該P(yáng)od就會(huì)在集群的任意節(jié)點(diǎn)重新啟動(dòng),這個(gè)重新啟動(dòng)的Pod的IP地址與原IP地址不同,這對(duì)于業(yè)務(wù)來(lái)說(shuō),就不能根據(jù)Pod的IP作為業(yè)務(wù)調(diào)度。kubernetes就引入了Service的概念,它為Pod提供一個(gè)入口,主要通過(guò)Labels標(biāo)簽來(lái)選擇后端Pod,這時(shí)候不論后端Pod的IP地址如何變更,只要Pod的Labels標(biāo)簽沒(méi)變,那么 業(yè)務(wù)通過(guò)service調(diào)度就不會(huì)存在問(wèn)題。

當(dāng)聲明Service的時(shí)候,會(huì)自動(dòng)生成一個(gè)cluster IP,這個(gè)IP是虛擬IP。我們就可以通過(guò)這個(gè)IP來(lái)訪問(wèn)后端的Pod,當(dāng)然,如果集群配置了DNS服務(wù),比如現(xiàn)在的CoreDNS,那么也可以通過(guò)Service的名字來(lái)訪問(wèn),它會(huì)通過(guò)DNS自動(dòng)解析Service的IP地址。

Service的模式有三種,user space,iptables,ipvs。

Service的類型有三種,Cluster IP,LoadBalance,NodePort,ExternalName。其中Cluster IP是默認(rèn)的類型。
(1)、Cluster IP:通過(guò) 集群內(nèi)部IP暴露服務(wù),默認(rèn)是這個(gè)類型,選擇該值,這個(gè)Service服務(wù)只能通過(guò)集群內(nèi)部訪問(wèn);
(2)、LoadBalance:使用云提供商的負(fù)載均衡器,可以向外部暴露服務(wù),選擇該值,外部的負(fù)載均衡器可以路由到NodePort服務(wù)和Cluster IP服務(wù);
(3)、NodePort:顧名思義是Node基本的Port,如果選擇該值,這個(gè)Service可以通過(guò)NodeIP:NodePort訪問(wèn)這個(gè)Service服務(wù),NodePort會(huì)路由到Cluster IP服務(wù),這個(gè)Cluster IP會(huì)通過(guò)請(qǐng)求自動(dòng)創(chuàng)建;
(4)、ExternalName:通過(guò)返回 CNAME 和它的值,可以將服務(wù)映射到 externalName 字段的內(nèi)容,沒(méi)有任何類型代理被創(chuàng)建,可以用于訪問(wèn)集群內(nèi)其他沒(méi)有Labels的Pod,也可以訪問(wèn)其他NameSpace里的Service。

kubernetes主要通過(guò)kube-proxy創(chuàng)建iptables和ipvs規(guī)則,在每個(gè)Node節(jié)點(diǎn)上都會(huì)創(chuàng)建這些規(guī)則。


image.png

1.1、Cluster IP

集群默認(rèn)的Service類型,只能在集群內(nèi)部訪問(wèn),一個(gè)簡(jiǎn)單的Service定義如下:

apiVersion: v1         # API版本
kind: Service                # 聲明版本為Service
metadata:                            # 元數(shù)據(jù)
  name: nginx-service  # 定義Service的名字
  labels:              # 定義Service的標(biāo)簽
    name: nginx-service
spec:
  type: ClusterIP      # 定義Service的類型
  selector:            # 定義標(biāo)簽選擇器,會(huì)代理后端name=nginx-service的Pod
    name: nginx-service
  ports:               # 暴露的端口名
  - port: 8000

然后通過(guò)kubectl get svc可以看到Cluster IP


image.png

可以通過(guò)容器內(nèi)訪問(wèn):


image.png

1.2、NodePort

暴露端口到Node節(jié)點(diǎn),可以通過(guò)Node節(jié)點(diǎn)訪問(wèn)容器。<br />如果設(shè)置 type 的值為 "NodePort",Kubernetes master 將從給定的配置范圍內(nèi)(默認(rèn):30000-32767)分配端口,每個(gè) Node 將從該端口(每個(gè) Node 上的同一端口)代理到 Service。該端口將通過(guò) Service 的 spec.ports[*].nodePort 字段被指定,如果不指定的話會(huì)自動(dòng)生成一個(gè)端口。
需要注意的是,Service 將能夠通過(guò) :spec.ports[].nodePort 和 spec.clusterIp:spec.ports[].port 而對(duì)外可見(jiàn)。
一個(gè)簡(jiǎn)單的Service定義如下:

apiVersion: v1         # API版本
kind: Service                # 聲明版本為Service
metadata:                            # 元數(shù)據(jù)
  name: nginx-service  # 定義Service的名字
  labels:              # 定義Service的標(biāo)簽
    name: nginx-service
spec:
  type: NodePort       # 定義Service的類型
  selector:            # 定義標(biāo)簽選擇器,會(huì)代理后端name=nginx-service的Pod
    name: nginx-service
  ports:               # 暴露的端口名
  - port: 8000

然后通過(guò)kubectl get svc可以看到剛才創(chuàng)建的NodePort。


image.png

可以通過(guò)容器內(nèi)訪問(wèn):


image.png

也可以通過(guò)外部訪問(wèn):


image.png

1.3、LoadBalance

需要云提供商支撐。
比如:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
  clusterIP: 10.0.171.239
  loadBalancerIP: 78.11.24.19
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
      - ip: 146.148.47.155

1.4、ExternalName

ExternalName 是 Service 的特例,它沒(méi)有 selector,也沒(méi)有定義任何的端口和 Endpoint。 對(duì)于運(yùn)行在集群外部的服務(wù),它通過(guò)返回該外部服務(wù)的別名這種方式來(lái)提供服務(wù)。
例如:

kind: Service
apiVersion: v1
metadata:
  name: my-service
  namespace: prod
spec:
  type: ExternalName
  externalName: my.database.example.com

當(dāng)查詢主機(jī) my-service.prod.svc.cluster.local (后面服務(wù)發(fā)現(xiàn)的時(shí)候我們會(huì)再深入講解)時(shí),集群的 DNS 服務(wù)將返回一個(gè)值為 my.database.example.com 的 CNAME 記錄。 訪問(wèn)這個(gè)服務(wù)的工作方式與其它的相同,唯一不同的是重定向發(fā)生在 DNS 層,而且不會(huì)進(jìn)行代理或轉(zhuǎn)發(fā)。 如果后續(xù)決定要將數(shù)據(jù)庫(kù)遷移到 Kubernetes 集群中,可以啟動(dòng)對(duì)應(yīng)的 Pod,增加合適的 Selector 或 Endpoint,修改 Service 的 type,完全不需要修改調(diào)用的代碼,這樣就完全解耦了。

二、Headless Service

上面的Service都是有IP的,也就是說(shuō)如果在Kubernetes集群中配置了DNS,解析ServeiceName得到的是ClusterIP,那Headless Service是什么呢?顧名思義是無(wú)頭服務(wù),無(wú)頭在這里就是沒(méi)有IP的意思,YAML文件定義也很簡(jiǎn)單,就是ClusterIP設(shè)置為None。
官方信息為:

"None" can be specified for headless services when proxying is not required.

我們來(lái)定義一個(gè)YAML文件:<br />nginx-headless-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: nginx-headless-service
  labels:
    name: nginx-headless-service
spec:
  clusterIP: None
  selector:
    name: nginx-service
  ports:
  - port: 8000
    targetPort: 80

然后創(chuàng)建SVC:

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

查看SVC:

# kubectl get svc
NAME                     TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGE
kubernetes               ClusterIP   10.68.0.1     <none>        443/TCP          4d18h
nginx-headless-service   ClusterIP   None          <none>        8000/TCP         4s

我們可以看到nginx-headless-service中CLUSTER-IP這一列為None,那么現(xiàn)在我們通過(guò)ServiceName解析會(huì)得到什么?<br />我們用dig命令來(lái)解析一下:

[root@master service]# dig -t a nginx-headless-service.default.svc.cluster.local. @10.68.0.2

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-9.P2.el7 <<>> -t a nginx-headless-service.default.svc.cluster.local. @10.68.0.2
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 15647
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;nginx-headless-service.default.svc.cluster.local. IN A

;; ANSWER SECTION:
nginx-headless-service.default.svc.cluster.local. 5 IN A 172.20.2.84

;; Query time: 1 msec
;; SERVER: 10.68.0.2#53(10.68.0.2)
;; WHEN: Mon Sep 09 12:04:55 CST 2019
;; MSG SIZE  rcvd: 141

可以看到解析得地址是Pod得地址,如果沒(méi)有dig命令,可以使用以下命令安裝:

yum install bind-utils -y

所以Headless Service類型得Service解析的Pod的IP地址,常用在statefulSet中。


公眾號(hào):?jiǎn)踢吂适拢↖D:qiaobiangushi)

知乎: 喬邊故事

頭條號(hào):?jiǎn)踢吂适?/p>

只要臉皮夠厚,整個(gè)世界都將被你踩在腳下。


感謝您的閱讀,歡迎轉(zhuǎn)發(fā)!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容