理解Kubernetes的NodePort、LoadBalancer和Ingress
這三個東西都可以實(shí)現(xiàn)將集群內(nèi)的服務(wù)暴露到集群外,那么它們到底有什么不同,要如何正確地使用這些組件,希望通過這篇文章,可以給大家一些啟示。首先明確一點(diǎn),NodePort和LoadBalancer指Kubernetes Service組件的兩種類型。
在正式開始之前,有必要對Service做簡單介紹。Service是一組Pod的抽象,雖然在集群中Pod可以通過IP直達(dá),但是Pod不穩(wěn)定,它可能會經(jīng)常死掉,這時集群會重新啟動一個Pod,這是一個全新的Pod,它的IP地址會發(fā)生變化,這樣不利于客戶端訪問。為了解決這個問題,Kubernetes引入了Service組件,從Pod創(chuàng)建之初到人為刪除這段時間,為其創(chuàng)建的Service訪問方式都是穩(wěn)定的,即它的訪問IP不變,再配合集群內(nèi)置的DNS服務(wù),客戶端可以利用不變的Service名稱或Service IP訪問到目標(biāo)Pods,而且Service還實(shí)現(xiàn)了簡單的負(fù)載均衡功能。
到這里,還有一個很重要的問題沒有解決,在Kubernetes集群外如何訪問集群內(nèi)的服務(wù),這就引出了標(biāo)題中列舉的三個對象,下面逐一介紹。
NodePort
Nodeport是Service的三種類型之一(ExternalName不常用故除外),其他兩種是ClusterIP和LoadBalancer。當(dāng)Service工作在NodePort類型時,默認(rèn)每個Node會在全部網(wǎng)絡(luò)接口開啟一個端口來轉(zhuǎn)發(fā)對集群內(nèi)服務(wù)的請求。當(dāng)請求到來時,Node會轉(zhuǎn)發(fā)請求到集群中的服務(wù)。這樣就帶來一個問題,請求的目標(biāo)Node可能會Down掉或其他別的原因?qū)е戮W(wǎng)絡(luò)不能訪問,NodePort還有一個問題就是對外暴露的端口有限制,默認(rèn)端口范圍是30,000-32,767。這就限制了可以對外暴露服務(wù)的個數(shù),使用這些不易記錄的端口訪問服務(wù)也是讓人頭疼的問題,這就引入了下一個Service類型:LoadBalancer。
LoadBalancer
大多數(shù)公有云平臺都支持創(chuàng)建這種類型的服務(wù),每個服務(wù)可以支持多種協(xié)議和多個端口,使用單個IP來訪問。因?yàn)樾枰诩和庠L問內(nèi)部服務(wù),所以這個IP地址是公有的,這會產(chǎn)生額外的費(fèi)用。如果暴露的服務(wù)很多,使用時需要慎重。在私有云環(huán)境中,不能創(chuàng)建此類的服務(wù),可以創(chuàng)建NodePort類型的服務(wù)然后使用HAproxy來充當(dāng)Load Balancer,這樣和公有云平臺的LoadBalancer差別不大。Service的三種類型:ClusterIP、NodePort、LoadBalancer,后一種是前一種的增強(qiáng),NodePort類型Service會創(chuàng)建ClusterIP類型Service,LoadBalancer類型Service會創(chuàng)建NodePort和ClusterIP類型Service。Service組件依賴操作系統(tǒng)中的iptables或ipvs,這是Service的靈魂。有一點(diǎn)需要注意,當(dāng)使用NodePort類型的服務(wù)時,請求會直接轉(zhuǎn)發(fā)給實(shí)際的Pod而不用轉(zhuǎn)發(fā)給Service的Cluster IP(kube-proxy工作在iptables模式),具體實(shí)現(xiàn)方法可以在搜索引擎上搜“NodePort類型Service的工作原理”。
Ingress
前面介紹的內(nèi)容都圍繞Service,主要解決網(wǎng)絡(luò)層的問題,Ingress的出現(xiàn)主要是解決應(yīng)用層的問題。Ingress實(shí)際上充當(dāng)一個反向代理的角色,和Nginx的功能很類似。Kubernetes中廣泛使用的Nginx Ingress其本質(zhì)就是一個Nginx服務(wù)。Ingress依賴LoadBalancer類型的Service,因?yàn)樗约簺]有暴露集群內(nèi)服務(wù)到外部的能力。這里以Nginx Ingress為例,介紹它的工作原理,其他類型的Ingress可以參考其官方文檔介紹。
Nginx Ingress主要包含兩個部分:Ingress Controller和Nginx,Controller通過Watch的方式訪問API服務(wù),從中采集它感興趣的資源更新,例如Ingress資源,然后操作Nginx,修改配置文件nginx.conf,更新證書、重啟Nginx等。它就像是一個Nginx的管理者,工程師發(fā)送指令到集群,Controller從API服務(wù)器接收到工程師發(fā)送的指令,然后操作Nginx。大體工作流程就是這樣。
上圖中有一個“Public Endpoint”組件,它可以通過LoadBalancer類型的Service來實(shí)現(xiàn),下面yaml片段來自阿里云上真實(shí)的nginx-ingress服務(wù)(IP地址和端口做了脫敏操作):
......
spec:
clusterIP: 172.14.13.67
externalTrafficPolicy: Cluster
ports:
- name: http
nodePort: 31800
port: 80
protocol: TCP
targetPort: 80
- name: https
nodePort: 31700
port: 443
protocol: TCP
targetPort: 443
selector:
app: ingress-nginx
sessionAffinity: None
type: LoadBalancer
status:
loadBalancer:
ingress:
- ip: 47.215.177.38
集群部署Ingress資源后,進(jìn)入集群流量的第一站就是Nginx Ingress中的Nginx服務(wù),由它做HTTP層的負(fù)載均衡,還有TLS終結(jié)等工作。
總結(jié)
文章對NodePort和LoadBalancer類型的Service做了簡單介紹,在測試環(huán)境中如果需要快速將服務(wù)從集群內(nèi)暴露出來,可以使用NodePort類型的Service,生產(chǎn)環(huán)境,如果使用了阿里云或騰訊云可以使用LoadBalancer類型的Service并配合Ingress,如果沒有也可以使用NodePort類型的Service并配置Haproxy等來實(shí)現(xiàn)負(fù)載均衡。