示例:Ingress通過互聯網訪問應用


Ingress

Ingress 是 Kubernetes 的一種 API 對象,將集群內部的 Service 通過 HTTP/HTTPS 方式暴露到集群外部,並通過規則定義 HTTP/HTTPS 的路由。Ingress 具備如下特性:集群外部可訪問的 URL、負載均衡、SSL Termination、按域名路由(name-based virtual hosting)。

Ingress Controller (通常需要負載均衡器配合)負責實現 Ingress API 對象所聲明的能力。如下圖所示:

  1. Ingress Controller 監聽所有 worker 節點上的 80/443 端口
  2. Ingress Controller 將所有對域名為 a.kuboard.cn 的 HTTP/HTTPS 請求路由到 Service B 的 9080 端口
  3. Service B 將請求進一步轉發到其標簽所選擇的 Pod 容器組(通過 targetPort 指定容器組上的端口號)

該圖中,請求被轉發的過程為:

  1. 假設您將 a.kuboard.cn 的 DNS 解析到了集群中的一個 worker 節點的 IP 地址 192.168.2.69。(如果您的 worker 節點有外網地址,請使用外網地址,這樣您可以從外網訪問您的服務)
  2. 從客戶端機器執行命令 curl http://a.kuboard.cn/abc/,該請求您將被轉發到 192.168.2.69 這個地址的 80 端口,並被 Ingress Controller 接收
  3. Ingress Controller 根據請求的域名 a.kuboard.cn 和路徑 abc 匹配集群中所有的 Ingress 信息,並最終找到 Ingress B 中有這個配置,其對應的 Service 為 Service B9080 端口
  4. Ingress Controller 通過 kube-proxy 將請求轉發到 Service B 對應的任意一個 Pod 上 與 Service B9080 端口對應的容器端口上。(從 Ingress Controller 到 Pod 的負載均衡由 kube-proxy + Service 實現)

Ingress Controller

如上所述,您必須在 Kubernetes 集群中安裝了 Ingress Controller,您配置的 Ingress 才能生效。

划重點
Ingress 只是 Kubernetes 中的一種配置信息;Ingress Controller 才是監聽 80/443 端口,並根據 Ingress 上配置的路由信息執行 HTTP 路由轉發的組件。

Ingress Controller 有多種實現可供選擇,請參考 Kubernetes 官方文檔 Additional controllers

,比較常用的有 Nginx Ingress Controller for Kubernetes等。

在 Kubernetes中安裝Nginx Ingress Controller for Kubernetes

在您 Kubernetes 集群中的安裝。該 Ingress Controller 以 DaemonSet 的類型部署到 Kubernetes,且監聽了 hostPort 80/443,YAML 片段如下所示:

如果您打算使用其他 Ingress Controller,您可以 卸載 Nginx Ingress Controller;如果您尚未安裝任何 Ingress Controller,請參考 安裝 Nginx Ingress Controller,以便可以完成本教程的后續內容。

apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: nginx-ingress
  namespace: nginx-ingress
	# ...
spec:
  selector:
    matchLabels:
      app: nginx-ingress
  template:
    metadata:
      labels:
        app: nginx-ingress
    spec:
      serviceAccountName: nginx-ingress
      containers:
      - image: nginx/nginx-ingress:1.5.3
        name: nginx-ingress
        ports:
        - name: http
          containerPort: 80
          hostPort: 80
        - name: https
          containerPort: 443
          hostPort: 443

TIP

  • Ingress Controller 並非只能監聽 80/443 端口,您可以根據自己網絡拓撲的需要,選擇合適的端口
  • 根據您安裝 Ingress Controller 的方式不同,您的 Ingress Controller 並不一定監聽了所有 worker 節點的 80/443 端口(本教程不涉及此主題)
  • 您也可以在 Kubernetes 集群中安裝多種 Ingress Controller,請參考 Using multiple Ingress controllers

融入到網絡拓撲中

如前所述,Kubernetes Ingress 只能監聽到節點的 80/443 端口,且 Ingress 可以完成 L7 路由的功能。由於 Kubernetes Ingress 配置更便捷,推薦使用 Kubernetes Ingress 替代常規的互聯網應用架構中的 Nginx 反向代理。那么,如何使部署在內網的 Kubernetes 集群上的 Ingress Controller 的 80/443 端口可以在外網訪問到呢?

本教程推薦如下兩種做法,結合您自己對安全性、可靠性等因素的考量,您可以演化出適合自己的拓撲結構。

暴露單worker節點

如下圖所示,暴露單個 worker 節點的步驟如下:

  • 為您 Kubernetes 集群中的某一個 worker 節點配置外網 IP 地址 Z.Z.Z.Z
  • 將您在 Ingress 中使用到的域名(假設是a.demo.kuboard.cn)解析到該外網 IP 地址 Z.Z.Z.Z
  • 設置合理的安全組規則(開放該外網 IP 地址 80/443 端口的入方向訪問)

文檔 安裝 Kubernetes 單Master節點 中使用的就是這種拓撲結構。這種方式下,Ingress Controller 存在單點故障的可能性。

使用外部負載均衡器

如下圖所示,使用外部負載均衡器的步驟如下:

  • 創建一個集群外部的負載均衡器,該負載均衡器擁有一個外網 IP 地址 Z.Z.Z.Z,並監聽 80/443 端口的 TCP 協議
  • 將負載均衡器在 80/443 端口上監聽到的 TCP 請求轉發到 Kubernetes 集群中所有(或某些)worker 節點的 80/443 端口,可開啟按源IP地址的會話保持
  • 將您在 Ingress 中使用到的域名(假設是a.demo.kuboard.cn)解析到該負載均衡器的外網 IP 地址 Z.Z.Z.Z

文檔 安裝 Kubernetes 高可用 中使用的就是這種拓撲結構。

實戰:通過 Ingress 使您的應用程序在互聯網可用

前提

  • 假設您已經完成了 公布應用程序 中的實戰部分
  • 假設您已經將 Ingress 融入到您的網絡拓撲中,並且將 *.demo.kuboard.cn (請使用您自己的域名)解析到對應的外網 IP 地址 (暫時可以通過修改主機hosts文件的方式來實現)
  • 使用kubectl

創建文件 nginx-deployment.yaml

vim nginx-deployment.yaml

文件內容如下

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9

創建文件 nginx-service.yaml

vim nginx-service.yaml

文件內容如下

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  labels:
    app: nginx
spec:
  selector:
    app: nginx
  ports:
  - name: nginx-port
    protocol: TCP
    port: 80
    nodePort: 32600
    targetPort: 80
  type: NodePort

創建文件 nginx-ingress.yaml

vim nginx-ingress.yaml

文件內容如下

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: my-ingress-for-nginx  # Ingress 的名字,僅用於標識
spec:
  rules:                      # Ingress 中定義 L7 路由規則
  - host: a.demo.kuboard.cn   # 根據 virtual hostname 進行路由(請使用您自己的域名)
    http:
      paths:                  # 按路徑進行路由
      - path: /
        backend:
          serviceName: nginx-service  # 指定后端的 Service 為之前創建的 nginx-service
          servicePort: 80

執行命令

kubectl apply -f nginx-deployment.yaml
kubectl apply -f nginx-service.yaml
kubectl apply -f nginx-ingress.yaml

檢查執行結果

kubectl get ingress -o wide

可查看到名稱為 my-ingress-for-nginx 的 Ingress。

從互聯網訪問

# 請使用您自己的域名,或者使用瀏覽器訪問(前提是已經修改了主機的hosts文件)
curl a.demo.kuboard.cn


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM