在ingress之前,我們想要存取k8s叢集中的pod服務時,是通過部署一個service,將service的type設定為NodePort或者將設定為LoadBalance,這樣可以在物理機上開闢出一個物理埠給到對應的service,service再通過dns解析出具體要路由的Pod服務,從而對Pod服務進行服務轉發存取。
但是在生產環境,一般是會有幾百上千個pod服務,意味著需要有幾百上千個service物件,那麼多service物件對外提供存取服務,都需要開闢埠,需要面臨下面幾個問題:
1、這些service該怎麼去管理?
2、這麼多埠管理,埠的建立需要消耗資源,降低效能。
3、存取困難,這麼多service,到底應該存取哪個service?
因此kubernetes提供了Ingress方案,Ingress方案為整個叢集提供了統一的入口,相當於微服務中的閘道器(gateway/nginx),所有的service不再對外提供介面方案,所有的請求都經過ingress進行路由轉發。
Ingress可以理解為Service 的Service , 相關於是一個閘道器入口,通過Ingress統一實現請求的分發,根據定義的路由規則,把請求分發給下游服務。
有了Ingress服務後,只需要對外暴露一個埠即可,其它所有的服務都只需要在內網存取即可。
官網的原圖:https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/
Ingress的作用跟Nginx有點像,但這裡之所以不用Nginx,是因為每個Pod服務都是動態生成的,以為Pod服務域名、IP都可能會發生變化,所以沒辦法直接用Nginx.
而Ingress就像是一個提供動態的nginx。通過將要路由的服務轉化成一個規則,通過對一系列的規則進行監聽轉發。
可以參考https://github.com/kubernetes/ingress-nginx/tree/nginx-0.30.0 ;
按順序部署上圖中的幾個檔案服務即可。
再給ingress開闢一個物理埠:
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: 80
nodePort: 30080
protocol: TCP
- name: https
port: 443
targetPort: 443
nodePort: 30443
protocol: TCP
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
執行:kubectl apply -f ingress-servce.yaml
目標:實現ingress轉發規則定義,實現從Ingress定義的規則把請求轉發到服務。
1)定義一個後端服務:
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: harbor.hyz.com/library/mynginx:v1
ports:
- containerPort: 80
2)定義Ingress轉發規則:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx
namespace: default
labels:
app: nginx
spec:
rules:
- host: ingress.huangyz.com
http:
paths:
- backend:
serviceName: nginx
servicePort: 80
通過域名存取:
具體的流轉對應流程:
隨機進入某一個nginx-ingress-controller服務,檢視根據規則動態生成的nginx路由設定:
1)部署nginx服務(已部署),部署tomcat服務
apiVersion: v1
kind: Service
metadata:
name: tomcat
namespace: default
spec:
selector:
app: tomcat
ports:
- port: 8080
targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: tomcat
template:
metadata:
labels:
app: tomcat
spec:
containers:
- name: tomcat
image: harbor.hyz.com/library/mytomcat:v1
ports:
- containerPort: 8080
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx
namespace: default
labels:
app: nginx
spec:
rules:
- host: ingress1.huangyz.com
http:
paths:
- path: /
backend:
serviceName: nginx
servicePort: 80
- host: ingress2.huangyz.com
http:
paths:
- path: /
backend:
serviceName: tomcat
servicePort: 8080
存取:http://ingress1.huangyz.com:30080,http://ingress2.huangyz.com:30080:分別存取nginx,tomcat的應用頁面。
檢視動態生成的設定,多了tomcat一項的路由設定:
部署nginx,tomcat服務(已部署)
部署ingress規則:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx
namespace: default
labels:
app: nginx
annotations:
nginx.ingress.kubernetes.io/rewrite-target: / # 請求重寫,重寫定位到跟路徑下存取服務
spec:
rules:
- host: ingress.huangyz.com
http:
paths:
- path: /nginx # 請求是/nginx/** 都會被攔截,請求傳送給nginx服務
backend:
serviceName: nginx
servicePort: 80
- path: /tomcat
backend:
serviceName: tomcat
servicePort: 8080
注意:
path : /nginx 請求必須滿足:ingress.huangyz.com/nginx 必須要求後端服務也有與之對應的請求;
@GetMapping(「/nginx」)
Path: / tomcat
@GetMapping(「/tomcat」)
我們把nginx的請求重定向到百度首頁:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx
namespace: default
labels:
app: nginx
annotations:
nginx.ingress.kubernetes.io/permanent-redirect: https://www.baidu.com
spec:
rules:
- host: ingress.huangyz.com
http:
paths:
- backend:
serviceName: nginx
servicePort: 80
這裡只是試驗了幾種情況,驗證了基本都是nginx的功能,只不過實現了nginx的路由規則動態設定化了。感興趣的童鞋也可以根據上面的幾種情況,在自己的環境上進行一個驗證。