Kubernetes---Service(SVC)服務

⒈介紹node

  kubernetes 經過標籤選擇的方式來匹配一組pod,而後提供對外訪問的一種機制
  一組pod能夠對應到多個svc的
  每個service(svc)均可以理解爲一個微服務
  Service有且只有一個算法 RB 輪詢,
  Service可以提供負載均衡的能力,可是在使用上有如下限制:
    ·只提供4層負載均衡能力【只能基於ip地址和端口進行轉發】,而沒有7層功能【不能經過主機名及域名的方案去進行負載均衡】,但有時咱們可能須要更多的匹配規則來轉發請求,這點上4層負載均衡是不支持的
 
⒉Service的類型
 
Service在K8s中有如下四種類型
  ·Clusterlp:默認類型,自動分配一個僅Cluster內部能夠訪問的虛擬IP【service建立一個僅集羣內部可訪問的ip,集羣內部其餘的pod能夠經過該服務訪問到其監控下的pod】
  ·NodePort:在ClusterlP基礎上爲Service在每臺機器上綁定一個端口,這樣就能夠經過:NodePort來訪問該服務【在service及各個node節點上開啓端口,外部的應用程序或客戶端訪問node的端口將會轉發到service的端口,而service將會依據負載均衡隨機將請求轉發到某一個pod的端口上。通常暴露服務經常使用的類型】
  ·LoadBalancer:在NodePort的基礎上,藉助 cloud provider 建立一個外部負載均衡器,並將請求轉發到:NodePort【在NodePort基礎之上,即各個節點前加入了負載均衡器實現了真正的高可用,通常雲供應商提供的k8s集羣就是這種】
  ·ExternalName:把集羣外部的服務引入到集羣內部來,在集羣內部直接使用。沒有任何類型代理被建立,這隻有kubernetes 1.7或更高版本的kube-dns 才支持【當咱們的集羣服務須要訪問k8s以外的集羣時,能夠選擇這種類型,而後把外部服務的IP及端口寫入到k8s服務中來,k8s的代理將會幫助咱們訪問到外部的集羣服務】
 
  1.ClusterIP
  clusterIP主要在每一個node節點使用iptables【新版本模式是ipvs代理模式所以此處爲ipvs,代理模式不一樣所使用的底層方案也是不一致的】,將發向clusterlP對應端口的數據,轉發到kube-proxy中。而後kube-proxy本身內部實現有負載均衡的方法,並能夠查詢到這個service下對應pod的地址和端口,進而把數據轉發給對應的pod的地址和端口
  
 
  爲了實現圖上的功能,主要須要如下幾個組件的協同工做:
    ·apiserver 用戶經過kubectl命令向apiserver發送建立service的命令,apiserver接收到請求後將數據存儲到etcd中
    ·kube-proxy kubernetes的每一個節點中都有一個叫作kube-porxy的進程,這個進程負責感知service,pod的變化,並將變化的信息寫入本地的iptables規則中
    ·iptables 使用NAT等技術將virtuallP的流量轉至endpoint中
   資源清單示例:
    ㈠建立一個Deployment  
apiVersion: apps/v1 
kind: Deployment 
metadata:
  name: myapp-deploy 
  namespace: default 
spec:
  replicas: 3 
  selector:
    matchLabels:
      app: myapp 
      release: stabel 
  template:
    metadata:
      1abels:
        app: myapp 
        release: stabel 
        env: test 
    spec:
      containers:
      - name: myapp
        image: fanqisoft/myapp:v2
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 80    

 

 

apiVersion: v1 
kind: Service 
metadata:
  name: myapp 
  namespace: default 
spec:
  type: ClusterIP 
  selector:
    app: myapp 
    release: stabel 
  ports:
  - name: http 
    port: 80 
    targetPort: 80

   

   Headless Service【無頭服務,無頭服務也是一種Cluster IP,只不過是一種特殊的Cluster IP】
  有時不須要或不想要負載均衡,以及單獨的Service IP。遇到這種狀況,能夠經過指定 ClusterIP(spec.clusterIP)的值爲「None」來建立 Headless Service。這類Service 並不會分配 Cluster IP,kube-proxy 不會處理它們,並且平臺也不會爲它們進行負載均衡和路由
  主要的特色是經過無頭服務的方式去解決hostname和portname的變化問題,也就是經過它去進行綁定
apiVersion: v1 
kind: Service 
metadata:
  name: myapp-headless 
  namespace: default 
spec:
  selector:
    app: myapp 
  clusterIP: "None"
  ports:
  - port: 80 
    targetPort: 80 
 對於svc,一旦建立成功之後,它會寫入到coreDNS中去,咱們的svc的建立會有一個主機名會被寫入到coreDNS,寫入的格式體就是 svc的名稱+命名空間的名稱+當前集羣的域名

 yum -y install bind-utils
 dig -t A myapp-headless.default.svc.cluster.local. @10.96.0.10

 意味着在無頭服務中,雖然它沒有ip了,但能夠經過訪問域名的方案依然能夠訪問服務下的pod

 

  2.NodePort算法

  nodePort的原理在於在node上開了一個端口,將向該端口的流量導入到kube-proxy,而後由 kube-proxy進一步到給對應的pod
apiVersion: v1 
kind: Service 
metadata:
  name: myapp 
  namespace: default 
spec:
  type: NodePort 
  selector:
    app: myapp 
    release: stabel 
  ports:
  - name: http 
    port: 80 
    targetPort: 80
