【本文內(nèi)容】
- 什么是Ingress
- Ingress的yaml配置
- Ingress的use case(什么情況下需要用到Ingress)
- Ingress Controller的介紹
- Demo - 通過(guò)Ingress暴露kubernetes dashboard
- tls相關(guān)(https)
【前置文章】
- 【k8s學(xué)習(xí)】Kubernetes學(xué)習(xí)——核心組件和架構(gòu)
- 【k8s學(xué)習(xí)】minikube伴郁、kubectl俊马、yaml配置文件的介紹
- 【k8s學(xué)習(xí)】在minikube上布署MongoDB和MongoExpress
- 【k8s學(xué)習(xí)】kubernetes namespace介紹
1. External Service vs. Ingress
External Service
假設(shè)我們的Kubernetes集群中有my-app pod
甘萧,以及my-app external service
慨蛙,意味著我們可以從外部以NodeIP + Port
的形式訪問(wèn)my-app項(xiàng)目,如http://124.89.11.11:35010
--> 這就是external service能達(dá)到的效果痴脾。這時(shí)候my-app service的yaml中的配置颤介,則需要配成:spec.type = LoadBalancer,并且需要配置spec.ports.nodePord = 35010赞赖,表明需要對(duì)集群外暴露這個(gè)Service滚朵,以下是定義external service的示例:
Ingress
官網(wǎng):https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/
但如果我們想要用https://my-app.com
來(lái)訪問(wèn)my-app項(xiàng)目,那么就需要用到Ingress
組件了前域。即會(huì)先創(chuàng)建一個(gè)my-app ingress
--> 然后轉(zhuǎn)發(fā)到my-app internal service
--> 再轉(zhuǎn)發(fā)到my-app pod
辕近,可以看到有了Ingress組件后,Service組件不再需要external了(即上述的type可以刪掉匿垄,不填默認(rèn)是ClusterIP移宅,即internal service了,不對(duì)外暴露椿疗,nodePort也可以刪除)吞杭。
2. Ingress yaml配置文件
簡(jiǎn)單的Ingress yaml示例:
注,這里的apiVersion有更新变丧,之前的版本是apiVersion: extensions/v1beta1,最新的版本是下述的v1绢掰,兩者的語(yǔ)法有些許差別痒蓬,比如v1beta1中是serviceName,servicePort滴劲,而在v1(下述)中則是service.name和service.port.number
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ingress
spec:
rules:
- host: dashboard.info.abc
http:
paths:
- path: "/"
pathType: Prefix
backend:
service:
name: myapp-internal-service
port:
number: 8080
-
apiVersion
和kind
攻晒,前兩行是聲明,其中kind表示當(dāng)前需要?jiǎng)?chuàng)建的是Ingress資源班挖。 -
spec
中的rules
:表示Routing rules鲁捏,路由規(guī)則。表示這個(gè)從host
來(lái)的請(qǐng)求萧芙,需要被轉(zhuǎn)發(fā)到serviceName
中给梅,即request from myapp.com
--> 轉(zhuǎn)發(fā)到myapp-internal-service
。 - 其中的
paths
表示可以按url的后綴進(jìn)行匹配双揪,下文有具體的例子解釋动羽。 - 【和internal service的對(duì)應(yīng)】,Ingress中的serviceName對(duì)應(yīng)的是service yaml中的metadata.name渔期,Ingress中的servicePort對(duì)應(yīng)的是service yaml中的spec.ports.port运吓。
3. Ingress Controller
官網(wǎng):https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress-controllers/
3.1 Ingress Controller介紹
除了安裝Ingress組件之外渴邦,我們還需要一個(gè)Ingress的實(shí)現(xiàn)(Implementation),這個(gè)實(shí)現(xiàn)就是Ingress Controller
拘哨,Ingress Controller也是運(yùn)行在Pod中的谋梭,即我們可以創(chuàng)建一個(gè)Pod,叫Ingress Controller Pod倦青。
Ingress Controller是干什么的瓮床?它是用來(lái)解析上述Ingress yaml中的rules規(guī)則的,即需要怎樣的跳轉(zhuǎn)姨夹。(如一級(jí)域名纤垂,二級(jí)域名等等,諸如此類(lèi)的跳轉(zhuǎn)規(guī)則的實(shí)現(xiàn))磷账。
目前有很多第三方的實(shí)現(xiàn)峭沦,如:
- Kubernetes Nginx Ingress Controller,github: https://github.com/kubernetes/ingress-nginx/blob/main/README.md#readme
- Kubernetes AWS Load Balancer Controller逃糟, github: https://github.com/kubernetes-sigs/aws-load-balancer-controller#readme
- 等等
3.2 現(xiàn)實(shí)中的Ingress Controller架構(gòu)
如果用的是一些云服務(wù)器吼鱼,例如aws, google提供的Kubernetes,那么請(qǐng)求會(huì)先到達(dá)這些云服務(wù)商的負(fù)載均衡器上绰咽,即Cloud Load Balancer
--> 再跳轉(zhuǎn)到我們?cè)贙ubernetes集群內(nèi)定義的Ingress Controller Pod
上 --> 然后再是my-app ingress
--> my-app internal service
--> my-app pod
菇肃。
相當(dāng)于云服務(wù)商會(huì)幫我們做掉負(fù)載均衡的部分。
如果我們的Kubernetes集群運(yùn)行在自己的服務(wù)器上(沒(méi)有依賴(lài)aws這些云服務(wù)商提供服務(wù))取募,那么在Ingress Controller之前琐谤,可能需要一臺(tái)Proxy Server,用來(lái)做轉(zhuǎn)發(fā)(負(fù)載均衡)玩敏。
3.3 在Minikube上安裝Ingress Controller
在minikube上可以通過(guò)以下命令斗忌,minikube會(huì)自動(dòng)幫我們安裝Kubernetes Nginx Ingress Controller,安裝的時(shí)候可能需要一些時(shí)間:
我minikube啟動(dòng)的時(shí)候vm-driver用的是hyperkit旺聚,然后遇到如下問(wèn)題:?minikube addons enable ingress
于是我換成docker作為vm-driver织阳,先用命令minikube delete --all
刪除下minikube,然后再run:minikube start --vm-driver=docker
砰粹。
再安裝ingress唧躲,就沒(méi)有問(wèn)題了:
通過(guò)查看namespace=kube-system下的pod,可以看到名為nginx-ingress-controller的相關(guān)的已經(jīng)running了:
kubectl get all -n ingress-nginx
3.4 示例:給kubernetes-dashboard配置Ingress
在minikube上安裝好基于Kubernetes Nginx的Ingress Controller后碱璃,我們?cè)囍okubenetes-dashboard配置Ingress弄痹,以便以hostName的方式暴露給集群外部使用。
首先運(yùn)行minikube dashboard:
minikube dashboard
首先查看kubernetes dashboard的所有配置(在namespace為kubernetes-dashboard下):
kubectl get all -n kubernetes-dashboard
編寫(xiě)Ingress yaml文件:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: dashboard-ingress
namespace: kubernetes-dashboard
spec:
rules:
- host: dashboard.com
http:
paths:
- path: "/"
pathType: Prefix
backend:
service:
name: kubernetes-dashboard
port:
number: 80
創(chuàng)建好之后嵌器,查看Ingress列表界酒,需要加上-n(即namespace的意思),否則只會(huì)在namespace=default下查詢(xún):kubectl apply -f dashboard-ingress.yaml
進(jìn)入host文件(我的是MacOS系統(tǒng)嘴秸,如果是Windows庇谆,自行查閱):
sudo vim /etc/hosts
在host文件的最后加上跳轉(zhuǎn)的mapping:
這要在瀏覽器中訪問(wèn)dashboard.com的時(shí)候會(huì)訪問(wèn)到我們的kubernetes dashboard。
3.5 default-http-backend
kubectl describe ingress dashboard-ingress -n kubernetes-dashboard
可能會(huì)遇到以下信息:
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
這個(gè)表示我們沒(méi)有default http來(lái)處理不正確的url凭疮,即如果我們?cè)趗rl中輸入dashboard.com/abc饭耳,會(huì)跳404,但如果我們配置了一個(gè)Service执解,名字就叫default-http-backend寞肖,那么所有404的跳轉(zhuǎn),就會(huì)跳到這個(gè)Service上了衰腌。
4. Ingress同一個(gè)域名下多個(gè)路徑
4.1 配置多個(gè)path
比如myapp.com網(wǎng)站新蟆,除了首頁(yè)之前,我們可能會(huì)有很多Service(即myapp.com項(xiàng)目并不只是一個(gè)Web項(xiàng)目右蕊,而是拆分成很多的微服務(wù)琼稻,那么可能會(huì)部署不同的Pod以及Mapping在不同的Service上),比如/analytics饶囚,/shopping帕翻,
我們可以通過(guò)在同一個(gè)Ingress配置多個(gè)path來(lái)達(dá)到這樣的效果:
spec:
rules:
- host: myapp.com
http:
paths:
- path: /analytics
pathType: Prefix
backend:
service:
name: analytics-service
port:
number: 3000
- path: /shopping
pathType: Prefix
backend:
service:
name: shopping-service
port:
number: 3001
4.2 配置多個(gè)host
另外一種case是有些大公司不止一個(gè)域名,除了myapp.com這個(gè)主域名外萝风,還會(huì)有二級(jí)域名嘀掸,如analytics.myapp.com,shopping.myapp.com等等规惰,針對(duì)這種情況睬塌,需要配置多個(gè)host:
spec:
rules:
- host: analytics.myapp.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: analytics-service
port:
number: 3000
- host: shopping.myapp.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: shopping-service
port:
number: 3001
5. 配置TLS認(rèn)證—http://
官網(wǎng):https://kubernetes.io/docs/concepts/services-networking/ingress/#tls
需要要Ingress yaml配置文件中的spec加tls配置,指向Secret中的metadata.name(所以還需要再配置一個(gè)Secret yaml文件)歇万。
spec:
tls:
- hosts:
- my-app.com
secretName: myapp-secret-tls
Secret yaml配置文件衫仑,當(dāng)需要?jiǎng)?chuàng)建tls的Secret,需要指定的type為kubernetes.io/tls
:
apiVersion: v1
kind: Secret
metadata:
name: myapp-secret-tls
namespace: default
data:
tls.crt: base64 encoded cert
tls.key: base64 encoded key
type: kubernetes.io/tls
需要注意的是Secret中的namespace需要和Ingress中的一致堕花,否則Ingress無(wú)法mapping這個(gè)信息。
參考:
- https://www.youtube.com/watch?v=X48VuDVv0do
- https://kubernetes.io/docs/tasks/access-application-cluster/ingress-minikube/
- https://stackoverflow.com/questions/70237546/minikube-dashboard-ingress
- https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0