摘要:如果在一個(gè)中部署使用,將地段設(shè)置為將會(huì)使使用人家提供的負(fù)載均衡。
概述
kubernetes中pods是平凡的,可創(chuàng)建可銷毀而且不可再生。 ReplicationControllers可以動(dòng)態(tài)的創(chuàng)建&銷毀pods(如擴(kuò)容 or 縮容 or 更新)。雖然pods有他們多帶帶的ip,但是他們的ip并不能得到穩(wěn)定的保證,這將會(huì)導(dǎo)致一個(gè)問題,如果在kubernetes集群中,有一些pods(backends)為另一些pods(frontend)提供一些功能,如何能保證frontend能夠找到&鏈接到backends。
引入Services。
kubernetes services是一個(gè)抽象的概念,定義了如何和一組pods相關(guān)聯(lián)—— 有時(shí)候叫做“micro-service”。一個(gè)service通過Label Selector來篩選出一組pods(下文會(huì)說明什么情況下不需要selector)。
舉個(gè)栗子,設(shè)想一個(gè)擁有三個(gè)節(jié)點(diǎn)的圖片處理backend,這三個(gè)節(jié)點(diǎn)都可以隨時(shí)替代——frontend并不關(guān)系鏈接的是哪一個(gè)。即使組成backend的pods發(fā)生了變動(dòng),frontend也不必關(guān)心連接到哪個(gè)backend。services將frontend和backend的鏈接關(guān)系解耦。
對(duì)于kubernetes本身的應(yīng)用來說,kubernetes提供了一個(gè)簡單的endpoint 的api,對(duì)于非kubernetes本身的應(yīng)用,kubernetes為servicet提供了一個(gè)解決方案,通過一個(gè)設(shè)定vip的bridge來鏈接pods。
定義一個(gè)service在kubernetes中,services和pods一樣都是一個(gè)REST對(duì)象。同其他的REST對(duì)象一樣,通過POST來創(chuàng)建一個(gè)service。比如,有一組pods,每個(gè)pod對(duì)外暴露9376端口 他們的label為“app=MyApp”:
{ "kind": "Service", "apiVersion": "v1", "metadata": { "name": "my-service" }, "spec": { "selector": { "app": "MyApp" }, "ports": [ { "protocol": "TCP", "port": 80, "targetPort": 9376 } ] } }
上述的json將會(huì)做以下事情:創(chuàng)建一個(gè)叫“my-service”的service,它映射了label為“app=MyApp”的pods端口9376,這個(gè)service將會(huì)被分配一個(gè)ip(cluster ip),service用這個(gè)ip作為代理,service的selector將會(huì)一直對(duì)pods進(jìn)行篩選,并將起pods結(jié)果放入一個(gè)也焦作“my-service”的Endpoints中。
注意,一個(gè)service可能將流量引入到任何一個(gè)targetPost,默認(rèn)targetPort字段和port字段是相同的。有趣的是targetPort 也可以是一個(gè)string,可以設(shè)定為是一組pods所映射port的name。在每個(gè)pod中,這個(gè)name所對(duì)應(yīng)的真實(shí)port都可以不同。這為部署& 升級(jí)service帶來了很大的靈活性,比如 可以在
kubernetes services支持TCP & UDP協(xié)議,默認(rèn)為tcp。
Services without selectorskubernetes service通常是鏈接pods的一個(gè)抽象層,但是service也可以作用在其他類型的backend。比如:
在生產(chǎn)環(huán)境中你想使用一個(gè)外部的database集群,在測(cè)試環(huán)境中使用自己的database;
希望將一個(gè)service指向另一個(gè)namespace中的service 或者 指向另外一個(gè)集群;
希望將非kubernetes的工作代碼環(huán)境遷移到kubernetes中;
在以上任意一個(gè)情景中,都可以使用到不指定selector的service:
{ "kind": "Service", "apiVersion": "v1", "metadata": { "name": "my-service" }, "spec": { "ports": [ { "protocol": "TCP", "port": 80, "targetPort": 9376 } ] } }
在這個(gè)例子中,因?yàn)闆]有使用到selector,因此沒有一個(gè)明確的Endpoint對(duì)象被創(chuàng)建。 因此需要手動(dòng)的將service映射到對(duì)應(yīng)的endpoint:
{ "kind": "Endpoints", "apiVersion": "v1", "metadata": { "name": "my-service" }, "subsets": [ { "addresses": [ { "IP": "1.2.3.4" } ], "ports": [ { "port": 80 } ] } ] }
無論有沒有selector都不會(huì)影響這個(gè)service,其router指向了這個(gè)endpoint(在本例中為1.2.3.4:80)。
虛IP & service代理(Virtual IPs and service proxies)kubernetes中的每個(gè)node都會(huì)運(yùn)行一個(gè)kube-proxy。他為每個(gè)service都映射一個(gè)本地port,任何連接這個(gè)本地port的請(qǐng)求都會(huì)轉(zhuǎn)到backend后的隨機(jī)一個(gè)pod,service中的字段SessionAffinity決定了使用backend的哪個(gè)pod,最后在本地建立一些iptables規(guī)則,這樣訪問service的cluster ip以及對(duì)應(yīng)的port時(shí),就能將請(qǐng)求映射到后端的pod中。
最終的結(jié)果就是,任何對(duì)service的請(qǐng)求都能被映射到正確的pod中,而client不需要關(guān)心kubernetes、service或pod的其他信息。
默認(rèn)情況下,請(qǐng)求會(huì)隨機(jī)選擇一個(gè)backend。可以將service.spec.sessionAffinity 設(shè)置為 "ClientIP" (the default is "None"),這樣可以根據(jù)client-ip來維持一個(gè)session關(guān)系來選擇pod。
在kubernetes中,service是基于三層(TCP/UDP over IP)的架構(gòu),目前還沒有提供專門作用于七層(http)的services。
Multi-Port Services在很多情況下,一個(gè)service需要對(duì)多個(gè)port做映射。下面舉個(gè)這樣的例子,注意,使用multi-port時(shí),必須為每個(gè)port設(shè)定name,如:
{ "kind": "Service", "apiVersion": "v1", "metadata": { "name": "my-service" }, "spec": { "selector": { "app": "MyApp" }, "ports": [ { "name": "http", "protocol": "TCP", "port": 80, "targetPort": 9376 }, { "name": "https", "protocol": "TCP", "port": 443, "targetPort": 9377 } ] } }Choosing your own IP address
用戶可以為service指定自己的cluster ip,通過字段spec.clusterIP來實(shí)現(xiàn)。用戶設(shè)定的ip必須是一個(gè)有效的ip,必須符合service_cluster_ip_range 范圍,如果ip不合符上述規(guī)定,apiserver將會(huì)返回422。
Why not use round-robin DNS?有一個(gè)問題會(huì)時(shí)不時(shí)的出現(xiàn),為什么不用一個(gè)DNS輪詢來替換vip?有如下幾個(gè)理由:
已經(jīng)擁有很長歷史的DNS庫不會(huì)太注意DNS TTL 并且會(huì)緩存name lookup的結(jié)果;
許多應(yīng)用只做一次name lookup并且將結(jié)果緩存;
即使app和dns庫做了很好的解決,client對(duì)dns做一遍又一遍的輪詢將會(huì)增加管理的復(fù)雜度;
我們做這些避免用戶做哪些作死的行為,但是,如果真有那么多用戶要求,我們會(huì)提供這樣的選擇。
Discovering services對(duì)于每個(gè)運(yùn)行的pod,kubelet將為其添加現(xiàn)有service的全局變量,支持Docker links compatible變量 以及 簡單的{SVCNAME}_SERVICE_HOST and {SVCNAME}_SERVICE_PORT變量。
比如,叫做”redis-master“的service,對(duì)外映射6379端口,已經(jīng)被分配一個(gè)ip,10.0.0.11,那么將會(huì)產(chǎn)生如下的全局變量:
REDIS_MASTER_SERVICE_HOST=10.0.0.11 REDIS_MASTER_SERVICE_PORT=6379 REDIS_MASTER_PORT=tcp://10.0.0.11:6379 REDIS_MASTER_PORT_6379_TCP=tcp://10.0.0.11:6379 REDIS_MASTER_PORT_6379_TCP_PROTO=tcp REDIS_MASTER_PORT_6379_TCP_PORT=6379 REDIS_MASTER_PORT_6379_TCP_ADDR=10.0.0.11
這意味著一個(gè)順序依賴——service要想被pod使用,必須比pod先建立,否則這些service環(huán)境變量不會(huì)構(gòu)建在pod中。DNS沒有這些限制。
DNS一個(gè)可選的擴(kuò)展(強(qiáng)烈建議)是DNS server。DNS server通過kubernetes api server來觀測(cè)是否有新service建立,并為其建立對(duì)應(yīng)的dns記錄。如果集群已經(jīng)enable DNS,那么pod可以自動(dòng)對(duì)service做name解析。
舉個(gè)栗子,有個(gè)叫做”my-service“的service,他對(duì)應(yīng)的kubernetes namespace為”my-ns“,那么會(huì)有他對(duì)應(yīng)的dns記錄,叫做”my-service.my-ns“。那么在my-ns的namespace中的pod都可以對(duì)my-service做name解析來輕松找到這個(gè)service。在其他namespace中的pod解析”my-service.my-ns“來找到他。解析出來的結(jié)果是這個(gè)service對(duì)應(yīng)的cluster ip。
Headless services有時(shí)候你不想做負(fù)載均衡 或者 在意只有一個(gè)cluster ip。這時(shí),你可以創(chuàng)建一個(gè)”headless“類型的service,將spec.clusterIP字段設(shè)置為”None“。對(duì)于這樣的service,不會(huì)為他們分配一個(gè)ip,也不會(huì)在pod中創(chuàng)建其對(duì)應(yīng)的全局變量。DNS則會(huì)為service 的name添加一系列的A記錄,直接指向后端映射的pod。此外,kube proxy也不會(huì)處理這類service
,沒有負(fù)載均衡也沒有請(qǐng)求映射。endpoint controller則會(huì)依然創(chuàng)建對(duì)應(yīng)的endpoint。
這個(gè)操作目的是為了用戶想減少對(duì)kubernetes系統(tǒng)的依賴,比如想自己實(shí)現(xiàn)自動(dòng)發(fā)現(xiàn)機(jī)制等等。Application可以通過api輕松的結(jié)合其他自動(dòng)發(fā)現(xiàn)系統(tǒng)。
External services對(duì)于你應(yīng)用的某些部分(比如frontend),你可能希望將service開放到公網(wǎng)ip,kubernetes提供兩種方式來實(shí)現(xiàn),NodePort and LoadBalancer。
每個(gè)service都有個(gè)type字段,值可以有以下幾種:
ClusterIP: 使用集群內(nèi)的私有ip —— 這是默認(rèn)值。
NodePort: 除了使用cluster ip外,也將service的port映射到每個(gè)node的一個(gè)指定內(nèi)部port上,映射的每個(gè)node的內(nèi)部port都一樣。
LoadBalancer: 使用一個(gè)ClusterIP & NodePort,但是會(huì)向cloud provider申請(qǐng)映射到service本身的負(fù)載均衡。
注意:NodePort支持TCP/UDP,LoadBalancer只支持TCP。
Type = NodePort如果將type字段設(shè)置為NodePort,kubernetes master將會(huì)為service的每個(gè)對(duì)外映射的port分配一個(gè)”本地port“,這個(gè)本地port作用在每個(gè)node上,且必須符合定義在配置文件中的port范圍(為--service-node-port-range)。這個(gè)被分配的”本地port“定義在service配置中的spec.ports[*].nodePort字段,如果為這個(gè)字段設(shè)定了一個(gè)值,系統(tǒng)將會(huì)使用這個(gè)值作為分配的本地port 或者 提示你port不符合規(guī)范。
這樣就方便了開發(fā)者使用自己的負(fù)載均衡方案。
Type = LoadBalancer如果在一個(gè)cloud provider中部署使用service,將type地段設(shè)置為LoadBalancer將會(huì)使service使用人家提供的負(fù)載均衡。這樣會(huì)異步的來創(chuàng)建service的負(fù)載均衡,在service配置的status.loadBalancer字段中,描述了所使用被提供負(fù)載均衡的詳細(xì)信息,如:
{ "kind": "Service", "apiVersion": "v1", "metadata": { "name": "my-service" }, "spec": { "selector": { "app": "MyApp" }, "ports": [ { "protocol": "TCP", "port": 80, "targetPort": 9376, "nodePort": 30061 } ], "clusterIP": "10.0.171.239", "type": "LoadBalancer" }, "status": { "loadBalancer": { "ingress": [ { "ip": "146.148.47.155" } ] } } }
這樣外部的負(fù)載均衡方案將會(huì)直接作用在后端的pod上。
Shortcomings通過iptables和用戶控件映射可以很好的為中小型規(guī)模服務(wù),但是并不適用于擁有數(shù)千個(gè)service的集群。詳情請(qǐng)看” the original design proposal for portals“。
使用kube-proxy不太可能看到訪問的源ip,這樣使得某些類型防火墻實(shí)效。
LoadBalancers 只支持TCP.
type字段被設(shè)計(jì)成嵌套的結(jié)構(gòu),每一層都被增加到了前一層。很多云方案提供商支持的并不是很好(如,gce沒有必要分配一個(gè)NodePort來使LoadBalancer正常工作,但是AWS需要),但是當(dāng)前的API需要。
Future work The gory details of virtual IPs以上的信息應(yīng)該足夠用戶來使用service。但是還是有許多東西值得大家來深入理解。
(懶得翻了,大家自己看吧,最后貼上最后一個(gè)圖)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/32419.html
摘要:本文詳細(xì)講解如何搭建高可用的集群,以下簡稱由三臺(tái)服務(wù)器組成集群命名為,,,用來代替集群搭建首先搭建集群為集群的核心組成部分,負(fù)責(zé)所有集群配置信息和服務(wù)信息的存儲(chǔ),所以必須要保證高可用,此處采用的靜態(tài)服務(wù)發(fā)現(xiàn),即在啟動(dòng)的時(shí)候,確定的。 本文詳細(xì)講解如何搭建高可用的Kubernetes集群,以下簡稱k8s 由三臺(tái)服務(wù)器(CentOS 7.0)組成master集群,命名為m1,m2,m3,i...
摘要:本文詳細(xì)講解如何搭建高可用的集群,以下簡稱由三臺(tái)服務(wù)器組成集群命名為,,,用來代替集群搭建首先搭建集群為集群的核心組成部分,負(fù)責(zé)所有集群配置信息和服務(wù)信息的存儲(chǔ),所以必須要保證高可用,此處采用的靜態(tài)服務(wù)發(fā)現(xiàn),即在啟動(dòng)的時(shí)候,確定的。 本文詳細(xì)講解如何搭建高可用的Kubernetes集群,以下簡稱k8s 由三臺(tái)服務(wù)器(CentOS 7.0)組成master集群,命名為m1,m2,m3,i...
摘要:本文詳細(xì)講解如何搭建高可用的集群,以下簡稱由三臺(tái)服務(wù)器組成集群命名為,,,用來代替集群搭建首先搭建集群為集群的核心組成部分,負(fù)責(zé)所有集群配置信息和服務(wù)信息的存儲(chǔ),所以必須要保證高可用,此處采用的靜態(tài)服務(wù)發(fā)現(xiàn),即在啟動(dòng)的時(shí)候,確定的。 本文詳細(xì)講解如何搭建高可用的Kubernetes集群,以下簡稱k8s 由三臺(tái)服務(wù)器(CentOS 7.0)組成master集群,命名為m1,m2,m3,i...
摘要:前言是一個(gè)開源和社區(qū)驅(qū)動(dòng)的監(jiān)控報(bào)警時(shí)序數(shù)據(jù)庫的項(xiàng)目。集群上部署的應(yīng)用監(jiān)控部署在集群上的應(yīng)用。通過和的接口采集。相應(yīng),配置文件官方也提供了一份,今天我們就解讀一下該配置文件。對(duì)于服務(wù)的終端節(jié)點(diǎn),也需要加注解,為則會(huì)將作為監(jiān)控目標(biāo)。 前言 Prometheus 是一個(gè)開源和社區(qū)驅(qū)動(dòng)的監(jiān)控&報(bào)警&時(shí)序數(shù)據(jù)庫的項(xiàng)目。來源于谷歌BorgMon項(xiàng)目。現(xiàn)在最常見的Kubernetes容器管理系統(tǒng)中,...
閱讀 828·2023-04-25 19:40
閱讀 3488·2023-04-25 17:41
閱讀 3003·2021-11-11 11:01
閱讀 2612·2019-08-30 15:55
閱讀 3227·2019-08-30 15:44
閱讀 1358·2019-08-29 14:07
閱讀 484·2019-08-29 11:23
閱讀 1326·2019-08-27 10:54