#查詢流程 
iptables -t nat -nvL 
    KUBE-NODEPORTS  

  3.LoadBalancer後端

  loadBalancer和nodePort 實際上是同一種方式。區別在於 loadBalancer 比nodePort多了一步,就是能夠調用cloud provider【雲供應商】 去建立LB【負載均衡】來向節點導流api

  4.ExternalName緩存

  這種類型的 Service 經過返回 CNAME和它的值,能夠將服務映射到externalName字段的內容(例如:hub.coreqi.cn)。ExternalName Service 是Service的特例,它沒有 selector,也沒有定義任何的端口和Endpoint。相反的,對於運行在集羣外部的服務,它經過返回該外部服務的別名這種方式來提供服務
apiVersion: v1
kind: Service
metadata:
  name: my-service
  namespace: default
spec:
  type: ExternalName
  externalName: hub.coreqi.cn
  當查詢主機 my-service.defalut.svc.cluster.local(SVC_NAME.NAMESPACE.svc.cluster.local)時,集羣的DNS 服務將返回一個值my.database.example.com的CNAME記錄。訪問這個服務的工做方式和其餘的相同,惟一不一樣的是重定向發生在DNS層,並且不會進行代理或轉發。
 
⒊實現原理
apiServer: 監聽服務和端點經過kube-proxy去監控
kube-proxy:經過選擇標籤去監控對應的pod並寫入到iptable規則裏面去
客戶端訪問服務時經過iptables中的規則被定向到pod的地址信息
客戶端訪問pod是經過iptables去實現的v
iptables規則是經過kube-proxy去寫入的
apiserver經過監控kube-proxy去實現服務端點信息的發現
 
⒌k8s代理模式的分類
  在Kubernetes集羣中,每一個Node 運行一個kube-proxy 進程。kube-proxy負責爲service 實現了一種VIP(虛擬IP)的形式【能夠在集羣內部直接訪問】,而不是ExternalName【返回集羣外部的地址信息】 的形式。在Kubernetes v1.0版本,代理徹底由userspace實現。在Kubernetesv1.1版本,新增了iptables代理,但並非默認的運行模式。從Kubernetesv1.2起,默認就是iptables 代理。在Kubernetes v1.8.0-beta.0中,添加了ipvs代理
  在Kubernetes 1.14版本開始默認使用ipvs代理
  在Kubernetes v1.0版本,service是「4層」(TCP/UDP over IP)概念。在Kubernetes v1.1版本,新增了IngressAPI(beta版),用來表示「7層」(HTTP)服務!能夠進行7層的負載均衡。正是由於有了Ingress的API接口,咱們纔有了7層調度的功能。
 
   爲什麼不使用 round-robin DNS?
  k8s不論是歷史仍是如今都沒有使用過DNS,不採用DNS負載均衡集羣,最大最有意義的一點就是DNS會在不少的客戶端裏進行緩存,很對服務訪問DNS進行域名解析的時候解析完成之後獲得地址之後不少的服務都不會對DNS的緩存進行清除,也就意味着只要緩存存在服務在下次訪問的時候仍是這個地址信息,所以也就達不到咱們負載均衡的要求了,所以DNS通常僅僅做爲負載均衡的一種輔助手段
 
  1.userspace代理模式  
  客戶端首先訪問iptables經過iptables訪問到kube-proxy而後訪問到具體的pod上
  也就是說每次訪問的時候都須要Kube-proxy進行一次代理
  也就是說kube-proxy壓力是很是大的
  同時kube-apiserver也會監控kube-proxy服務更新及端點的維護
  2.iptables代理模式
  捨棄掉了kube-proxy,全部訪問直接經過iptables而不須要kube-proxy去調度
  這樣的話訪問速度就會大大增長以及kube-proxy穩定性會提升壓力將會減小不少
  固然使用iptables(防火牆)性能並不會怎麼高,但除此以外幾乎沒有什麼缺點。
  kube-apiserver依然經過監控kube-proxy去實現iptables的端口的更新維護
  3.ipvs代理模式
  將iptables代理模式中iptables變動爲ipvs,原來是把全部的調度規則經過iptables
  進行所謂的服務轉發定向的變成了經過ipvs模塊去實現負載均衡以及流量導向,而且和
  iptables代理模式相同,全部的訪問也是不通過kube-proxy的
  若是沒有提早安裝ipvs模塊以及一些基本需求沒有完成,那些k8s將會使用iptables的代理模式
    ipvs這種模式,kube-proxy會監視Kubernetes service 對象和Endpoints,調用netlink 接口以相應地建立ipvs 規則並按期與Kubernetes service對象和Endpoints 對象同步ipvs規則,以確保ipvs狀態與指望一致。訪問服務時,流量將被重定向到其中一個後端 Pod
    與iptables相似,ipvs於netfilter的hook功能,但使用哈希表做爲底層數據結構並在內核空間中工做。這意味着ipvs能夠更快地重定向流量,而且在同步代理規則時具備更好的性能。此外,ipvs爲負載均衡算法提供了更多選項,例如:
    ·rr:輪詢調度
    ·1c:最小鏈接數
    ·dh:目標哈希
    ·sh:源哈希
    ·sed:最短時間望延遲
    ·nq:不排隊調度

    注意: ipvs模式假定在運行kube-proxy以前在節點上都已經安裝了IPVS內核模塊。當kube-proxy以ipvs代理模式啓動時,kube-proxy將驗證節點上是否安裝了IPVS模塊,若是未安裝,則kube-proxy將回退到iptables代理模式
#查看ipvs代理規則
ipvsadm -Ln
相關文章
相關標籤/搜索