成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Kubernetes Service詳解

baukh789 / 614人閱讀

摘要:后端代理之前的文章部署最后的測試部分,創(chuàng)建了一組及服務(wù)來驗證業(yè)務(wù),繼續(xù)以這個例子來說明集群中已經(jīng)有如下一組都帶有標(biāo)簽,對外暴露端口,訪問路徑會返回主機名。請求代理轉(zhuǎn)發(fā)是一個虛擬的地址,并不是某張網(wǎng)卡的真實地址。

為什么需要service

Kubernetes可以方便的為容器應(yīng)用提供了一個持續(xù)運行且方便擴(kuò)展的環(huán)境,但是,應(yīng)用最終是要被用戶或其他應(yīng)用訪問、調(diào)用的。要訪問應(yīng)用pod,就會有以下兩個問題:

pod是有生命周期的。它會根據(jù)集群的期望狀態(tài)不斷的在創(chuàng)建、刪除、更新,所以pod的ip也在不斷變化,如何訪問到不斷變化的pod?

通常一個應(yīng)用不會單只有一個pod,而是由多個相同功能的pod共同提供服務(wù)的。那么對這個應(yīng)用的訪問,如何在多個pod中負(fù)載均衡?

service主要就是用來解決這兩個問題的。簡單來說,它是一個抽象的api對象,用來表示一組提供相同服務(wù)的pod及對這組pod的訪問方式。

service的實現(xiàn)

service作為一個類似中介的角色,對內(nèi),它要能代理訪問到不斷變換的一組后端Pod;對外,它要能暴露自己給集群內(nèi)部或外部的其他資源訪問。我們分別來看下具體是怎么實現(xiàn)的。

后端代理

之前的文章kubeadm部署最后的測試部分,創(chuàng)建了一組pod及服務(wù)來驗證業(yè)務(wù),繼續(xù)以這個例子來說明:

集群中已經(jīng)有如下一組pod:

NAME                     READY   STATUS       IP            NODE     APP
goweb-55c487ccd7-5t2l2   1/1     Running     10.244.1.15   node-1   goweb
goweb-55c487ccd7-cp6l8   1/1     Running     10.244.3.9    node-2   goweb
goweb-55c487ccd7-gcs5x   1/1     Running     10.244.1.17   node-1   goweb
goweb-55c487ccd7-pp6t6   1/1     Running     10.244.3.10   node-2   goweb

pod都帶有app:goweb標(biāo)簽,對外暴露8000端口,訪問/info路徑會返回主機名。

創(chuàng)建service

創(chuàng)建一個servcie有兩種方式

命令式

$ kubectl expose deployment goweb --name=gowebsvc --port=80  --target-port=8000  

聲明式

# 定義服務(wù)配置文件
# svc-goweb.yaml
apiVersion: v1
kind: Service
metadata:
  name: gowebsvc
spec:
  selector:
    app: goweb
  ports:
  - name: default
    protocol: TCP
    port: 80
    targetPort: 8000
  type: ClusterIP
# 創(chuàng)建服務(wù)
$ kubectl apply -f svc-goweb.yaml

我們來看下配置文件中幾個重點字段:

selector指定了app: goweb標(biāo)簽。說明該svc代理所有包含有"app: goweb"的pod

port字段指定了該svc暴露80端口

targetPort指定改svc代理對應(yīng)pod的8000端口

type定義了svc的類型為ClusterIP,這也是svc的默認(rèn)類型

通過apply創(chuàng)建服務(wù)后,來查看一下服務(wù)狀態(tài)

$ kubectl  get svc gowebsvc  -o wide
NAME       TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE   SELECTOR
gowebsvc   ClusterIP   10.106.202.0           80/TCP    3d   app=goweb

可以看到,Kubernetes自動為服務(wù)分配了一個CLUSTER-IP。通過這個訪問這個IP的80端口,就可以訪問到"app: goweb"這組pod的8000端口,并且可以在這組pod中負(fù)載均衡。

[root@master-1 ~]# curl http://10.106.202.0/info
Hostname: goweb-55c487ccd7-gcs5x
[root@master-1 ~]# curl http://10.106.202.0/info
Hostname: goweb-55c487ccd7-cp6l8
[root@master-1 ~]# curl http://10.106.202.0/info
Hostname: goweb-55c487ccd7-pp6t6
請求代理轉(zhuǎn)發(fā)

