【Kubernetes學(xué)習(xí)筆記】-服務(wù)訪問之 IP & Port & Endpoint 辨析

[TOC]

當(dāng)新手剛學(xué)習(xí)k8s時(shí)候灾馒,會(huì)被各種的IP 和port 搞暈茎用,其實(shí)它們都與k8s service的訪問有密切關(guān)系,梳理它們之間的差異可以更好了解k8s的服務(wù)訪問機(jī)制睬罗。

IP&Port

不同類型的IP

  • Node IP:Node節(jié)點(diǎn)的IP地址轨功。 節(jié)點(diǎn)物理網(wǎng)卡ip
  • Pod IP:Pod的IP地址。 Docker Engine根據(jù)docker0網(wǎng)橋的IP地址段進(jìn)行分配的容达,通常是一個(gè)虛擬的二層網(wǎng)絡(luò)
  • Cluster IP:Service的IP地址古涧。 屬于Kubernetes集群內(nèi)部的地址,無法在集群外部直接使用這個(gè)地址

Pod IP

Pod IP 地址是實(shí)際存在于某個(gè)網(wǎng)卡(可以是虛擬設(shè)備)上的董饰,但Service Cluster IP就不一樣了蒿褂,沒有網(wǎng)絡(luò)設(shè)備為這個(gè)地址負(fù)責(zé)圆米。它是由kube-proxy使用Iptables規(guī)則重新定向到其本地端口卒暂,再均衡到后端Pod的。

例如娄帖,當(dāng)Service被創(chuàng)建時(shí)也祠,Kubernetes給它分配一個(gè)地址10.0.0.1。這個(gè)地址從我們啟動(dòng)API的service-cluster-ip-range參數(shù)(舊版本為portal_net參數(shù))指定的地址池中分配近速,比如--service-cluster-ip-range=10.0.0.0/16诈嘿。假設(shè)這個(gè)Service的端口是1234堪旧。集群內(nèi)的所有kube-proxy都會(huì)注意到這個(gè)Service。當(dāng)proxy發(fā)現(xiàn)一個(gè)新的service后奖亚,它會(huì)在本地節(jié)點(diǎn)打開一個(gè)任意端口淳梦,建相應(yīng)的iptables規(guī)則,重定向服務(wù)的IP和port到這個(gè)新建的端口昔字,開始接受到達(dá)這個(gè)服務(wù)的連接爆袍。

當(dāng)一個(gè)客戶端訪問這個(gè)service時(shí),這些iptable規(guī)則就開始起作用作郭,客戶端的流量被重定向到kube-proxy為這個(gè)service打開的端口上陨囊,kube-proxy隨機(jī)選擇一個(gè)后端pod來服務(wù)客戶。

Cluster IP

Service的IP地址夹攒,此為虛擬IP地址蜘醋。外部網(wǎng)絡(luò)無法ping通,只有kubernetes集群內(nèi)部訪問使用咏尝。通過命令 kubectl -n 命名空間 get Service 即可查詢ClusterIP

Cluster IP是一個(gè)虛擬的IP压语,但更像是一個(gè)偽造的IP網(wǎng)絡(luò),原因有以下幾點(diǎn)

  • Cluster IP僅僅作用于Kubernetes Service這個(gè)對(duì)象编检,并由Kubernetes管理和分配P地址

  • Cluster IP無法被ping无蜂,他沒有一個(gè)“實(shí)體網(wǎng)絡(luò)對(duì)象”來響應(yīng)

  • Cluster IP只能結(jié)合Service Port組成一個(gè)具體的通信端口Endpoint,單獨(dú)的Cluster IP不具備通信的基礎(chǔ)蒙谓,并且他們屬于Kubernetes集群這樣一個(gè)封閉的空間斥季。

  • 在不同Service下的pod節(jié)點(diǎn)在集群間相互訪問可以通過Cluster IP

    不同服務(wù)的Pod訪問

