Kubernetes Ingress

misakivv發表於2024-09-18

目錄
  • 一、為什麼需要 Ingress
  • 二、什麼是Ingress,Ingress Controller
  • 三、Ingress 的工作原理
  • 四、Ingress 配置資源模版
  • 五、例項
    • 1、搭建 Ingress 環境
      • 1.1、Ingress-Nginx官網地址
      • 1.2、master 節點下載 deploy.yaml
      • 1.3、所有節點提前 pull 必須的映象
      • 1.4、修改並應用 deploy.yaml 檔案
      • 1.5、檢視 ingress-nginx
      • 1.6、檢視 service
    • 2、準備 service 和 pod
      • 2.1、建立 nginx 和 tomcat 的 Deployment
      • 2.2、建立並檢視對應 svc,pod
    • 3、HTTP代理
      • 3.1、建立 ingress-http.yaml
      • 3.2、應用並檢視
      • 3.3、本地電腦配置 hosts 解析
      • 3.4、透過域名+埠號檢視
    • 4、HTTPS代理
      • 4.1、生成證書
      • 4.2、建立金鑰
      • 4.3、建立ingress-https.yaml
      • 4.4、應用並檢視
      • 4.5、透過 https://域名+埠號 訪問

一、為什麼需要 Ingress

我們使用傳統的NodePort型別的Service的確能將叢集內的服務暴露給叢集外部客戶端去訪問,但是使用這種型別的Service存在以下問題:

  • 一個埠只能使用一個服務,所有透過NodePort暴露的埠都需要提前規劃;

  • 如果叢集上的Service的數量太多的話,暴露的NodePort埠不具有連續性。後期維護成本太大,且不宜於管理;

  • 無論是Iptables或者是Ipvs模型的Service都配置在Linux核心中的Netfilter之上進行四層排程。是一種比較通用的排程器。支援排程HTTP、Mysql等應用層服務,不過,也正是工作於傳輸層從而使得它無法做到類似解除安裝HTTPS中的SSL會話,也不支援基於URL的請求排程機制,因為它工作在傳輸層。kubernetes也不支援為此類負載均衡配置任何型別的健康狀態檢測機制。

為了解決這種需求,提供了一種高階的流量管理,也就Ingress和Ingress Controller,kubernetes使用Ingress Controller來接收所有入口的流量,然後透過Ingress資源來定義流量如何區分,以及如何轉發的規則。有了Ingress和Ingress控制器。我們就可以直接定義流量轉發規則來發布服務,而無需建立許多的NodePort和LoadBalancer型別的Service。

image-20240917180553792

二、什麼是Ingress,Ingress Controller

Ingress 是 Kubernetes 中的一個 API 物件,用於定義叢集內部服務的外部可訪問性。簡而言之,Ingress 是用來描述如何將外部請求路由到叢集內部的服務的規則集合。Ingress 提供了一種定義 HTTP 路由規則的方式,使得外部客戶端可以透過一個統一的入口點訪問叢集內部的服務。

img

Ingress相當於一個7層的負載均衡器,是kubernetes對反向代理的一個抽象,它的工作原理類 似於Nginx,可以理解成在Ingress裡建立諸多對映規則,Ingress Controller透過監聽這些配置規則並 轉化成Nginx的反向代理配置 , 然後對外部提供服務。

在這裡有兩個核心概念:

  • ingress:kubernetes中的一個物件,作用是定義請求如何轉發到service的規則
  • ingress controller:具體實現反向代理及負載均衡的程式,對ingress定義的規則進行解析,根據配置的規則來實現請求轉發,實現方式有很多,比如Nginx, Contour, Haproxy等等

三、Ingress 的工作原理

Ingress(以Nginx為例)的工作原理如下:

  1. 使用者編寫Ingress規則,說明哪個域名對應kubernetes叢集中的哪個Service
  2. Ingress控制器動態感知Ingress服務規則的變化,然後生成一段對應的Nginx反向代理配置
  3. Ingress控制器會將生成的Nginx配置寫入到一個執行著的Nginx服務中,並動態更新
  4. 到此為止,其實真正在工作的就是一個Nginx了,內部配置了使用者定義的請求轉發規則

image-20240917184743873

四、Ingress 配置資源模版

apiVersion: networking.k8s.io/v1   # 資源所屬的API群組和版本
kind: Ingress   # 資源型別
metadata:   # 後設資料
     name:  <string>   # 資源名稱
 namespace: <string>  # 名稱空間
spec:     
   ingressClassName: "nginx"   # 適用的Ingress控制器類別,須明確指明
   rules: <[]object>    # Ingress規則列表
   - host: <string>      # 虛擬主機的FQDN,俗稱域名
     http: <object>
   paths: <[]object>      # 虛擬主機的PATH定義列表
   - path: <string>    # 匹配以什麼開頭類似於nginx中的location
  pathType: <string>    # Prefix字首匹配,不區分大小寫 Exact。精確匹配URL,區分大小寫
  backend: <object>     # 後端
      service: <object>   #關聯後端的Service
      name: <string>   # 後端Service的名稱
  port: <object>   #後端Service的埠
     name:      # 埠名稱
 number:   # 埠號
 