cluster-ip是一個虛擬的ip地址,并不是某張網(wǎng)卡的真實地址。那具體的請求代理轉(zhuǎn)發(fā)過程是怎么實現(xiàn)的呢? 答案是iptables。我們來看下iptables中與cluster-ip相關(guān)的規(guī)則

[root@master-1 ~]# iptables-save | grep 10.106.202.0
-A KUBE-SERVICES ! -s 10.244.0.0/16 -d 10.106.202.0/32 -p tcp -m comment --comment "default/gowebsvc:default cluster IP" -m tcp --dport 80 -j KUBE-MARK-MASQ
-A KUBE-SERVICES -d 10.106.202.0/32 -p tcp -m comment --comment "default/gowebsvc:default cluster IP" -m tcp --dport 80 -j KUBE-SVC-SEG6BTF25PWEPDFT

可以看到,目的地址為CLUSTER-IP、目的端口為80的數(shù)據(jù)包,會被轉(zhuǎn)發(fā)到KUBE-MARK-MASQ與KUBE-SVC-SEG6BTF25PWEPDFT鏈上。其中,KUBE-MARK-MASQ鏈的作用是給數(shù)據(jù)包打上特定的標(biāo)記(待驗證),重點來看下KUBE-SVC-SEG6BTF25PWEPDFT鏈:

-A KUBE-SVC-SEG6BTF25PWEPDFT -m statistic --mode random --probability 0.25000000000 -j KUBE-SEP-5ZXTVLEM4DKNW7T2
-A KUBE-SVC-SEG6BTF25PWEPDFT -m statistic --mode random --probability 0.33332999982 -j KUBE-SEP-EBFXI7VOCPDT2QU5
-A KUBE-SVC-SEG6BTF25PWEPDFT -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-C3PKSXKMO2M43SPF
-A KUBE-SVC-SEG6BTF25PWEPDFT -j KUBE-SEP-2GQCCNJGO65Z5MFS

可以看到,KUBE-SVC-SEG6BTF25PWEPDFT鏈通過設(shè)置--probability,將請求等概率轉(zhuǎn)發(fā)到4條鏈上,查看其中一條轉(zhuǎn)發(fā)鏈:

[root@master-1 ~]# iptables-save | grep  "A KUBE-SEP-5ZXTVLEM4DKNW7T2" 
-A KUBE-SEP-5ZXTVLEM4DKNW7T2 -s 10.244.1.15/32 -j KUBE-MARK-MASQ
-A KUBE-SEP-5ZXTVLEM4DKNW7T2 -p tcp -m tcp -j DNAT --to-destination 10.244.1.15:8000

發(fā)現(xiàn)KUBE-SEP-5ZXTVLEM4DKNW7T2這條規(guī)則對請求的目的地址作了DNAT到10.244.1.15:8000,這正是goweb組中g(shù)oweb-55c487ccd7-5t2l2這個pod的ip地址。這樣,對svc的CLUSTER-IP的請求,就會通過iptables規(guī)則轉(zhuǎn)發(fā)到相應(yīng)的pod。

但是,還有個問題,svc是怎么跟蹤pod的ip變化的?
注意到前面的nat規(guī)則,第一次轉(zhuǎn)發(fā)的鏈名稱是KUBE-SVC-xxx,第二次轉(zhuǎn)發(fā)給具體pod的鏈名稱是KUBE-SEP-xxx,這里的SEP實際指的是kubernetes另一個對象endpoint,我們可以通過vkubectl get ep命令來查看:

[root@master-1 ~]# kubectl  get ep gowebsvc
NAME         ENDPOINTS 
gowebsvc     10.244.1.15:8000,10.244.1.17:8000,10.244.3.10:8000 + 1 more...   35d

在svc創(chuàng)建的時候,kube-proxy組件會自動創(chuàng)建同名的endpoint對象,動態(tài)地跟蹤匹配selector的一組pod當(dāng)前ip及端口,并生成相應(yīng)的iptables KUBE-SVC-xxx規(guī)則。

請求代理的三種方式

