
Service資源對象
介紹
在生產環(huán)境中,我們不能期望Pod一直是健壯的。假設Pod的容器很可能因為各種原因發(fā)送故障而掛掉。Deployment等Controller會通過動態(tài)創(chuàng)建和銷毀Pod來保證應用整體的健壯性。
在創(chuàng)建的每個Pod中,都有自己的IP地址,當Controller用新Pod替代發(fā)生故障的Pod時,新Pod會分配到新的IP地址。那么這樣就產生一個問題,如果在Pod是對外提供服務的,如HTTP服務,它們在重新創(chuàng)建時,IP地址也就發(fā)生了變化,那么客戶如何找到并訪問這個服務呢?此時Kubernetes就會有了Service。
Service是一個抽象概念,定義了一個服務的多個pod邏輯合集和訪問pod的策略,一般把Service稱為微服務。借助 Service,應用可以方便的實現服務發(fā)現與負載均衡,并實現應用的零宕機升級。Service 通過標簽來選取服務后端,一般配合 Replication Controller 或者 Deployment 來保證后端容器的正常運行。這些匹配標簽的 Pod IP 和端口列表組成 endpoints,由 kube-proxy 負責將服務 IP 負載均衡到這些 endpoints 上。
Service類型---發(fā)布服務
- ClusterIP: 默認類型,自動分配一個僅 cluster 內部可以訪問的虛擬 IP。
- NodePort: 在 ClusterIP 基礎上為 Service 在每臺機器上綁定一個端口,這樣就可以通過 NodeIP:NodePort 來訪問該服務。如果 kube-proxy 設置了 – - nodeport-addresses=10.240.0.0/16(v1.10 支持),那么僅該 NodePort 僅對設置在范圍內的 IP 有效。
- LoadBalancer: 在 NodePort 的基礎上,借助 cloud provider 創(chuàng)建一個外部的負載均衡器,并將請求轉發(fā)到 :NodePort
- ExternalName: 將服務通過 DNS CNAME 記錄方式轉發(fā)到指定的域名(通過 spec.externlName 設定)。需要 kube-dns 版本在 1.7 以上。
網絡代理模式
- userspace :client先請求serviceip,經由iptables轉發(fā)到kube-proxy上之后再轉發(fā)到pod上去。這種方式效率比較低。

- iptables :lient請求serviceip后會直接轉發(fā)到pod上。這種模式性能會高很多。kube-proxy就會負責將pod地址生成在node節(jié)點iptables規(guī)則中。

- ipvs :它是直接有內核中的ipvs規(guī)則來接受Client Pod請求,并處理該請求,再有內核封包后,直接發(fā)給指定的Server Pod。

注:
以上不論哪種,kube-proxy都通過watch的方式監(jiān)控著kube-APIServer寫入etcd中關于Pod的最新狀態(tài)信息,它一旦檢查到一個Pod資源被刪除了或新建,它立即將這些變化,反應在iptables 或 ipvs規(guī)則中,以便iptables和ipvs在調度Clinet Pod請求到Server Pod時,不會出現Server Pod不存在的情況。
創(chuàng)建服務
apiVersion: v1
kind: Service
metadata:
name: "maxscale"
labels:
mariadb: "mariadb"
entrypoint.mariadb: "mariadb"
spec:
type: NodePort
ports:
- name: maxscale-readwrite
port: 4006
targetPort: 4006
nodePort: 31783
- name: maxscale-readonly
port: 4008
targetPort: 4008
selector:
maxscale.mariadb: "mariadb"
yaml說明:
- selector: 指定了為哪一個標簽的app進行負載均衡。
- nodePort: 節(jié)點數監(jiān)聽的端口。
- targetPort: Pod監(jiān)聽的端口。
服務發(fā)現
headless service(無頭service)
headless service: 沒有ClusterIP的service, 它僅有一個service name.這個服務名解析得到的不是service的集群IP,而是Pod的IP,當其它人訪問該service時,將直接獲得Pod的IP,進行直接訪問。
示例
apiVersion: v1
kind: Service
metadata:
labels:
app: "es-cluster-discovery"
name: "es-cluster-discovery"
spec:
selector:
app: "es-node-instanceid"
ports:
- port: 9300
name: discovery
targetPort: 9300
以上es-cluster-discovery服務是用作es集群通過9300來發(fā)現其他待加入節(jié)點的Pod IP。es的“DISCOVERY_ZEN_PING_UNICAST_HOSTS”參數是待加入集群節(jié)點列表,此時可以將"es-cluster-discovery"作為該參數的值,進行解析,直接獲取到Pod的Ip。具體詳見 Elasticsearch容器化。
參考:https://kubernetes.io/zh/docs/concepts/services-networking/service/