為了實(shí)現(xiàn)圖上的功能主要需要以下幾個(gè)組件的協(xié)同工作:

  • apiserver:在創(chuàng)建service時(shí),apiserver接收到請(qǐng)求以后將數(shù)據(jù)存儲(chǔ)到etcd中累驮。
  • kube-proxy:k8s的每個(gè)節(jié)點(diǎn)中都有該進(jìn)程酣倾,負(fù)責(zé)實(shí)現(xiàn)service功能,這個(gè)進(jìn)程負(fù)責(zé)感知service谤专,pod的變化躁锡,并將變化的信息寫入本地的iptables中。
  • iptables:使用NAT等技術(shù)將virtualIP的流量轉(zhuǎn)至endpoint中

根據(jù)是否生成ClusterIP又可分為普通Service和Headless Service兩類:

  1. 普通Service:通過為Kubernetes的Service分配一個(gè)集群內(nèi)部可訪問的固定虛擬IP(Cluster IP)置侍,實(shí)現(xiàn)集群內(nèi)的訪問映之。為最常見的方式。

  2. Headless Service:該服務(wù)不會(huì)分配Cluster IP蜡坊,也不通過kube-proxy做反向代理和負(fù)載均衡杠输。而是通過DNS提供穩(wěn)定的網(wǎng)絡(luò)ID來訪問,DNS會(huì)將headless service的后端直接解析為Pod IP列表秕衙。主要供StatefulSet使用蠢甲。

不同類型的Port

apiVersion: v1
kind: Service
metadata:
 name: nginx-service
spec:
 type: NodePort         // 有配置NodePort,外部流量可訪問k8s中的服務(wù)
 ports:
 - port: 30080          // 服務(wù)訪問端口据忘,集群內(nèi)部訪問的端口
   targetPort: 80       // pod控制器中定義的端口(應(yīng)用訪問的端口)
   nodePort: 30001      // NodePort鹦牛,外部客戶端訪問的端口
 selector:
  name: nginx-pod

port

  • port是k8s集群內(nèi)部訪問service的端口(service暴露在Cluster IP上的端口)搞糕,即通過clusterIP: port可以訪問到某個(gè)service

nodePort

  • nodePort是外部訪問k8s集群中service的端口,通過nodeIP: nodePort可以從外部訪問到某個(gè)service曼追。

該端口號(hào)的范圍是 kube-apiserver 的啟動(dòng)參數(shù) –service-node-port-range指定的窍仰,在當(dāng)前測試環(huán)境中其值是 30000-50000伦忠。表示只允許分配30000-50000之間的端口豺鼻。

比如外部用戶要訪問k8s集群中的一個(gè)Web應(yīng)用茶凳,那么我們可以配置對(duì)應(yīng)service的type=NodePort符隙,nodePort=30001裆装。其他用戶就可以通過瀏覽器http://node:30001訪問到該web服務(wù)崇棠。而數(shù)據(jù)庫等服務(wù)可能不需要被外界訪問涛贯,只需被內(nèi)部服務(wù)訪問即可厕氨,那么我們就不必設(shè)置service的NodePort

TargetPort

  • targetPort 是pod的端口坝辫,從port和nodePort來的流量經(jīng)過kube-proxy流入到后端pod的targetPort上篷就,最后進(jìn)入容器。

containerPort

  • containerPort是pod內(nèi)部容器的端口近忙,targetPort映射到containerPort竭业。

hostPort

這是一種直接定義Pod網(wǎng)絡(luò)的方式。hostPort是直接將容器的端口與所調(diào)度的節(jié)點(diǎn)上的端口路由及舍,這樣用戶就可以通過宿主機(jī)的IP加上來訪問Pod了未辆,如

apiVersion: v1
kind: Pod
metadata:
  name: influxdb
spec:
  containers:
    - name: influxdb
      image: influxdb
      ports:
        - containerPort: 8086 # 此處定義暴露的端口
          hostPort: 8086