上面說的請求代理轉(zhuǎn)發(fā)的方式,是kubernetes目前版本的默認(rèn)方式,實際上,service的代理方式一共有三種:

Userspace 模式

在這種模式下,kube-proxy為每個服務(wù)都打開一個隨機的端口,所有訪問這個端口的請求都會被轉(zhuǎn)發(fā)到服務(wù)對應(yīng)endpoints指定的后端。最后,kube-proxy還會生成一條iptables規(guī)則,把訪問cluster-ip的請求重定向到上面說的隨機端口,最終轉(zhuǎn)發(fā)到后端pod。整個過程如下圖所示:

Userspace模式的代理轉(zhuǎn)發(fā)主要依靠kube-proxy實現(xiàn),工作在用戶態(tài)。所以,轉(zhuǎn)發(fā)效率不高。較為不推薦用該種模式。

iptables 模式

iptables模式是目前版本的默認(rèn)服務(wù)代理轉(zhuǎn)發(fā)模式,上兩小節(jié)做過詳細(xì)說明的就是這種模式,來看下請求轉(zhuǎn)發(fā)的示意圖:

與userspace模式最大的不同點在于,kube-proxy只動態(tài)地維護(hù)iptables,而轉(zhuǎn)發(fā)完全靠iptables實現(xiàn)。由于iptables工作在內(nèi)核態(tài),不用在用戶態(tài)與內(nèi)核態(tài)切換,所以相比userspace模式更高效也更可靠。但是每個服務(wù)都會生成若干條iptables規(guī)則,大型集群iptables規(guī)則數(shù)會非常多,造成性能下降也不易排查問題。

ipvs 模式

在v1.9版本以后,服務(wù)新增了ipvs轉(zhuǎn)發(fā)方式。kube-proxy同樣只動態(tài)跟蹤后端endpoints的情況,然后調(diào)用netlink接口來生成ipvs規(guī)則。通過ipvs來轉(zhuǎn)發(fā)請求:

ipvs同樣工作在內(nèi)核態(tài),而且底層轉(zhuǎn)發(fā)是依靠hash表實現(xiàn),所以性能比iptables還要好的多,同步新規(guī)則也比iptables快。同時,負(fù)載均衡的方式除了簡單rr還有多種選擇,所以很適合在大型集群使用。而缺點就是帶來了額外的配置維護(hù)操作。

集群內(nèi)部服務(wù)發(fā)現(xiàn)

在集群內(nèi)部對一個服務(wù)的訪問,主要有2種方式,環(huán)境變量與DNS。

環(huán)境變量方式

當(dāng)一個pod創(chuàng)建時,集群中屬于同個namespace下的所有service對象信息都會被作為環(huán)境變量添加到pod中。隨便找一個pod查看一下:

$ kubectl exec goweb-55c487ccd7-5t2l2 "env" | grep GOWEBSVC
GOWEBSVC_PORT_80_TCP_ADDR=10.106.202.0
GOWEBSVC_SERVICE_PORT=80
GOWEBSVC_SERVICE_PORT_DEFAULT=80
GOWEBSVC_PORT_80_TCP=tcp://10.106.202.0:80
GOWEBSVC_PORT_80_TCP_PROTO=tcp
GOWEBSVC_PORT_80_TCP_PORT=80
GOWEBSVC_PORT=tcp://10.106.202.0:80
GOWEBSVC_SERVICE_HOST=10.106.202.0

可以看到,pod通過{SVCNAME}_SERVICE_HOST/PORT就可以方便的訪問到某個服務(wù)。這種訪問方式簡單易用,可以用來快速測試服務(wù)。但最大的問題就是,服務(wù)必須先于pod創(chuàng)建,后創(chuàng)建的服務(wù)是不會添加到現(xiàn)有pod的環(huán)境變量中的。

DNS方式

DNS組件是k8s集群的可選組件,它會不停監(jiān)控k8s API,在有新服務(wù)創(chuàng)建時,自動創(chuàng)建相應(yīng)的DNS記錄。。以gowebsvc為例,在服務(wù)創(chuàng)建時,會創(chuàng)建一條gowebsvc.default.svc.cluster.local的dns記錄指向服務(wù)。而且dns記錄作用域是整個集群,不局限在namespace。
雖然是可選組件,但DNS生產(chǎn)環(huán)境可以說是必備的組件了。這里先簡單說明,后面打算專門開篇文章來詳細(xì)介紹。

