寫在前面
Ingress
英文翻譯 進入;進入權;進食
,更准確的講就是入口,即外部流量進入k8s
集群必經之口。這道大門到底有什么作用?我們如何使用Ingress
?k8s
又是如何進行服務發現的呢?先看一張圖:
備注:此圖來源我轉載的一篇博客NodePort,LoadBalancer還是Ingress?我該如何選擇 - kubernetes,特此說明。
原理
雖然k8s
集群內部署的pod
、server
都有自己的IP
,但是卻無法提供外網訪問,以前我們可以通過監聽NodePort
的方式暴露服務,但是這種方式並不靈活,生產環境也不建議使用。Ingresss
是k8s
集群中的一個API
資源對象,扮演邊緣路由器(edge router)的角色,也可以理解為集群防火牆、集群網關,我們可以自定義路由規則來轉發、管理、暴露服務(一組pod),非常靈活,生產環境建議使用這種方式。另外LoadBlancer
也可以暴露服務,不過這種方式需要向雲平台申請負債均衡器;雖然目前很多雲平台都支持,但是這種方式深度耦合了雲平台,所以你懂的。
首先我們來思考用傳統的web
服務器,比如Nginx
,如何處理這種場景?
Nginx
充當一個反向代理服務器攔截外部請求,讀取路由規則配置,轉發相應的請求到后端服務。
kubernetes
處理這種場景時,涉及到三個組件:
- 反向代理
web
服務器
負責攔截外部請求,比如Nginx
、Apache
、traefik
等等。我一般以Deployment
方式部署到kubernetes
集群中,當然也可以用DeamonSet
方式部署;這兩種部署方式個人覺得有利有弊,感興趣的請參考這篇文章,這里就不敖述了。 - Ingress controller
k8s
中的controller
有很多,比如CronJob
、DeamonSet
、Deployment
、ReplicationSet
、StatefulSet
等等,大家最熟悉的應該是Deployment
(嘿嘿,我也是),它的作用就是監控集群的變化,使集群始終保持我們期望的最終狀態(yml文件)。同理,Ingress controller
的作用就是實時感知Ingress
路由規則集合的變化,再與Api Server
交互,獲取Service
、Pod
在集群中的IP
等信息,然后發送給反向代理web
服務器,刷新其路由配置信息,這就是它的服務發現機制。 - Ingress
定義路由規則集合,上面已經詳細介紹,這里就不再敖述了。
經過上面的剖析,知道了吧,如果我們僅僅創建Ingress
對象,只是定義了一系列路由規則集合而已,沒有任何作用,不要想得太簡單了,嘿嘿。
Ingress 選型
這個我花費了不少時間,最終選用的是Traefik
,它是一個用Golang開發的輕量級的Http反向代理和負載均衡器,雖然相比於Nginx
,它是后起之秀,但是它天然擁抱kubernetes
,直接與集群k8s的Api Server
通信,反應非常迅速,實時感知集群中Ingress
定義的路由規則集合和后端Service
、Pod
的變化,自動熱更新Traefik
后端配置,根本不用創建Ingress controller
對象,同時還提供了友好的控制面板和監控界面,不僅可以方便地查看Traefik
根據Ingress
生成的路由配置信息,還可以查看統計的一些性能指標數據,如:總響應時間、平均響應時間、不同的響應碼返回的總次數等,Traefik
部署請參考官網用戶示例Kubernetes Ingress Controller。不僅如此,Traefik
還支持豐富的annotations
配置,可配置眾多出色的特性,例如:自動熔斷、負載均衡策略、黑名單、白名單;還支持許多后端存儲,如:zookeeper、eureka、consul、rancher、docker等,它會自動感知這些統一配置中心的變化,熱更新自己的路由配置,所以Traefik
對於微服務來說簡直就是一神器啊,嘿嘿。那么Traefik
性能又如何呢?容器化部署,還擔心性能,不要這么搞笑,好嗎。而Nginx
在擁抱kubernetes
這方面比較后知后覺,詳情請參考官方網站和開源項目ingress-nginx ;另外微軟開源的微服務示例項目 eShopOnContainers 采用了ingress-nginx
,大家可以下去自行研究。
**Traefik **:
示例說明
使用Ingress
暴露微服務
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
labels:
app: light
component: frontend
name: light-edge-router
namespace: geekbuying-light
annotations:
kubernetes.io/ingress.class: "traefik"
ingress.kubernetes.io/ssl-redirect: "false"
traefik.frontend.rule.type: "PathPrefixStrip"
traefik.ingress.kubernetes.io/frontend-entry-points: "http,https"
traefik.ingress.kubernetes.io/priority: "3"
spec:
rules:
- host: <hostdomain literal>
http:
paths:
- path: /api/v1/light
backend:
serviceName: aggregation-light-api
servicePort: 80
- path: /api/v1/identity
backend:
serviceName: identity-api
servicePort: 80
非常重要:
- 當我們定義額外的路由時,比如這里的
/api/vi/identity
,必須添加這個traefik.ingress.kubernetes.io/rule-type: PathPrefixStrip
注解傳遞路徑,否則會看不到任何效果;ingress.kubernetes.io/ssl-redirect: "false"
是否強制使用https
,其他的配置信息,請查看詳情。另外,不同的Ingress
選型,請參照各自的組件說明。 - 其他命名空間下的服務發現規則為:[serviceName].[namespace]:[port],如:exceptionless-ui.geekbuying-light-addons:80(備注:端口80可以省略,其他端口不能省略),表示查找
geekbuying-light-addons
命名空間下的exceptionless-ui
服務,並匹配端口。
特性配置
traefik支持強大的annotations
配置,需要添加到kubernetes
相應資源對象的annotations
下面。至於具體配置到的哪個對象,先弄清楚三個概念:
-
EntryPoint(入口點)
顧名思義,這是外部網絡進入traefik
的入口,我們上面就是通過監聽主機端口攔截請求。 -
FrontEnd(前端)
traefik
攔截請求后,會轉發給FrontEnd
。前端定義EntryPoint
映射到BackEnd
的路由規則集,字段包括Host
,Path
,Headers
等,匹配請求后,默認通過加權輪詢負載算法路由到一個可用的BackEnd
,然后進入指定的微服務,這就是服務發現。
備注:這些路由規則可以來自不同的后端存儲,如
Kubernetes、zookeeper、eureka、consul
等,Kubernetes
使用的Ingress
資源對象定義路由規則集。建議大家自行去官網學習Kubernetes Ingress Backend。
- BackEnd(后端)
一組http
服務集,kubernetes
中對應一個service
對象下的一組pod
地址。對於后端的服務發現,可配置負載均衡策略、熔斷器等特性。
一個后端service
對象的配置例子:
apiVersion: v1
kind: Service
metadata:
annotations:
traefik.backend.circuitbreaker: NetworkErrorRatio() > 0.5
traefik.backend.loadbalancer.method: drr
labels:
app: light
component: identity
name: identity-api
namespace: geekbuying-light
spec:
ports:
- port: 80
selector:
app: light
component: identity
type: webapi
效果圖
控制面板:
前端優先級、后端熔斷器和負載均衡策略:
監控界面:
總結
綜上所述,首先部署擁抱k8s的反向代理服務器(treafik、nginx
等)攔截請求,然后攔截的請求會根據Ingress
定義的路由規則集,轉發到集群內部對應的Service
。
延伸閱讀
https://docs.traefik.io/
https://github.com/containous/traefik
https://docs.traefik.io/user-guide/kubernetes/
https://docs.traefik.io/configuration/backends/kubernetes/
https://kubernetes.io/docs/concepts/services-networking/ingress/
https://kubernetes.io/docs/admin/authorization/rbac/
https://github.com/kubernetes/ingress-nginx/blob/master/README.md
https://kubernetes.github.io/ingress-nginx/development/
https://www.kubernetes.org.cn/1237.html
https://github.com/kubernetes/ingress-nginx
https://blog.csdn.net/hxpjava1/article/details/79459489
https://blog.csdn.net/hxpjava1/article/details/79375452
如果你覺得本篇文章對您有幫助的話,感謝您的【推薦】。
如果你對 kubernets 感興趣的話可以關注我,我會定期的在博客分享我的學習心得。