K8s Service

什么是service

pod不是永恒存在的怠肋,pod會(huì)隨時(shí)被創(chuàng)建,同時(shí)pod也會(huì)被隨時(shí)銷毀(運(yùn)行出錯(cuò)宣决,超過(guò)資源限制等原因)穿挨。pod不可能被復(fù)活,因此pod被銷毀和重建之后的IP地址是不同的胧后。
其他依賴該pod的服務(wù)不可能去維護(hù)這些pod的IP地址信息芋浮。這里我們引入的service,service保存了我們?nèi)绾卧L問(wèn)一組pod的方式壳快。這一組pod通過(guò)pod selector來(lái)確定纸巷。無(wú)論這些pod怎樣創(chuàng)建和銷毀镇草,他們的label不變。service可以動(dòng)態(tài)維護(hù)這些pod的真實(shí)IP(通過(guò)endpoint對(duì)象)瘤旨。所以說(shuō)梯啤,service解耦了pod和依賴這些pod的應(yīng)用。

定義一個(gè)service

創(chuàng)建service的描述文件:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376

這里我們定義了一個(gè)service的描述文件存哲。service的名字為my-service因宇。service指向的pod需要具有app: MyApp標(biāo)簽∷钔担可以使用80端口訪問(wèn)每個(gè)pod的9376端口察滑。這個(gè)service擁有一個(gè)cluster IP。這個(gè)IP只能在kubernetes集群內(nèi)部訪問(wèn)肩袍。

具有selector的service在創(chuàng)建的時(shí)候會(huì)自動(dòng)創(chuàng)建一個(gè)同名的endpoint杭棵。endpoint維護(hù)了具有這些標(biāo)簽的一組pod的真正的IP。如果這些pod的IP發(fā)生變化氛赐,endpoint中的IP也會(huì)隨著變化魂爪。

沒(méi)有pod selector的service

如下情況我們需要使用沒(méi)有pod selector的service:

  • 使用集群外部的數(shù)據(jù)庫(kù)
  • 要?jiǎng)?chuàng)建的service指向位于另一個(gè)namespace,或者是另一個(gè)kubernetes集群的service

編寫(xiě)描述文件:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376

只有這樣是不夠的艰管,service需要有一個(gè)對(duì)應(yīng)的endpoint對(duì)象滓侍。創(chuàng)建沒(méi)有selector的service并不會(huì)隨之創(chuàng)建一個(gè)endpoint。這時(shí)候我們需要手工創(chuàng)建endpoint牲芋。endpoint的描述文件如下:

apiVersion: v1
kind: Endpoints
metadata:
  name: my-service
subsets:
  - addresses:
      - ip: 192.0.2.42
    ports:
      - port: 9376

service proxy

service使用kube-proxy實(shí)現(xiàn)

不使用輪詢DNS方式的原因

  • 不少DNS的實(shí)現(xiàn)不支持TTL(Time To Live)撩笆。無(wú)法在pod IP發(fā)生變化的時(shí)候及時(shí)改變緩存。
  • 一部分應(yīng)用在DNS查詢之后便永久保存缸浦,再也不會(huì)更新夕冲。
  • 即便是支持DNS再次解析,我們需要降低DNS的TTL裂逐。越低的TTL會(huì)導(dǎo)致DNS解析服務(wù)的頻繁運(yùn)行歹鱼,增加系統(tǒng)的負(fù)載。

user space proxy 模式

kube-proxy 負(fù)責(zé)監(jiān)視service和endpoint的創(chuàng)建和刪除卜高。對(duì)于每個(gè)service弥姻,在本地節(jié)點(diǎn)上隨機(jī)開(kāi)啟一個(gè)端口(代理端口)。任何連接到該端口的連接會(huì)被代理到service后端一組pod中的一個(gè)掺涛。kube-proxy使用SessionAffinity配置項(xiàng)來(lái)決定使用哪一個(gè)后端pod庭敦。

user space模式使用iptables規(guī)則,把目標(biāo)為service的cluster IP和端口的請(qǐng)求發(fā)送到代理端口薪缆。

iptables proxy 模式

iptables使用規(guī)則配置秧廉,將訪問(wèn)service的cluster IP和port的連接重定向到某一個(gè)后端pod。默認(rèn)來(lái)說(shuō),kube-proxy隨機(jī)選擇后端pod提供服務(wù)定血。