這樣做有個(gè)缺點(diǎn),因?yàn)镻od重新調(diào)度的時(shí)候該P(yáng)od被調(diào)度到的宿主機(jī)可能會(huì)變動(dòng)锯玛,這樣就變化了咐柜,用戶必須自己維護(hù)一個(gè)Pod與所在宿主機(jī)的對(duì)應(yīng)關(guān)系。
使用了 hostPort 的容器只能調(diào)度到端口不沖突的 Node 上攘残,除非有必要(比如運(yùn)行一些系統(tǒng)級(jí)的 daemon 服務(wù))拙友,不建議使用端口映射功能。如果需要對(duì)外暴露服務(wù)歼郭,建議使用 NodePort Service遗契。

總的來說,port和nodePort都是service的端口病曾,前者暴露給集群內(nèi)客戶訪問服務(wù)牍蜂,后者暴露給集群外客戶訪問服務(wù)。從這兩個(gè)端口到來的數(shù)據(jù)都需要經(jīng)過反向代理kube-proxy流入后端 pod的targetPod泰涂,從而到達(dá)pod上的容器內(nèi)鲫竞。

Endpoint

創(chuàng)建Service的同時(shí),會(huì)自動(dòng)創(chuàng)建跟Service同名的Endpoints负敏。

Endpoint 是k8s集群中一個(gè)資源對(duì)象贡茅,存儲(chǔ)在etcd里面,用來記錄一個(gè)service對(duì)應(yīng)的所有pod的訪問地址其做。service通過selector和pod建立關(guān)聯(lián)顶考。

Endpoint = Pod IP + Container Port

service配置selector endpoint controller 才會(huì)自動(dòng)創(chuàng)建對(duì)應(yīng)的endpoint 對(duì)象,否則是不會(huì)生產(chǎn)endpoint 對(duì)象

一個(gè)service由一組后端的pod組成妖泄,這些后端的pod通過service endpoint暴露出來驹沿,如果有一個(gè)新的pod創(chuàng)建創(chuàng)建出來,且pod的標(biāo)簽名稱(label:pod)跟service里面的標(biāo)簽(label selector 的label)一致會(huì)自動(dòng)加入到service的endpoints 里面蹈胡,如果pod對(duì)象終止后渊季,pod 會(huì)自動(dòng)從edponts 中移除。在集群中任意節(jié)點(diǎn) 可以使用curl請(qǐng)求service <CLUSTER-IP>:<PORT>

Endpoint Controller

Endpoint Controller是k8s集群控制器的其中一個(gè)組件罚渐,其功能如下:

  • 負(fù)責(zé)生成和維護(hù)所有endpoint對(duì)象的控制器
  • 負(fù)責(zé)監(jiān)聽service和對(duì)應(yīng)pod的變化
  • 監(jiān)聽到service被刪除却汉,則刪除和該service同名的endpoint對(duì)象
  • 監(jiān)聽到新的service被創(chuàng)建,則根據(jù)新建service信息獲取相關(guān)pod列表荷并,然后創(chuàng)建對(duì)應(yīng)endpoint對(duì)象
  • 監(jiān)聽到service被更新合砂,則根據(jù)更新后的service信息獲取相關(guān)pod列表,然后更新對(duì)應(yīng)endpoint對(duì)象
  • 監(jiān)聽到pod事件源织,則更新對(duì)應(yīng)的service的endpoint對(duì)象翩伪,將podIp記錄到endpoint中

定義 Endpoint

對(duì)于Service,我們還可以定義Endpoint谈息,Endpoint 把Service和Pod動(dòng)態(tài)地連接起來缘屹,Endpoint 的名稱必須和服務(wù)的名稱相匹配。

創(chuàng)建mysql-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: mysql-production
spec:
  ports:
    - port: 3306

創(chuàng)建mysql-endpoints.yaml

kind: Endpoints
apiVersion: v1
metadata:
  name: mysql-production
  namespace: default
subsets:
  - addresses:
      - ip: 192.168.1.25
    ports:
      - port: 3306