五、例項

1、搭建 Ingress 環境

1.1、Ingress-Nginx官網地址

#Ingress-Nginx 官網地址
https://kubernetes.github.io/ingress-nginx/
 
#Ingress-Nginx GitHub地址
https://github.com/kubernetes/ingress-nginx

1.2、master 節點下載 deploy.yaml

wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.0.4/deploy/static/provider/baremetal/deploy.yaml

image-20240917195944285

1.3、所有節點提前 pull 必須的映象

docker pull registry.cn-hangzhou.aliyuncs.com/eagleslab/service:ingresswebhook111

docker tag c41e9fcadf5a k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1

docker pull registry.cn-hangzhou.aliyuncs.com/eagleslab/service:ingresscontroller104

docker tag a9f76bcccfb5 k8s.gcr.io/ingress-nginx/controller:v1.0.4

1.4、修改並應用 deploy.yaml 檔案

如果是提前pull的映象,要刪除掉deploy.yaml中對映象sha256的檢查,在image標籤中,刪除 @sha256到行尾

sed -i 's/@sha256:.*//g' deploy.yaml

kubectl apply -f deploy.yaml

image-20240917220226247

1.5、檢視 ingress-nginx

kubectl get pods -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx

image-20240918101812536

1.6、檢視 service

kubectl get svc -n ingress-nginx

image-20240918101850149

2、準備 service 和 pod

image-20240917222647664

2.1、建立 nginx 和 tomcat 的 Deployment

apiVersion: v1
kind: Namespace
metadata:
  name: dev
  
---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: dev
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.1
        ports:
        - containerPort: 80

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: tomcat-deployment
  namespace: dev
spec:
  replicas: 3
  selector:
    matchLabels:
      app: tomcat-pod
  template:
    metadata:
      labels:
        app: tomcat-pod
    spec:
      containers:
      - name: tomcat
        image: tomcat:8.5-jre10-slim
        ports:
        - containerPort: 8080

---

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  namespace: dev
spec:
  selector:
    app: nginx-pod
  clusterIP: None
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 80

---

apiVersion: v1
kind: Service
metadata:
  name: tomcat-service
  namespace: dev
spec:
  selector:
    app: tomcat-pod
  clusterIP: None
  type: ClusterIP
  ports:
  - port: 8080
    targetPort: 8080

2.2、建立並檢視對應 svc,pod

kubectl apply -f tomcat-nginx.yaml

kubectl get pods,svc -n dev

image-20240918103916622

3、HTTP代理

3.1、建立 ingress-http.yaml

ingressClassName: nginx

使用 nginx 的 IngressClass(關聯的 ingress-nginx 控制器)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-nginx
  namespace: dev
spec:
  rules:
  - host: nginx.bbj1030.cn
    http:
      paths:
      - path: /
        pathType: Prefix
        backend: 
          service:
            name: nginx-service
            port: 
              number: 80
  ingressClassName: nginx
---

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-tomcat
  namespace: dev
spec:
  rules:
  - host: tomcat.bbj1030.cn
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: tomcat-service
            port: 
              number: 8080
  ingressClassName: nginx

3.2、應用並檢視

kubectl get ing -n dev

image-20240918120230378

kubectl describe ing -n dev

image-20240918120311196

3.3、本地電腦配置 hosts 解析

將以上 nginx.bbj1030.cn 和 tomcat.bbj1030.cn 解析到 master 節點 192.168.112.10上

192.168.112.10 nginx.bbj1030.cn
192.168.112.10 tomcat.bbj1030.cn

image-20240918120828477

3.4、透過域名+埠號檢視

nginx.bbj1030.cn:32596

tomcat.bbj1030.cn:32596

image-20240918112152192

image-20240918120508649

image-20240918130957117

4、HTTPS代理

4.1、生成證書

openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/C=CN/ST=BJ/L=BJ/O=nginx/CN=bbj1030.cn"

4.2、建立金鑰

kubectl create secret tls tls-secret --key tls.key --cert tls.crt

image-20240918121104780

4.3、建立ingress-https.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: https-nginx
  namespace: dev
spec:
  tls:
    - hosts:
      - nginx.bbj1030.cn
      secretName: tls-secret # 指定秘鑰
  rules:
  - host: nginx.bbj1030.cn
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-service
            port: 
              number: 80
  ingressClassName: nginx
---

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tomcat-https
  namespace: dev
spec:
  tls:
    - hosts:
      - tomcat.bbj1030.cn
      secretName: tls-secret # 指定秘鑰
  rules:
  - host: tomcat.bbj1030.cn
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: tomcat-service
            port: 
              number: 8080
  ingressClassName: nginx

4.4、應用並檢視

需要先刪除之前建立的 ingress 不然會報錯

image-20240918121547056

kubectl delete -f ingress-http.yaml

kubectl apply -f ingress-https.yaml

image-20240918121408401

kubectl get ing -n dev

kubectl describe ing -n dev

image-20240918121642798

4.5、透過 https://域名+埠號 訪問

https://nginx.bbj1030.cn:31563

https://tomcat.bbj1030.cn:31563

image-20240918131142580

image-20240918121928061

相關文章