iptables模式系統(tǒng)開(kāi)銷較小赔癌。

如果連接到的第一個(gè)被選定的pod沒(méi)有響應(yīng),此連接會(huì)失敗澜沟。這個(gè)和userspace模式不同灾票。userspace模式中,如果連接到第一個(gè)pod失敗茫虽,系統(tǒng)會(huì)自動(dòng)重試連接另一個(gè)后端pod刊苍。

可以使用readness probe來(lái)確保pod是否正常工作。如果某個(gè)podreadness probe 失敗濒析,這個(gè)pod會(huì)從endpoint中移除正什,網(wǎng)絡(luò)請(qǐng)求不會(huì)再轉(zhuǎn)發(fā)到這個(gè)pod中,直到readness probe恢復(fù)到success狀態(tài)号杏。

IPVS proxy 模式

ipvs 模式kube-proxy使用netlink接口創(chuàng)建IPVS規(guī)則婴氮。IPVS基于鉤子函數(shù),使用內(nèi)核空間的hash表作為底層數(shù)據(jù)結(jié)構(gòu)盾致。因此IPVS相比iptables具有更低的延遲主经,吞吐量更高。同時(shí)同步代理規(guī)則的時(shí)候也更快庭惜。

IPVS重定向網(wǎng)絡(luò)通信具有如下策略:

  • rr: round-robin 輪詢
  • lc: least connection (smallest number of open connections) 優(yōu)先連接數(shù)最少
  • dh: destination hashing 目標(biāo)hash
  • sh: source hashing 源hash
  • sed: shortest expected delay 延遲最小
  • nq: never queue 不排隊(duì)

如果需要相同客戶端的請(qǐng)求被重定向到相同的pod罩驻,需要配置service.spec.sessionAffinityClientIP(默認(rèn)為None)。我們還可以設(shè)置pod和client的最大粘性時(shí)間service.spec.sessionAffinityConfig.clientIP.timeoutSeconds护赊。默認(rèn)為10800惠遏,即3小時(shí)。如果3小時(shí)內(nèi)client沒(méi)有訪問(wèn)pod骏啰,那么該client下次訪問(wèn)service的時(shí)候?qū)⒅匦轮付ㄐ碌膒od节吮,原先的session會(huì)失效。

多端口服務(wù)

service可以暴露多個(gè)port判耕。如果使用多個(gè)port透绩,必須為每一個(gè)port設(shè)置name。描述文件如下所示:

apiVersion: v1
kind: Service
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

顯式指定service的IP

可以設(shè)定spec.clusterIP配置項(xiàng)祈秕。但是IP必須位于API server的service-cluster-ip-range CIDR范圍中。

service發(fā)現(xiàn)

環(huán)境變量方式

Kubernetes自動(dòng)為每一個(gè)運(yùn)行的pod中加入各個(gè)service環(huán)境變量雏胃。這些service的環(huán)境變量的格式為

  • {SVCNAME}_SERVICE_HOST
  • {SVCNAME}_SERVICE_PORT