[root@k8s-master endpoint]# kubectl describe svc mysql-production
Name:           mysql-production
Namespace:      default
Labels:         <none>
Annotations:        <none>
Selector:       <none>
Type:           ClusterIP
IP:         10.254.218.165
Port:           <unset> 3306/TCP
Endpoints:      192.168.1.25:3306
Session Affinity:   None
Events:         <none>

使用Endpoint引用外部服務(wù)

service 不僅可以代理pod, 還可以代理任意其它的后端(運(yùn)行在k8s集群外部的服務(wù)侠仇,比如mysql mongodb)轻姿。如果需要從k8s里面鏈接外部服務(wù)(mysql),可定義同名的service和endpoint

在實(shí)際生成環(huán)境中逻炊,像mysql mongodb這種IO密集型應(yīng)用踢代,性能問題會(huì)顯得非常突出,所以在實(shí)際應(yīng)用中嗅骄,一般不會(huì)把這種有狀態(tài)的應(yīng)用(mysql 等)放入k8s里面胳挎,而是使用單獨(dú)的服務(wù)來部署,而像web這種無狀態(tài)的應(yīng)用更適合放在k8s里面 里面k8s的自動(dòng)伸縮溺森,和負(fù)載均衡慕爬,故障自動(dòng)恢復(fù) 等強(qiáng)大功能

創(chuàng)建service (mongodb-service-exten)

kind: Service
apiVersion: v1
metadata:
  name: mongodb
  namespace: name
spec:
  ports:
  - port: 30017
    name: mongodb
    targetPort: 30017

創(chuàng)建 endpoint(mongodb-endpoint)

kind: Endpoints
apiVersion: v1
metadata:
  name: mongodb
  namespace: tms-test
subsets:
- addresses:
  - ip: xxx.xxx.xx.xxx
  ports:
   - port: 30017
     name: mongod

可以看到service跟endpoint成功掛載一起了,表面外面服務(wù)成功掛載到k8s里面了屏积,在應(yīng)用中配置鏈接的地方使用mongodb://mongodb:30017 鏈接數(shù)據(jù)

創(chuàng)建ExternalName類型的服務(wù)

除了手動(dòng)配置服務(wù)的endpoint來代替公開外部服務(wù)方法医窿,還可以通過完全限定域名(FQDN)訪問外部服務(wù)——?jiǎng)?chuàng)建ExternalName類型的服務(wù)。

20201020135304113_1274858680

ExternalName類型的服務(wù)創(chuàng)建后炊林,pod可以通過external-service.default.svc.cluster.local域名連接到外部服務(wù)姥卢,或者通過externale-service。當(dāng)需要指向其他外部服務(wù)時(shí),只需要修改spec.externalName的值即可独榴。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末僧叉,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子棺榔,更是在濱河造成了極大的恐慌瓶堕,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件症歇,死亡現(xiàn)場離奇詭異郎笆,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)忘晤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門宛蚓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人设塔,你說我怎么就攤上這事凄吏。” “怎么了壹置?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵竞思,是天一觀的道長。 經(jīng)常有香客問我钞护,道長盖喷,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任难咕,我火速辦了婚禮课梳,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘余佃。我一直安慰自己暮刃,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布爆土。 她就那樣靜靜地躺著椭懊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪步势。 梳的紋絲不亂的頭發(fā)上氧猬,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音坏瘩,去河邊找鬼盅抚。 笑死,一個(gè)胖子當(dāng)著我的面吹牛倔矾,可吹牛的內(nèi)容都是我干的妄均。 我是一名探鬼主播柱锹,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼丰包!你這毒婦竟也來了禁熏?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤烫沙,失蹤者是張志新(化名)和其女友劉穎匹层,沒想到半個(gè)月后隙笆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體锌蓄,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年撑柔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了瘸爽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡铅忿,死狀恐怖剪决,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情檀训,我是刑警寧澤柑潦,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站峻凫,受9級(jí)特大地震影響渗鬼,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜荧琼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一譬胎、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧命锄,春花似錦堰乔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至驶冒,卻和暖如春苟翻,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背只怎。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國打工袜瞬, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人身堡。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓邓尤,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子汞扎,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

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