這篇文章將為大家詳細(xì)講解有關(guān)Kubernetes中Service和Ingress的作用是什么,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。
成都創(chuàng)新互聯(lián)公司專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站制作、做網(wǎng)站、瑪多網(wǎng)絡(luò)推廣、微信平臺(tái)小程序開發(fā)、瑪多網(wǎng)絡(luò)營(yíng)銷、瑪多企業(yè)策劃、瑪多品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);成都創(chuàng)新互聯(lián)公司為所有大學(xué)生創(chuàng)業(yè)者提供瑪多建站搭建服務(wù),24小時(shí)服務(wù)熱線:18982081108,官方網(wǎng)址:www.cdcxhl.com
Service資源概述
Service是Kubernetes的核心資源類型之一,它通過規(guī)則定義出由多個(gè)Pod對(duì)象組合而成的邏輯集合,以及訪問這組Pod的策略。 由Deployment等控制器管理的Pod對(duì)象在中斷或擴(kuò)縮容后,Pod組合的IP地址都會(huì)發(fā)生變化,而引入Service資源后,就可以基于標(biāo)簽選擇器將一組Pod定義成一個(gè)邏輯組合,并通過自己的IP地址和端口調(diào)度代理請(qǐng)求至組內(nèi)的Pod對(duì)象之上,它向客戶端隱藏了真實(shí)的、處理用戶請(qǐng)求的Pod資源,使得客戶端的請(qǐng)求看上去就像是由Service直接處理并進(jìn)行響應(yīng)的一樣。而且Service與Pod對(duì)象之間通過標(biāo)簽選擇器以松耦合的方式關(guān)聯(lián),它可以先于Pod對(duì)象創(chuàng)建而不會(huì)發(fā)生錯(cuò)誤。
Service資源基本的配置清單:
apiVersion: v1 kind: Service metadata: name: myapp-svc spec: selector: app: myapp ports: - name: http port: 80 targetPort: 80 protocol: TCP
Service資源myapp-svc通過標(biāo)簽選擇器關(guān)聯(lián)至標(biāo)簽為“app=myapp”的各Pod對(duì)象,它會(huì)自動(dòng)創(chuàng)建名為myapp-svc的Endpoints資源對(duì)象,并自動(dòng)配置一個(gè)ClusterIP,暴露的端口由port字段進(jìn)行指定,后端各Pod對(duì)象的端口則由targetPort給出。 分別查看service和endpoint的狀態(tài):
kubectl get svc myapp-svc kubectl get endpoints myapp-svc
Service資源的默認(rèn)類型為ClusterIP,它僅能接收來自于集群中的Pod對(duì)象中的客戶端程序的訪問請(qǐng)求。所以為了測(cè)試,會(huì)創(chuàng)建一個(gè)專用的Pod對(duì)象,利用其交互式接口來訪問service資源。
kubectl run cirros-$RANDOM --rm -it --image=cirros -- sh
啟動(dòng)了一個(gè)運(yùn)行CirrOS容器的Pod,CirrOS是設(shè)計(jì)用來進(jìn)行云計(jì)算環(huán)境測(cè)試的Linux微型發(fā)行版,它自帶HTTP客戶端工具curl等。 在容器的交互式接口訪問ClusterIP:Port
/ # curl http://10.105.246.145:80 Hello MyApp | Version: v1 | Pod Name
Kubernetes集群默認(rèn)的Service代理模式為iptables,而且使用隨機(jī)調(diào)度算法,因此Service會(huì)將客戶端請(qǐng)求隨機(jī)調(diào)度至與其關(guān)聯(lián)的某個(gè)后端Pod資源上。
Service資源還支持Session affinity(會(huì)話粘性)機(jī)制,它能夠?qū)碜酝粋€(gè)客戶端的請(qǐng)求始終轉(zhuǎn)發(fā)至同一個(gè)后端的Pod對(duì)象,適用于需要基于客戶端身份保存某些私有信息,并根據(jù)這些私有信息追蹤用戶的活動(dòng)等一類的需求。 Service資源通過spec.sessionAffinity和spec.sessionAffinityConfig兩個(gè)字段配置粘性會(huì)話:
sessionAffinity字段用于定義要使用的粘性會(huì)話的類型,它僅支持使用“None”和“ClientIP”兩種屬性值。?
None:不使用sessionAffinity,默認(rèn)值。?
ClientIP:基于客戶端IP地址識(shí)別客戶端身份,把來自同一個(gè)源IP地址的請(qǐng)求始終調(diào)度至同一個(gè)Pod對(duì)象。
sessionAffinityConfig用于配置其會(huì)話保持的時(shí)長(zhǎng),其可用的時(shí)長(zhǎng)范圍為“1~86400”,默認(rèn)為10800秒
但是Service資源的Session affinity機(jī)制僅能基于客戶端IP地址識(shí)別客戶端身份,它會(huì)把經(jīng)由同一個(gè)NAT服務(wù)器進(jìn)行源地址轉(zhuǎn)換的所有客戶端識(shí)別為同一個(gè)客戶端,調(diào)度粒度粗糙且效果不佳,因此實(shí)踐中并不推薦使用此種方法實(shí)現(xiàn)粘性會(huì)話。
Service為Pod中的服務(wù)類應(yīng)用提供了一個(gè)穩(wěn)定的訪問入口,但Pod客戶端中的應(yīng)用如何得知某個(gè)特定Service資源的IP和端口呢,這就需要借助服務(wù)發(fā)現(xiàn)機(jī)制來進(jìn)行。 服務(wù)發(fā)現(xiàn)機(jī)制的基本實(shí)現(xiàn),一般是事先部署好一個(gè)網(wǎng)絡(luò)位置較為穩(wěn)定的服務(wù)注冊(cè)中心(也稱為服務(wù)總線),服務(wù)提供者(服務(wù)端)向注冊(cè)中心注冊(cè)自己的位置信息,并在變動(dòng)后及時(shí)予以更新,服務(wù)消費(fèi)者則周期性地從注冊(cè)中心獲取服務(wù)提供者的最新位置信息從而“發(fā)現(xiàn)”要訪問的目標(biāo)服務(wù)資源。 在K8S中可以基于CoreDNS進(jìn)行服務(wù)發(fā)現(xiàn),甚至也可以使用簡(jiǎn)單的環(huán)境變量方式。
Service的IP地址默認(rèn)僅在集群內(nèi)可達(dá),集群外部想訪問服務(wù),需要首先進(jìn)行服務(wù)的暴露。
Service有四種類似ClusterIP、NodePort、LoadBalancer和ExternalName
ClusterIP:通過集群內(nèi)部IP地址暴露服務(wù),此地址僅在集群內(nèi)部可達(dá),而無(wú)法被集群外部的客戶端訪問;
NodePort:建立在ClusterIP類型之上,其在每個(gè)Node的IP地址的某靜態(tài)端口(NodePort)暴露服務(wù),NodePort的路由目標(biāo)為ClusterIP,簡(jiǎn)單來說,NodePort類型就是在工作節(jié)點(diǎn)的IP地址上選擇一個(gè)端口用于將集群外部的用戶請(qǐng)求轉(zhuǎn)發(fā)至目標(biāo)Service的ClusterIP和Port,這種類型的Service既可如ClusterIP一樣受到集群內(nèi)部客戶端Pod的訪問,也會(huì)受到集群外部客戶端通過套接字NodeIP:NodePort進(jìn)行的請(qǐng)求;
LoadBalancer:建構(gòu)在NodePort類型之上,其通過cloud provider提供的負(fù)載均衡器將服務(wù)暴露到集群外部,LoadBalancer類型的Service會(huì)指向關(guān)聯(lián)至Kubernetes集群外部的某個(gè)負(fù)載均衡設(shè)備,該設(shè)備通過工作節(jié)點(diǎn)之上的NodePort向集群內(nèi)部發(fā)送請(qǐng)求流量,這種Service的優(yōu)勢(shì)在于,能夠把來自于集群外部客戶端的請(qǐng)求調(diào)度至所有節(jié)點(diǎn)(或部分節(jié)點(diǎn))的NodePort之上,而不是依賴于客戶端自行決定連接至哪個(gè)節(jié)點(diǎn),從而避免了因客戶端指定的節(jié)點(diǎn)故障而導(dǎo)致的服務(wù)不可用;
ExternalName:通過將Service映射至由externalName字段的內(nèi)容指定的主機(jī)名來暴露服務(wù),此主機(jī)名需要被DNS服務(wù)解析至CNAME類型的記錄。這種類型并非定義由Kubernetes集群提供的服務(wù),而是把集群外部的某服務(wù)以DNS CNAME記錄的方式映射到集群內(nèi),從而讓集群內(nèi)的Pod資源能夠訪問外部的Service的一種實(shí)現(xiàn)方式,這種類型的Service沒有ClusterIP和NodePort,也沒有標(biāo)簽選擇器用于選擇Pod資源。
NodePort型的Service資源,其配置清單與前面默認(rèn)的ClusterIP類型類似,只是要顯式地在spec下指定type: NodePort
此外還可以指定Node端口,但必須在30000-32767之間,而且推薦使用集群自動(dòng)分配的端口以避免端口的沖突。
NodePort類型的Service資源雖然能夠于集群外部訪問得到,但外部客戶端必須得事先得知NodePort和集群中至少一個(gè)節(jié)點(diǎn)的IP地址,且選定的節(jié)點(diǎn)發(fā)生故障時(shí),客戶端還得自行選擇請(qǐng)求訪問其他的節(jié)點(diǎn),此外有時(shí)節(jié)點(diǎn)并不允許外界訪問,LoadBalancer類型可將請(qǐng)求流量調(diào)度至各節(jié)點(diǎn)的NodePort之上。 創(chuàng)建LoadBalancer類型需要指定type: LoadBalancer
,
ExternalName類型的Service資源用于將集群外部的服務(wù)發(fā)布到集群中以供Pod中的應(yīng)用程序訪問。需要指定type: ExternalName
和externalName,比如externalName: redis.ilinux.io
,externalName屬性定義了一個(gè)CNAME記錄用于返回外部真正提供服務(wù)的主機(jī)的別名,而后通過CNAME記錄值獲取到相關(guān)主機(jī)的IP地址。
spec: type: ExternalName externalName: redis.ilinux.io
服務(wù)創(chuàng)建后通過serviceName訪問相應(yīng)的服務(wù),ClusterDNS會(huì)將此名稱以CNAME格式解析為spec.externalName字段中的名稱,而后通過DNS服務(wù)將其解析為相應(yīng)的主機(jī)的IP地址。
在Kubernetes中,Service資源和Pod資源的IP地址僅能用于集群網(wǎng)絡(luò)內(nèi)部的通信,所有的網(wǎng)絡(luò)流量都無(wú)法穿透邊界路由器以實(shí)現(xiàn)集群內(nèi)外通信。Kubernetes提供了兩種內(nèi)建的云端負(fù)載均衡機(jī)制(cloud loadbalancing)用于發(fā)布公共應(yīng)用:
一種是工作于傳輸層的Service資源,它實(shí)現(xiàn)的是“TCP負(fù)載均衡器”,無(wú)論是iptables還是ipvs模型的Service資源都配置于Linux內(nèi)核中的Netfilter之上進(jìn)行四層調(diào)度,是一種類型更為通用的調(diào)度器,支持調(diào)度HTTP、MySQL等應(yīng)用層服務(wù)。 但由于工作于傳輸層而功能有局限,比如不支持基于URL的請(qǐng)求調(diào)度機(jī)制,而且Kubernetes也不支持為其配置任何類型的健康檢查。
另一種便是Ingress資源,它實(shí)現(xiàn)的是“HTTP(S)負(fù)載均衡器”,屬于應(yīng)用層負(fù)載均衡機(jī)制的一種,它提供了諸如可自定義URL映射和TLS卸載等功能,并支持多種類型的后端服務(wù)器健康狀態(tài)檢查機(jī)制。
Ingress是Kubernetes API的標(biāo)準(zhǔn)資源類型之一,它其實(shí)就是一組基于DNS名稱(host)或URL路徑把請(qǐng)求轉(zhuǎn)發(fā)至指定的Service資源的規(guī)則,用于將集群外部的請(qǐng)求流量轉(zhuǎn)發(fā)至集群內(nèi)部完成服務(wù)發(fā)布,它僅是一組路由規(guī)則的集合,Ingress控制器根據(jù)這些規(guī)則來匹配并路由請(qǐng)求流量。
Ingress資源是基于HTTP虛擬主機(jī)或URL的轉(zhuǎn)發(fā)規(guī)則。Ingress資源的定義方式舉例:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-ingress annotations: kubernetes.io/ingress.class: "nginx" spec: rules: - host: www.ilinux.io http: paths: - path: / pathType: Prefix backend: service: name: myapp-svc port: number: 80
spec字段下主要嵌套如下三個(gè)字段
rules,用于定義當(dāng)前Ingress資源的轉(zhuǎn)發(fā)規(guī)則列表;未由rules定義規(guī)則,或者沒有匹配到任何規(guī)則時(shí),所有流量都會(huì)轉(zhuǎn)發(fā)到由backend定義的默認(rèn)后端。?
backend,默認(rèn)的后端用于服務(wù)那些沒有匹配到任何規(guī)則的請(qǐng)求;定義Ingress資源時(shí),至少應(yīng)該定義backend或rules兩者之一;此字段用于讓負(fù)載均衡器指定一個(gè)全局默認(rèn)的后端。backend對(duì)象的定義由兩個(gè)必選的內(nèi)嵌字段組成:serviceName和servicePort,分別用于指定流量轉(zhuǎn)發(fā)的后端目標(biāo)Service資源的名稱和端口。?
tls,TLS配置,目前僅支持通過默認(rèn)端口443提供服務(wù);如果要配置指定的列表成員指向了不同的主機(jī),則必須通過SNI TLS擴(kuò)展機(jī)制來支持此功能。
暴露單個(gè)Service的方法可以使用NodePort、LoadBalancer,也可以使用Ingress來暴露服務(wù),只需要為Ingress指定“default backend”,這樣Ingress控制器會(huì)為其分配一個(gè)IP地址接入請(qǐng)求流量,并將它們轉(zhuǎn)至指定的后段service,如:
spec: backend: serviceName: my-svc servicePort: 80
Ingress也支持基于URL路徑進(jìn)行流量分發(fā),如:
spec: rules: - host: www.ilinux.io http: paths: - path: /web backend: service: name: myapp-svc-web port: number: 80 - path: /api backend: service: name: myapp-svc-api port: number: 80
上面定義的規(guī)則會(huì)將對(duì)www.ilinux.io/web的請(qǐng)求轉(zhuǎn)發(fā)到前端service myapp-svc-web,而將www.ilinux.io/api請(qǐng)求轉(zhuǎn)發(fā)到后段service myapp-svc-api。
如果服務(wù)按照域名進(jìn)行劃分,可以將Ingress基于虛擬主機(jī)定義如下:
spec: rules: - host: web.ilinux.io ... - host: api.ilinux.io
如果需要以HTTPS發(fā)布Service資源,也可以配置TLS協(xié)議的Ingress資源,但需要基于一個(gè)含有私鑰和證書的Secret對(duì)象,這在后面的章節(jié)會(huì)涉及到,在Ingress資源中引用此Secret即可讓Ingress控制器加載并配置為HTTPS服務(wù):
spec: tls: - secretName: ilinuxSecret backend: ...
Ingress控制器自身是運(yùn)行于Pod中的容器應(yīng)用,一般是Nginx或Envoy一類的具有代理及負(fù)載均衡功能的守護(hù)進(jìn)程,它監(jiān)視著來自于API Server的Ingress對(duì)象狀態(tài),并以其規(guī)則生成相應(yīng)的應(yīng)用程序?qū)S懈袷降呐渲梦募⑼ㄟ^重載或重啟守護(hù)進(jìn)程而使新配置生效。例如,對(duì)于Nginx來說,Ingress規(guī)則需要轉(zhuǎn)換為Nginx的配置信息。 既然Ingress控制器實(shí)際上也是Pod資源,那么也需要接入外部流量,這可以使用NodePort或LoadBalancer類型的Service對(duì)象為其接入集群外部的請(qǐng)求流量;或者借助于DaemonSet控制器,將Ingress控制器的Pod資源各自以單一實(shí)例的方式運(yùn)行于集群的所有或部分工作節(jié)點(diǎn)之上,并配置這類Pod對(duì)象以hostPort或hostNetwork的方式在當(dāng)前節(jié)點(diǎn)接入外部流量。 以部署ingress-nginx并通過專用的Service接入流量為例: 首先apply在線的mandatory.yaml來部署ingress-nginx所需的全部資源,它們的namespace:為ingress-nginx:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.24.1/deploy/mandatory.yaml
然后定義專用的NodePort型Service資源,注意其selector要與nginx-ingress-controller的selector保持一致:
apiVersion: v1 kind: Service metadata: name: ingress-nginx-controller namespace: ingress-nginx spec: type: NodePort selector: app.kubernetes.io/name: ingress-nginx ports: - port: 80 name: http nodePort: 30080 - port: 443 name: https nodePort: 30443
然后就可以通過這個(gè)NodePort型Serviced的IP:30002訪問了?;蛘咭部梢愿鶕?jù)ingress指定的host名稱配置etc/hosts,比如對(duì)于如下的ingress配置:
spec: rules: - host: tomcat.ilinux.io
sudo vim /etc/hosts
,添加一行
127.0.0.1 tomcat.ilinux.io
關(guān)于Kubernetes中Service和Ingress的作用是什么就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。