以redis-master服務(wù)為例请毛,對(duì)應(yīng)的環(huá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

注意:如果pod需要使用環(huán)境變量的方式訪問(wèn)service,一定要在創(chuàng)建pod之前創(chuàng)建service瞭亮。否則pod中將沒(méi)有這個(gè)service的環(huán)境變量方仿。如果使用DNS方式的話不需要擔(dān)心這個(gè)創(chuàng)建順序問(wèn)題。

DNS方式

集群的DNS服務(wù),例如CoreDNS會(huì)監(jiān)聽(tīng)service仙蚜,創(chuàng)建service對(duì)應(yīng)的DNS入口此洲。

如果在命名空間my-ns定義了一個(gè)服務(wù)my-service,自動(dòng)創(chuàng)建的DNS入口為my-service.my-ns委粉。集群內(nèi)任何pod可以通過(guò)此DNS訪問(wèn)這個(gè)服務(wù)呜师。如果是和該服務(wù)位于同一個(gè)命名空間的pod,可以省略DNS中的命名空間部分贾节,使用my-service這個(gè)DNS入口訪問(wèn)my-service服務(wù)汁汗。

DNS支持命名端口的方式。如果一個(gè)端口命名為http栗涂,使用的是TCP協(xié)議知牌,可以通過(guò)_http._tcp.my-service.my-ns這條DNS解析到它的IP和端口號(hào)。

Headless Service

特點(diǎn):

  1. 禁用掉了service的負(fù)載均衡功能斤程。
  2. 沒(méi)有指定service的clusterIP角寸。
  3. service不使用kube-proxy代理。

適用場(chǎng)景:

  1. 需要不經(jīng)過(guò)代理直接訪問(wèn)pod忿墅。
  2. 使用服務(wù)發(fā)現(xiàn)功能扁藕,例如部署zookeeper等。

配置方式:
設(shè)置spec.clusterIPNone

DNS自動(dòng)配置的方式和是否配置了pod selector有關(guān)球匕。

  • 配置了pod selector:endpoints會(huì)被創(chuàng)建纹磺,DNS直接指向后臺(tái)pod的IP
  • 沒(méi)有配置pod selector:endpoints不會(huì)被創(chuàng)建。DNS服務(wù)會(huì)查找: 1. CNAME記錄(ExternalName-type Services)2. 和service同名的endpoints

公開(kāi)service(允許service在集群外訪問(wèn))

通過(guò)設(shè)置服務(wù)類型(ServiceType)來(lái)實(shí)現(xiàn)亮曹。
service type有如下類型:

  • clusterIP:一個(gè)只有在集群內(nèi)部可訪問(wèn)的虛擬的IP橄杨。這個(gè)是Service Type的默認(rèn)值。
  • NodePort:使用每個(gè)節(jié)點(diǎn)的一個(gè)靜態(tài)端口來(lái)訪問(wèn)service照卦。集群外可使用<NodeIP>:<NodePort>形式訪問(wèn)式矫。
  • LoadBalancer:負(fù)載均衡器,使用云提供商的負(fù)載均衡器訪問(wèn)服務(wù)役耕。
  • ExternalName:映射為一個(gè)自定義DNS名稱采转,適用于訪問(wèn)外部服務(wù)。

除此之外還可以使用Ingress方式瞬痘,但是Ingress不是ServiceType故慈。

NodePort

NodePort范圍從--service-node-port-rangeflag中隨機(jī)選擇(默認(rèn)為30000-32767)。分配的端口號(hào)在.spec.ports[*].nodePort字段中框全。

可以使用kube-proxy的--nodeport-addresses配置指定nodePort IP的范圍察绷。

可以通過(guò)指定nodePort字段的內(nèi)容,來(lái)使得NodePort使用一個(gè)固定的IP津辩。

NodePort的使用例子:

apiVersion: v1
kind: Service
metadata:
    name: kubia-nodeport
spec:
    type: NodePort
    ports:
        - port: 80
          targetPort: 8080
          nodePort: 30123
    selector:
        app: kubia

LoadBalancer

自己部署的集群中無(wú)LoadBalancer拆撼,此部分省略容劳。

ExternalName

映射service到一個(gè)DNS名稱。

apiVersion: v1
kind: Service
metadata:
  name: my-service
  namespace: prod
spec:
  type: ExternalName
  externalName: my.database.example.com

External IPs

使用外部IP訪問(wèn)服務(wù)闸度。要求可以通過(guò)外部IP訪問(wèn)到集群節(jié)點(diǎn)竭贩。

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 9376
  externalIPs:
    - 80.11.12.10

Service 使用Session Affinity

session affinity,同一個(gè)client發(fā)出的請(qǐng)求會(huì)發(fā)送給同一個(gè)pod處理莺禁。配置方法如下:

apiVersion: v1
kind: Service
spec:
    sessionAffinity: ClientIP
    ...

使用命名端口

可以在Pod中為端口命令留量,在service中使用。

步驟如下所示:

  1. 在pod中給端口命名
kind: Pod
spec:
    containers:
    - name: kubia
      ports:
      - name: http
        containerPort: 8080
      - name: https
        containerPort: 8443
  1. 創(chuàng)建service時(shí)使用命名端口(targetPort中使用)
apiVersion: v1
kind: Service
spec:
    ports:
    - name: http
      port: 80
      targetPort: http
    - name: https
      port: 443
      targetPort: https

Service關(guān)聯(lián)k8s集群外部的服務(wù)

把集群外部的某一服務(wù)的入口做成k8s的endpoint睁宰。創(chuàng)建service的時(shí)候如果不指定label selector肪获,endpoints就不會(huì)自動(dòng)創(chuàng)建。

下面舉一個(gè)例子柒傻。我們需要在k8s集群中訪問(wèn)集群外部11.11.11.11和22.22.22.22的80端口這個(gè)服務(wù)孝赫。

這里我們需要手工創(chuàng)建service和endpoint:

apiVersion: v1
kind: Service
metadata:
    name: external-service
spec:
    ports:
    - port: 80
apiVersion: v1
kind: Endpoints
metadata:
    name: external-service
subsets:
    - addresses:
        - ip: 11.11.11.11
        - ip: 22.22.22.22
    ports:
        - port: 80

完成之后,集群內(nèi)部可以通過(guò)訪問(wèn)external-service來(lái)實(shí)現(xiàn)訪問(wèn)集群外部11.11.11.1122.22.22.22红符。

減少網(wǎng)絡(luò)連接的hop數(shù)量

可以通過(guò)配置service青柄,只把連接重定向到接收這個(gè)連接的node上運(yùn)行的pod。

方法如下:

spec:
    externalTrafficPolicy: Local
    ...

缺點(diǎn):如果這個(gè)node上沒(méi)有運(yùn)行該service對(duì)應(yīng)的pod预侯,連接會(huì)掛起致开。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市萎馅,隨后出現(xiàn)的幾起案子双戳,更是在濱河造成了極大的恐慌,老刑警劉巖糜芳,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件飒货,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡峭竣,警方通過(guò)查閱死者的電腦和手機(jī)塘辅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)皆撩,“玉大人扣墩,你說(shuō)我怎么就攤上這事】竿蹋” “怎么了呻惕?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)滥比。 經(jīng)常有香客問(wèn)我亚脆,道長(zhǎng),這世上最難降的妖魔是什么守呜? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任型酥,我火速辦了婚禮,結(jié)果婚禮上查乒,老公的妹妹穿的比我還像新娘弥喉。我一直安慰自己,他們只是感情好玛迄,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布由境。 她就那樣靜靜地躺著,像睡著了一般蓖议。 火紅的嫁衣襯著肌膚如雪虏杰。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,679評(píng)論 1 305
  • 那天勒虾,我揣著相機(jī)與錄音纺阔,去河邊找鬼。 笑死修然,一個(gè)胖子當(dāng)著我的面吹牛笛钝,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播愕宋,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼玻靡,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了中贝?” 一聲冷哼從身側(cè)響起囤捻,我...
    開(kāi)封第一講書(shū)人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎邻寿,沒(méi)想到半個(gè)月后蝎土,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡老厌,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年瘟则,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片枝秤。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡醋拧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出淀弹,到底是詐尸還是另有隱情丹壕,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布薇溃,位于F島的核電站菌赖,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏沐序。R本人自食惡果不足惜琉用,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一堕绩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧邑时,春花似錦奴紧、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至浅浮,卻和暖如春沫浆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背滚秩。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工专执, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人郁油。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓他炊,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親已艰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子痊末,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Service Service是一種抽象的對(duì)象,它定義了一組Pod的邏輯集合和一個(gè)用于訪問(wèn)它們的策略哩掺,一個(gè)Seri...
    祁恩達(dá)閱讀 11,034評(píng)論 0 0
  • Service 是Kubernetes 最核心的概念嚼吞、通過(guò)創(chuàng)建 Service 可以為一組具有相同功能的容器應(yīng)用提...
    搬板凳嗑瓜子閱讀 2,478評(píng)論 0 1
  • 背景 最開(kāi)始聽(tīng)到同事 k8s 分享時(shí)比較困惑我的一個(gè)問(wèn)題是 k8s 怎么實(shí)現(xiàn)一個(gè)私有 ip(虛擬 ip盒件,以下簡(jiǎn)稱 ...
    小虛大魔王閱讀 9,864評(píng)論 4 12
  • k8s Pod 創(chuàng)建 文件名:deploy-echoserver.yml (這里以 Deployment 的方式來(lái)...
    taj3991閱讀 2,830評(píng)論 0 4
  • 一般來(lái)說(shuō)任何一個(gè)民族都會(huì)思考 誰(shuí)創(chuàng)造了世界 和我從哪里來(lái)的問(wèn)題 自然也就隨之產(chǎn)生了 創(chuàng)世神話 來(lái)給予答案 但愛(ài)爾蘭...
    羊咩的內(nèi)心擁有一頭狼閱讀 235評(píng)論 0 1