集群外部的服務(wù)暴露

服務(wù)發(fā)現(xiàn)解決了集群內(nèi)部訪問pod問題,但很多時候,pod提供的服務(wù)也是要對集群外部來暴露訪問的,最典型的就是web服務(wù)。k8s中的service有多種對外暴露的方式,可以在部署Service時通過ServiceType字段來指定。默認(rèn)情況下,ServiceType配置是只能內(nèi)部訪問的ClusterIP方式,前面的例子都是這種模式,除此之外,還可以配置成下面三種方式:

NodePort方式:

該方式把服務(wù)暴露在每個Node主機IP的特定端口上,同一個服務(wù)在所有Node上端口是相同的,并自動生成相應(yīng)的路由轉(zhuǎn)發(fā)到ClusterIP。這樣,集群外部通過:就可以訪問到對應(yīng)的服務(wù)。舉個例子:

## 創(chuàng)建svc,通過Nodeport方式暴露服務(wù)
$ kubectl expose deployment goweb --name=gowebsvc-nodeport --port=80  --target-port=8000  --type=NodePort 
## 查看svc,可以看到NodePort隨機分配的端口為32538
$ kubectl get svc gowebsvc-nodeport 
NAME                TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
gowebsvc-nodeport   NodePort   10.101.166.252           80:32538/TCP   86s
## 隨便訪問一個nodeip的32538端口,都可以訪問到gowebsvc-nodeport服務(wù)對應(yīng)的pod
$ curl 172.16.201.108:32538/info
Hostname: goweb-55c487ccd7-pp6t6
$ curl 172.16.201.109:32538/info
Hostname: goweb-55c487ccd7-5t2l2
LoadBalance:

LoadBalance方式主要是給公有云服務(wù)使用的,通過配置LoadBalance,可以觸發(fā)公有云創(chuàng)建負(fù)載均衡器,并把node節(jié)點作為負(fù)載的后端節(jié)點。每個公有云的配置方式不同,具體可以參考各公有云的相關(guān)文檔。

ExternalName:

當(dāng)ServiceType被配置為這種方式時,該服務(wù)的目的就不是為了外部訪問了,而是為了方便集群內(nèi)部訪問外部資源。舉個例子,假如目前集群的pod要訪問一組DB資源,而DB是部署在集群外部的物理機,還沒有容器化,可以配置這么一個服務(wù):

apiVersion: v1
kind: Service
metadata:
  name: dbserver
  namespace: default
spec:
  type: ExternalName
  externalName: database.abc.com

這樣,集群內(nèi)部的pod通過dbserver.default.svc.cluster.local這個域名訪問這個服務(wù)時,請求會被cname到database.abc.com來。過后,假如db容器化了,不需要修改業(yè)務(wù)代碼,直接修改service,加上相應(yīng)selector就可以了。

幾種特殊的service

除了上面這些通常的service配置,還有幾種特殊情況:

Multi-Port Services

service可以配置不止一個端口,比如官方文檔的例子:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
  - name: http
    protocol: TCP
    port: 80
    targetPort: 9376
  - name: https
    protocol: TCP
    port: 443
    targetPort: 9377

這個service保留了80與443端口,分別對應(yīng)pod的9376與9377端口。這里需要注意的是,pod的每個端口一定指定name字段(默認(rèn)是default)。

Headless services

Headless services是指一個服務(wù)沒有配置了clusterIP=None的服務(wù)。這種情況下,kube-proxy不會為這個服務(wù)做負(fù)載均衡的工作,而是交予DNS完成。具體又分為2種情況:

有配置selector: 這時候,endpoint控制器會為服務(wù)生成對應(yīng)pod的endpoint對象。service對應(yīng)的DNS返回的是endpoint對應(yīng)后端的集合。

沒有配置selector:這時候,endpoint控制器不會自動為服務(wù)生成對應(yīng)pod的endpoint對象。若服務(wù)有配置了externalname,則生成一套cnmae記錄,指向externalname。如果沒有配置,就需要手動創(chuàng)建一個同名的endpoint對象。dns服務(wù)會創(chuàng)建一條A記錄指向endpoint對應(yīng)后端。

