Service資源對象
介紹
在生產(chǎn)環(huán)境中,我們不能期望Pod一直是健壯的。假設(shè)Pod的容器很可能因?yàn)楦鞣N原因發(fā)送故障而掛掉。Deployment等Controller會通過動態(tài)創(chuàng)建和銷毀Pod來保證應(yīng)用整體的健壯性。
在創(chuàng)建的每個Pod中,都有自己的IP地址,當(dāng)Controller用新Pod替代發(fā)生故障的Pod時,新Pod會分配到新的IP地址。那么這樣就產(chǎn)生一個問題,如果在Pod是對外提供服務(wù)的,如HTTP服務(wù),它們在重新創(chuàng)建時,IP地址也就發(fā)生了變化,那么客戶如何找到并訪問這個服務(wù)呢?此時Kubernetes就會有了Service。
Service是一個抽象概念,定義了一個服務(wù)的多個pod邏輯合集和訪問pod的策略,一般把Service稱為微服務(wù)。借助 Service,應(yīng)用可以方便的實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)與負(fù)載均衡,并實(shí)現(xiàn)應(yīng)用的零宕機(jī)升級。Service 通過標(biāo)簽來選取服務(wù)后端,一般配合 Replication Controller 或者 Deployment 來保證后端容器的正常運(yùn)行。這些匹配標(biāo)簽的 Pod IP 和端口列表組成 endpoints,由 kube-proxy 負(fù)責(zé)將服務(wù) IP 負(fù)載均衡到這些 endpoints 上。
Service類型---發(fā)布服務(wù)
- ClusterIP: 默認(rèn)類型,自動分配一個僅 cluster 內(nèi)部可以訪問的虛擬 IP。
- NodePort: 在 ClusterIP 基礎(chǔ)上為 Service 在每臺機(jī)器上綁定一個端口,這樣就可以通過 NodeIP:NodePort 來訪問該服務(wù)。如果 kube-proxy 設(shè)置了 – - nodeport-addresses=10.240.0.0/16(v1.10 支持),那么僅該 NodePort 僅對設(shè)置在范圍內(nèi)的 IP 有效。
- LoadBalancer: 在 NodePort 的基礎(chǔ)上,借助 cloud provider 創(chuàng)建一個外部的負(fù)載均衡器,并將請求轉(zhuǎn)發(fā)到 :NodePort
- ExternalName: 將服務(wù)通過 DNS CNAME 記錄方式轉(zhuǎn)發(fā)到指定的域名(通過 spec.externlName 設(shè)定)。需要 kube-dns 版本在 1.7 以上。
網(wǎng)絡(luò)代理模式
- userspace :client先請求serviceip,經(jīng)由iptables轉(zhuǎn)發(fā)到kube-proxy上之后再轉(zhuǎn)發(fā)到pod上去。這種方式效率比較低。
- iptables :lient請求serviceip后會直接轉(zhuǎn)發(fā)到pod上。這種模式性能會高很多。kube-proxy就會負(fù)責(zé)將pod地址生成在node節(jié)點(diǎn)iptables規(guī)則中。
- ipvs :它是直接有內(nèi)核中的ipvs規(guī)則來接受Client Pod請求,并處理該請求,再有內(nèi)核封包后,直接發(fā)給指定的Server Pod。
注:
以上不論哪種,kube-proxy都通過watch的方式監(jiān)控著kube-APIServer寫入etcd中關(guān)于Pod的最新狀態(tài)信息,它一旦檢查到一個Pod資源被刪除了或新建,它立即將這些變化,反應(yīng)在iptables 或 ipvs規(guī)則中,以便iptables和ipvs在調(diào)度Clinet Pod請求到Server Pod時,不會出現(xiàn)Server Pod不存在的情況。
創(chuàng)建服務(wù)
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: 指定了為哪一個標(biāo)簽的app進(jìn)行負(fù)載均衡。
- nodePort: 節(jié)點(diǎn)數(shù)監(jiān)聽的端口。
- targetPort: Pod監(jiān)聽的端口。
服務(wù)發(fā)現(xiàn)
headless service(無頭service)
headless service: 沒有ClusterIP的service, 它僅有一個service name.這個服務(wù)名解析得到的不是service的集群IP,而是Pod的IP,當(dāng)其它人訪問該service時,將直接獲得Pod的IP,進(jìn)行直接訪問。
示例
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服務(wù)是用作es集群通過9300來發(fā)現(xiàn)其他待加入節(jié)點(diǎn)的Pod IP。es的“DISCOVERY_ZEN_PING_UNICAST_HOSTS”參數(shù)是待加入集群節(jié)點(diǎn)列表,此時可以將"es-cluster-discovery"作為該參數(shù)的值,進(jìn)行解析,直接獲取到Pod的Ip。具體詳見 Elasticsearch容器化。
參考:https://kubernetes.io/zh/docs/concepts/services-networking/service/