【本文內(nèi)容】
- 什么是Ingress
- Ingress的yaml配置
- Ingress的use case(什么情況下需要用到Ingress)
- Ingress Controller的介紹
- Demo - 通過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的形式訪問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來訪問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配置文件
簡單的Ingress yaml示例:
注,這里的apiVersion有更新,之前的版本是apiVersion: extensions/v1beta1,最新的版本是下述的v1,兩者的語法有些許差別,比如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來的請(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是干什么的?它是用來解析上述Ingress yaml中的rules規(guī)則的,即需要怎樣的跳轉(zhuǎn)。(如一級(jí)域名,二級(jí)域名等等,諸如此類的跳轉(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ù)器上(沒有依賴aws這些云服務(wù)商提供服務(wù)),那么在Ingress Controller之前,可能需要一臺(tái)Proxy Server,用來做轉(zhuǎn)發(fā)(負(fù)載均衡)。
3.3 在Minikube上安裝Ingress Controller
在minikube上可以通過以下命令,minikube會(huì)自動(dòng)幫我們安裝Kubernetes Nginx Ingress Controller,安裝的時(shí)候可能需要一些時(shí)間:
我minikube啟動(dòng)的時(shí)候vm-driver用的是hyperkit,然后遇到如下問題:?minikube addons enable ingress

于是我換成docker作為vm-driver,先用命令minikube delete --all刪除下minikube,然后再run:minikube start --vm-driver=docker。
再安裝ingress,就沒有問題了:

通過查看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

編寫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下查詢:kubectl apply -f dashboard-ingress.yaml

進(jìn)入host文件(我的是MacOS系統(tǒng),如果是Windows,自行查閱):
sudo vim /etc/hosts
在host文件的最后加上跳轉(zhuǎn)的mapping:

這要在瀏覽器中訪問dashboard.com的時(shí)候會(huì)訪問到我們的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è)表示我們沒有default http來處理不正確的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)站,除了首頁之前,我們可能會(huì)有很多Service(即myapp.com項(xiàng)目并不只是一個(gè)Web項(xiàng)目,而是拆分成很多的微服務(wù),那么可能會(huì)部署不同的Pod以及Mapping在不同的Service上),比如/analytics,/shopping,
我們可以通過在同一個(gè)Ingress配置多個(gè)path來達(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無法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