External IPs

如果有個非node本地的IP地址,可以通過比如外部負(fù)載均衡的vip等方式被路由到任意一臺node節(jié)點,那就可以通過配置service的externalIPs字段,通過這個IP地址訪問到服務(wù)。集群以這個IP為目的IP的請求時,會把請求轉(zhuǎn)發(fā)到對應(yīng)服務(wù)。參考官方文檔的例子:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
  - name: http
    protocol: TCP
    port: 80
    targetPort: 9376
  externalIPs:
  - 80.11.12.10

這里的80.11.12.10就是一個不由kubernetes維護(hù)的公網(wǎng)IP地址,通過80.11.12.10:80就可以訪問到服務(wù)對應(yīng)的pod。

簡單總結(jié)下,service對象實際上解決的就是一個分布式系統(tǒng)的服務(wù)發(fā)現(xiàn)問題,把相同功能的pod做成一個服務(wù)集也能很好的對應(yīng)微服務(wù)的架構(gòu)。在目前的kubernetes版本中,service還只能實現(xiàn)4層的代理轉(zhuǎn)發(fā),并且要搭配好DNS服務(wù)才能真正滿足生產(chǎn)環(huán)境的需求。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/32978.html

相關(guān)文章

  • 【容器云 UK8S】服務(wù)發(fā)現(xiàn)之ULB 參數(shù)說明:用于創(chuàng)建LoadBalancer類型的Service

    摘要:參數(shù)說明本文主要描述用于創(chuàng)建類型的時,與相關(guān)的說明。為時表示連接保持的時間,單位為秒,取值范圍,,表示禁用連接保持,默認(rèn)為。會話保持方式枚舉值為關(guān)閉,自動生成,用戶自定義,默認(rèn)為。健康檢查方式為時有效,指檢查路徑。ULB 參數(shù)說明本文主要描述用于創(chuàng)建LoadBalancer 類型的Service時,與ULB相關(guān)的Annotations說明。備注:目前除了外網(wǎng) ULB 綁定的 EIP 的帶寬值...

    Tecode 評論0 收藏0
  • Kubernetes集群監(jiān)控詳解

    摘要:儀表板是一個附加組件,它能提供集群上運行的資源的概述信息??梢院苋菀椎貏?chuàng)建圖形,并且把它們合并稱儀表板,而這些儀表板由一個強大的身份驗證和授權(quán)層保護(hù),它們還可以和其他儀表板進(jìn)行共享而不需要訪問服務(wù)器本身。 介 紹 Kubernetes在Github上擁有超過4萬顆星,7萬以上的commits,以及像Google這樣的主要貢獻(xiàn)者。Kubernetes可以說已經(jīng)快速地接管了容器生態(tài)系統(tǒng),成...

    A Loity 評論0 收藏0
  • kubernetes安裝heapster、influxdb及grafana

    摘要:下載在這里下載修改替換鏡像修改添加,同時把由改為。因為的跟中的的沖突了。修改新增的暴露出來,同時添加創(chuàng)建配置修改下數(shù)據(jù)源的查看數(shù)據(jù)總結(jié)部署詳解監(jiān)控 下載yaml 在這里下載deploy/kube-config/influxdb 修改yaml 替換鏡像 gcr.io/google_containers/heapster-grafana:v4.0.2 registry.cn-hangzho...

    waterc 評論0 收藏0
  • Kubernetes之Pod生命周期詳解

    摘要:下面通過該文章來簡述的基礎(chǔ)信息并詳述的生命周期。聲明周期鉤子函數(shù)為容器提供了兩種生命周期鉤子于容器創(chuàng)建完成之后立即運行的鉤子程序。向容器指定發(fā)起請求,響應(yīng)碼為或者是為成功,否則失敗。 簡述 Kubernetes 是一種用于在一組主機上運行和協(xié)同容器化應(yīng)用程序的系統(tǒng),提供應(yīng)用部署、規(guī)劃、更新維護(hù)的機制。應(yīng)用運行在 kubernetes 集群之上,實現(xiàn)服務(wù)的擴(kuò)容、縮容,執(zhí)行滾動更新以及在不...

    高勝山 評論0 收藏0

發(fā)表評論

0條評論

baukh789

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<