k8s~k8s裏的服務Service

k8s用命名空間namespace把資源進行隔離,默認狀況下,相同的命名空間裏的服務能夠相互通信,反之進行隔離。前端

服務Service

1.1 Service

Kubernetes中一個應用服務會有一個或多個實例(Pod,Pod能夠經過rs進行多複本的創建),每一個實例(Pod)的IP地址由網絡插件動態隨機分配(Pod重啓後IP地址會改變)。爲屏蔽這些後端實例的動態變化和對多實例的負載均衡,引入了Service這個資源對象,以下所示:node

apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
  labels:
    app: nginx
spec:
  type: ClusterIP
  ports:
    - port: 80
       targetPort: 80
  selector:  #service經過selector和pod創建關聯
    app: nginx

根據建立Service的type類型不一樣,可分紅4種模式:nginx

  • ClusterIP: 默認方式。根據是否生成ClusterIP又可分爲普通Service和Headless Service兩類:
    • 普通Service:經過爲Kubernetes的Service分配一個集羣內部可訪問的固定虛擬IP(Cluster IP),實現集羣內的訪問。爲最多見的方式。
    • Headless Service:該服務不會分配Cluster IP,也不經過kube-proxy作反向代理和負載均衡。而是經過DNS提供穩定的絡ID來訪問,DNS會將headless service的後端直接解析爲podIP列表。主要供StatefulSet使用。
  • NodePort:除了使用Cluster IP以外,還經過將service的port映射到集羣內每一個節點的相同一個端口,實現經過nodeIP:nodePort從集羣外訪問服務。
  • LoadBalancer:和nodePort相似,不過除了使用一個Cluster IP和nodePort以外,還會向所使用的公有云申請一個負載均衡器(負載均衡器後端映射到各節點的nodePort),實現從集羣外經過LB訪問服務。
  • ExternalName:是 Service 的特例。此模式主要面向運行在集羣外部的服務,經過它能夠將外部服務映射進k8s集羣,且具有k8s內服務的一些特徵(如具有namespace等屬性),來爲集羣內部提供服務。此模式要求kube-dns的版本爲1.7或以上。這種模式和前三種模式(除headless service)最大的不一樣是重定向依賴的是dns層次,而不是經過kube-proxy。
    好比,在service定義中指定externalName的值"my.database.example.com":

此時k8s集羣內的DNS服務會給集羣內的服務名 . .svc.cluster.local 建立一個CNAME記錄,其值爲指定的"my.database.example.com"。
當查詢k8s集羣內的服務my-service.prod.svc.cluster.local時,集羣的 DNS 服務將返回映射的CNAME記錄"foo.bar.example.com"。
後端

備註:
前3種模式,定義服務的時候經過selector指定服務對應的pods,根據pods的地址建立出endpoints做爲服務後端;Endpoints Controller會watch Service以及pod的變化,維護對應的Endpoint信息。kube-proxy根據Service和Endpoint來維護本地的路由規則。當Endpoint發生變化,即Service以及關聯的pod發生變化,kube-proxy都會在每一個節點上更新iptables,實現一層負載均衡。
而ExternalName模式則不指定selector,相應的也就沒有port和endpoints。
ExternalName和ClusterIP中的Headles Service同屬於Headless Service的兩種狀況。Headless Service主要是指不分配Service IP,且不經過kube-proxy作反向代理和負載均衡的服務。api

1.2 Port

Service中主要涉及三種Port: * port 這裏的port表示service暴露在clusterIP上的端口,clusterIP:Port 是提供給集羣內部訪問kubernetes服務的入口。網絡

  • targetPort
    containerPort,targetPort是pod上的端口,從port和nodePort上到來的數據最終通過kube-proxy流入到後端pod的targetPort上進入容器。app

  • nodePort
    nodeIP:nodePort 是提供給從集羣外部訪問kubernetes服務的入口。負載均衡

總的來講,port和nodePort都是service的端口,前者暴露給從集羣內訪問服務,後者暴露給從集羣外訪問服務。從這兩個端口到來的數據都須要通過反向代理kube-proxy流入後端具體pod的targetPort,從而進入到pod上的容器內。less

1.3 IP

使用Service服務還會涉及到幾種IP:google

  • ClusterIP
    Pod IP 地址是實際存在於某個網卡(能夠是虛擬設備)上的,但clusterIP就不同了,沒有網絡設備承載這個地址。它是一個虛擬地址,由kube-proxy使用iptables規則從新定向到其本地端口,再均衡到後端Pod。當kube-proxy發現一個新的service後,它會在本地節點打開一個任意端口,建立相應的iptables規則,重定向服務的clusterIP和port到這個新建的端口,開始接受到達這個服務的鏈接。

  • Pod IP
    Pod的IP,每一個Pod啓動時,會自動建立一個鏡像爲gcr.io/google_containers/pause的容器,Pod內部其餘容器的網絡模式使用container模式,並指定爲pause容器的ID,即:network_mode: "container:pause容器ID",使得Pod內全部容器共享pause容器的網絡,與外部的通訊經由此容器代理,pause容器的IP也能夠稱爲Pod IP。

  • 節點IP Node-IP,service對象在Cluster IP range池中分配到的IP只能在內部訪問,若是服務做爲一個應用程序內部的層次,仍是很合適的。若是這個service做爲前端服務,準備爲集羣外的客戶提供業務,咱們就須要給這個服務提供公共IP了。指定service的spec.type=NodePort,這個類型的service,系統會給它在集羣的各個代理節點上分配一個節點級別的端口,能訪問到代理節點的客戶端都能訪問這個端口,從而訪問到服務。

相關文章
相關標籤/搜索