1. 程式人生 > >Kubernetes用Helm安裝Ingress並踩一下使用的坑

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

# 1 前言 > 歡迎訪問[南瓜慢說 www.pkslow.com](https://www.pkslow.com/)獲取更多精彩文章! `Ingress`是`Kubernetes`一個非常重要的`Controller`,它類似一個路由轉發的元件,可以讓外界訪問`Kubernetes`內部的`Service`。除了`Ingress`,還有`NodePort`、`LoadBalance`等方式,`Ingress`暴露給外界的方式還是很常用的。 # 2 安裝Ingress 我們通過`helm`來安裝,會方便一些,先更新`helm`的倉庫。 ```bash $ helm repo update ``` `Helm`相關文章:[用Helm部署Kubernetes應用,支援多環境部署與版本回滾](https://www.pkslow.com/archives/kubernetes-helm) [容器技術相關文章](https://www.pkslow.com/categories/container) 更新完之後,查詢倉庫關於`Ingress`的包有哪些: ```bash $ $ 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`來安裝,注意是有版本的。安裝如下: ```bash $ helm install pkslow-ingress azure/nginx-ingress ``` 安裝成功後,控制檯會有輸出相關的使用說明。但要注意的是,要去`Kubernetes Dashboard`檢視一下是否真的安裝成功。我安裝遇到過失敗,原因都是因為映象下載失敗。解決方案是開啟全域性`代理`,先手動下載好相關映象。如: ```bash 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`有: ![](https://img2020.cnblogs.com/other/946674/202008/946674-20200811160558037-1497468939.png) # 3 使用Ingress ## 3.1 訪問一個服務 一個最簡單的例子如下: ```yaml 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 ``` 這樣配置後,當我們訪問`http://localhost/`時,就會把我們的請求轉發到`nginx-service`的`80`埠上去。如下所示: ![](https://img2020.cnblogs.com/other/946674/202008/946674-20200811160558794-372006019.png) ## 3.2 訪問多個服務 當要訪問多個服務時,事情就變得複雜起來了。訪問多個服務,有兩種配置方式,一種是通過`URL`路徑匹配再轉發,另一種是通過`子域名`轉發。 ### 3.2.1 子域名方式 通過子域名轉發如下配置: ```yaml 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`的配置了。 訪問`http://nginx.localhost/`如下: ![](https://img2020.cnblogs.com/other/946674/202008/946674-20200811160559887-1629821135.png) 訪問`http://springboot.localhost/swagger-ui.html`如下,注意這個`URL`帶了子路徑`swagger-ui.html`: ![](https://img2020.cnblogs.com/other/946674/202008/946674-20200811160600842-675402546.png) ### 3.2.2 URL路徑匹配方式 那通過`URL`路徑匹配方式是不是這樣配置呢? ```yaml 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`,但不是`Ingress`的`404`,而是`Nginx`或`Springboot`的`404`。說明請求已經成功轉發到對應的`service`了,但路徑有問題。原因是,當這樣配置時,`Ingress`會把`path`也轉發到`service`上。所以實際效果如下: ```bash 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`資料庫,需要把地址和`3306`以`TCP`方式暴露給外面,就比較麻煩了,我們後續再討論吧。 --- 歡迎關注微信公眾號<**南瓜慢說**>,將持續為你更新... ![](https://img2020.cnblogs.com/other/946674/202008/946674-20200811160601414-1724443234.png) **多讀書,多分享;多寫作,多整理