K8S核心概念之SVC(易混淆難理解知識點總結)


本文將結合實際工作當中遇到的一些問題和情況來解析SVC的作用以及一些比較易混淆和難理解的概念,方便日后工作用到或者遺忘時可以直接在自己曾經學習總結的博客當中直接查找到。

首先應該清楚SVC的作用是什么,SVC主要有以下兩個作用:

一、服務發現

現在工作當中都將微服務項目部署到K8S上,因為每個項目都是很多個服務的集合,每個服務一般又都是由很多個pod組成的,那么當請求想要訪問這個服務的時候如何將請求能夠很好地找到這些POD並將請求分發給他們呢?
即使是同一組服務他們的pod是在集群的不同位置的,Ip也就各不相同,SVC就可以有效地將同一組服務綁定在一起,也就是提供了一個統一的服務訪問的入口,無論他們分發到哪個節點,也無論他們被分發了多少個不同的IP,SVC都可以做到將請求轉發到這組服務的其中一個POD中進行處理,k8s在創建SVC時候,會根據標簽選擇器selector(Lable selector)來查找pod,據此創建與SVC同名的endpoint對象,當pod地址發生變化時,endpoint也會隨之發生變化,SVC接收到前端client請求的時候,就會通過endpoint,找到要轉發到哪個Pod進行訪問網站的地址。(至於要轉發到哪個節點的Pod,由負載均衡kube-proxy起初就決定好了的)
這里面有幾個點需要說明一下:

1.endpoint是k8s集群中的一個資源對象,存儲在etcd中,用來記錄一個service對應的所有pod的訪問地址。
2.只有當service配置selector(選擇器) ,endpoint controller才會自動創建對應的endpoint對象,否則,不會生成endpoint對象。
3.例:k8s集群中創建一個名為hello的service,就會生成一個同名的endpoint對象,endpoint就是service關聯的pod的ip地址和端口。

二、負載均衡

因為每個SVC都是通過Label綁定微服務當中其中一個服務的一組POD,當外部或者集群其他服務發來請求時,SVC會通過負載均衡,將請求分發到這一組POD當中的其中一個
注:這里面要強調一下SVC是我們運維人員通過yaml文件或者是kubectl命令指定規則並創建的,而底層真正實現負載均衡和服務發現的是K8S中運行在每個NODE節點的kube-proxy組件。

那么SVC是如何通過kube-proxy組件來實現負載均衡和服務發現的呢?

kube-proxy工作原理

kube-proxy存在於各個node節點上,主要用於Service功能的實現(負載均衡和服務發現),具體來說,就是實現集群內的客戶端pod訪問service,或者是集群外的主機通過NodePort等方式訪問service。在之前版本的k8s中,kube-proxy默認使用的是iptables模式,通過各個node節點上的iptables規則來實現service的負載均衡,但是隨着service數量的增大,iptables模式由於線性查找匹配、全量更新等特點,其性能會顯著下降。從k8s的1.8版本開始,kube-proxy引入了IPVS模式,IPVS模式與iptables同樣基於Netfilter,但是采用的hash表,因此當service數量達到一定規模時,hash查表的速度優勢就會顯現出來,從而提高service的服務性能。

注:kube-proxy通過watch的方式監控着kube-APIServer寫入etcd中關於Pod的最新狀態信息,它一旦檢查到一個Pod資源被刪除了 或 新建,它將立即將這些變化,反應再iptables 或 ipvs規則中,以便iptables和ipvs在調度Clinet Pod請求到Server Pod時,不會出現Server Pod不存在的情況,如下圖所示:

image

如何創建SVC

對集群內部暴露服務的模式--Cluster

apiVersion: v1
kind: Service
metadata:
  labels:
    app: my-dep
  name: my-dep
spec:
  ports:
  - port: 8000      #設定Serivce對集群內部暴露的端口.
    protocol: TCP
    targetPort: 80  #設定Pod的端口,即Pod網絡的端口。
  selector:
    app: my-dep
  type: ClusterIP

image

對集群外部暴露服務的模式--NodePort

apiVersion: v1
kind: Service
metadata:
  labels:
    app: my-dep
  name: my-dep
spec:
  ports:
  - port: 8000      #設定Serivce對集群內部暴露的端口.
    protocol: TCP   
    targetPort: 80  #設定Pod的端口,即Pod網絡的端口。
  selector:
    app: my-dep
  type: NodePort


注:如果不在yaml文件當中指定NodePort端口,則NodePort是在Node節點上的30000-32767之間隨機暴漏端口
全文皆由本人的學習筆記總結而成,希望能對大家有幫助,若轉載請標明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM