Kubernetes用Helm安裝Ingress並踩一下使用的坑

1 前言

歡迎訪問南瓜慢說 www.pkslow.com獲取更多精彩文章!

IngressKubernetes一個非常重要的Controller,它類似一個路由轉發的組件,可以讓外界訪問Kubernetes內部的Service。除了Ingress,還有NodePortLoadBalance等方式,Ingress暴露給外界的方式還是很常用的。

2 安裝Ingress

我們通過helm來安裝,會方便一些,先更新helm的倉庫。

$ helm repo update

Helm相關文章:用Helm部署Kubernetes應用,支援多環境部署與版本回滾

容器技術相關文章

更新完之後,查找倉庫關於Ingress的包有哪些:

$ $ helm search repo ingress
NAME                          	CHART VERSION	APP VERSION	DESCRIPTION                                       
azure/gce-ingress             	1.2.0        	1.4.0      	A GCE Ingress Controller                          
azure/ingressmonitorcontroller	1.0.48       	1.0.47     	IngressMonitorController chart that runs on kub...
azure/nginx-ingress           	1.41.2       	v0.34.1    	An nginx Ingress controller that uses ConfigMap...
stable/nginx-ingress          	0.9.5        	0.10.2     	An nginx Ingress controller that uses ConfigMap...
azure/contour                 	0.2.0        	v0.15.0    	Contour Ingress controller for Kubernetes         
azure/external-dns            	1.8.0        	0.5.14     	Configure external DNS servers (AWS Route53, Go...
azure/kong                    	0.36.7       	1.4        	DEPRECATED The Cloud-Native Ingress and API-man...
azure/lamp                    	1.1.3        	7          	Modular and transparent LAMP stack chart suppor...
azure/nginx-lego              	0.3.1        	           	Chart for nginx-ingress-controller and kube-lego  
azure/traefik                 	1.87.2       	1.7.24     	A Traefik based Kubernetes ingress controller w...
azure/voyager                 	3.2.4        	6.0.0      	DEPRECATED Voyager by AppsCode - Secure Ingress...
stable/external-dns           	0.4.9        	0.4.8      	Configure external DNS servers (AWS Route53, Go...
stable/lamp                   	0.1.4        	           	Modular and transparent LAMP stack chart suppor...
stable/nginx-lego             	0.3.1        	           	Chart for nginx-ingress-controller and kube-lego  
stable/traefik                	1.24.1       	1.5.3      	A Traefik based Kubernetes ingress controller w...
stable/voyager                	3.1.0        	6.0.0-rc.0 	Voyager by AppsCode - Secure Ingress Controller...

選擇azure/nginx-ingress來安裝,注意是有版本的。安裝如下:

$ helm install pkslow-ingress azure/nginx-ingress

安裝成功後,控制台會有輸出相關的使用說明。但要注意的是,要去Kubernetes Dashboard查看一下是否真的安裝成功。我安裝遇到過失敗,原因都是因為鏡像下載失敗。解決方案是打開全局代理,先手動下載好相關鏡像。如:

us.gcr.io/k8s-artifacts-prod/ingress-nginx/controller:v0.34.1
k8s.gcr.io/defaultbackend-amd64:1.5
jettech/kube-webhook-certgen:v1.0.0
quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.32.0

之後就安裝成功了,相關的Pods都跑起來了。相關的Deployment有:

3 使用Ingress

3.1 訪問一個服務

一個最簡單的例子如下:

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

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

---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
    - http:
        paths:
          - path: /
            backend:
              serviceName: nginx-service
              servicePort: 80
      host: localhost

這樣配置後,當我們訪問//localhost/時,就會把我們的請求轉發到nginx-service80埠上去。如下所示:

3.2 訪問多個服務

當要訪問多個服務時,事情就變得複雜起來了。訪問多個服務,有兩種配置方式,一種是通過URL路徑匹配再轉發,另一種是通過子域名轉發。

3.2.1 子域名方式

通過子域名轉發如下配置:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
    - http:
        paths:
          - path: /
            backend:
              serviceName: nginx-service
              servicePort: 80
      host: nginx.localhost
    - http:
        paths:
          - path: /
            backend:
              serviceName: springboot-service
              servicePort: 8080
      host: springboot.localhost

為了節省篇幅,這裡就只展示Ingress的配置了。

訪問//nginx.localhost/如下:

訪問//springboot.localhost/swagger-ui.html如下,注意這個URL帶了子路徑swagger-ui.html

3.2.2 URL路徑匹配方式

那通過URL路徑匹配方式是不是這樣配置呢?

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
    - http:
        paths:
          - path: /nginx
            backend:
              serviceName: nginx-service
              servicePort: 80
      host: localhost
    - http:
        paths:
          - path: /springboot
            backend:
              serviceName: springboot-service
              servicePort: 8080
      host: localhost

這樣配置後,會直接報404,但不是Ingress404,而是NginxSpringboot404。說明請求已經成功轉發到對應的service了,但路徑有問題。原因是,當這樣配置時,Ingress會把path也轉發到service上。所以實際效果如下:

localhost/nginx      --> nginx-service/nginx
localhost/springboot --> springboot-service/springboot

所以服務的Web Context路徑要與配置的path匹配。比如nginx-service的基礎路徑就要改為/nginx,而不能是/了。

如果就想保持服務的Web Context路徑是/,那就需要配置rewrite規則,如nginx.ingress.kubernetes.io/rewrite-target: /$1

4 總結

過了一遍,坑真不少。使用子域名感覺是比較好的方式。另外,Ingress還有一個坑,它是實現HTTP/HTTPS轉發的,但TCP就不行了,比如我在Kubernetes安裝了一個MySQL資料庫,需要把地址和3306TCP方式暴露給外面,就比較麻煩了,我們後續再討論吧。


歡迎關注微信公眾號<南瓜慢說>,將持續為你更新…

多讀書,多分享;多寫作,多整理。

Tags: