先來個一句話總結(jié):Ingress由Ingress規(guī)則、IngressController、IngressClass這3部分組成。Ingress資源只是一系列路由轉(zhuǎn)發(fā)配置,必須使用IngressController才能讓路由規(guī)則生效,而IngressClass是IngressController的具體實現(xiàn)。使用原則:先部署IngressController → 再部署Ingress資源。
1、理論
1.1、Ingress的概念
沒有Ingress之前,可以通過Service的nodePort對外暴露服務,將容器端口與Service的nodePort端口做映射,這樣訪問集群中任意一臺Node的IP:nodePort就能訪問到集群內(nèi)部。Service 的這種暴露服務的形式是工作在TCP/IP層。或者將Pod的端口與HostPort做映射。
但是這樣做弊端較多,比如暴露了太多的Node端口、無法做域名轉(zhuǎn)發(fā)等。
所以引入了Ingress的概念,Ingress是一個七層路由轉(zhuǎn)發(fā)器,類似于Nginx。使用Ingress進行路由轉(zhuǎn)發(fā)時,ingressController會基于ingress規(guī)則將客戶端請求直接轉(zhuǎn)發(fā)到Service對應的Pod上,這樣會跳過 kube-proxy 設置的路由轉(zhuǎn)發(fā)規(guī)則,可以提高網(wǎng)絡轉(zhuǎn)發(fā)效率。
1.2、Ingress的組成
Ingress資源是一種虛擬的資源和規(guī)則定義,需要配合ingressController才能生效。所以要讓Ingress資源工作,集群必須有一個正在運行的ingressController。
Ingress由Ingress規(guī)則、IngressController、IngressClass這3部分組成。Ingress規(guī)則只是一系列的配置,必須使用IngressController才能使其生效,而IngressClass是IngressController的具體實現(xiàn)。關(guān)系如下圖:
1.3、Ingress的功能和工作流程
ingressController的實現(xiàn)有多種,比如有Ingress-Nginx、Traefik、Kong Ingress等,所以需要在Yaml編排文件中指定ingressClass。
一旦Ingress資源成功部署創(chuàng)建,IngressController就會監(jiān)控到其配置的路由策略,并更新到Nginx的配置文件中生效。
綜上,IngressController 的功能如下:
- 接受外部的流量,并將請求負載均衡到內(nèi)部運行的 pod上
- 部署Ingress路由轉(zhuǎn)發(fā)規(guī)則
- 監(jiān)控Kube.NETes中運行的Pod,并在添加或刪除Pod后自動更新負載均衡規(guī)則
Ingress的工作流程,如下圖:
2、實踐
2.1、安裝IngressClass
本文實踐使用的是ingress-nginx,其實方式你可以自行實踐。
官網(wǎng)地址:https://kubernetes.Github.io/ingress-nginx/deploy/#quick-start
可以通過helm或kubectl安裝,本文使用的是kubectl方式安裝,yaml的文件內(nèi)容較多,你可以自行下載查閱。執(zhí)行以下命令安裝:
kubectl Apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/cloud/deploy.yaml
2.2、編排Yaml
IngressController部署完畢后,就是開始編排Yaml了。
Yaml中定義了一個容器鏡像是Nginx的Pod,然后通過Service與Pod關(guān)聯(lián),再通過Ingress規(guī)則訪問對應的Pod。
apiVersion: v1
kind: Pod
metadata:
name: web-app
namespace: demo
labels:
app: web-app
spec:
contAIners:
- name: web-app
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: web-service
namespace: demo
labels:
app: web-service
spec:
selector:
app: web-app
# ClusterIP | LoadBalancer | NodePort,使用Ingress就沒必要設置成NortPort
type: ClusterIP
clusterIP: None
ports:
- name: web-service-port
protocol: TCP
port: 80
targetPort: 80
---
# 創(chuàng)建Ingress策略
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
name: web-ingress
namespace: demo
spec:
# 指定ingressClass
ingressClassName: nginx
rules:
- host: web-ingress.mangod.top
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
2.3、部署測試
Yaml編排完畢后,使用kubectl apply命令部署,部署完畢后,在本地/etc/hosts里配置域名和某個K8S-Node節(jié)點的映射關(guān)系(當然,生產(chǎn)環(huán)境的訪問鏈路比這個長,后面有機會再介紹,文中為了快速測試,直接在本地配置DNS),類似這樣點的映射關(guān)系:
10.20.1.23 web-ingress.mangod.top
然后,瀏覽器訪問http://web-ingress.mangod.top/,界面如下,說明ingress使用成功。
此時我們使用如下命令,進入到ingressController對應的pod,繼續(xù)驗證,可以看到熟悉的nginx.conf,之前配置的ingress規(guī)則在配置里都可以看到,如下:
kubectl get pods -n ingress-nginx
kubectl exec ingress-nginx-controller-nginx-d864d97df-22ljk -it -n ingress-nginx /bin/bash
至此實踐過程結(jié)束。
3、總結(jié)
一句話總結(jié):Ingress由Ingress規(guī)則、IngressController、IngressClass這3部分組成。Ingress資源只是一系列路由轉(zhuǎn)發(fā)配置,必須使用IngressController才能讓路由規(guī)則生效,而IngressClass是IngressController的具體實現(xiàn)。使用原則:先部署IngressController → 再部署Ingress資源。