使用 Kubernetes Ingress 对外暴露服务
本文主要介紹如何通過 Kubernetes Ingress 資源對象實現從外部對 k8s 集群中服務的訪問,介紹了 k8s 對外暴露服務的多種方法、Ingress 及 Ingress Controller 的概念。涉及到的話題有:
- k8s 對外暴露服務的方法;
- Ingress 及 Ingress Controller 簡介;
- helm 裸機部署 Nginx Ingress Controller;
- 使用 Ingress 對外暴露服務;
- 通過 Ingress 訪問 kubernetes dashboard(支持 HTTPS 訪問);
k8s 對外暴露服務的方法
向 k8s 集群外部暴露服務的方式有三種: nodePort,LoadBalancer 和本文要介紹的 Ingress。每種方式都有各自的優缺點,nodePort 方式在服務變多的情況下會導致節點要開的端口越來越多,不好管理。而 LoadBalancer 更適合結合云提供商的 LB 來使用,但是在 LB 越來越多的情況下對成本的花費也是不可小覷。Ingress 是 k8s 官方提供的用于對外暴露服務的方式,也是在生產環境用的比較多的方式,一般在云環境下是 LB + Ingress Ctroller 方式對外提供服務,這樣就可以在一個 LB 的情況下根據域名路由到對應后端的 Service,有點類似于 Nginx 反向代理,只不過在 k8s 集群中,這個反向代理是集群外部流量的統一入口。
Ingress 及 Ingress Controller 簡介
Ingress 是 k8s 資源對象,用于對外暴露服務,該資源對象定義了不同主機名(域名)及 URL 和對應后端 Service(k8s Service)的綁定,根據不同的路徑路由 http 和 https 流量。而 Ingress Contoller 是一個 pod 服務,封裝了一個 web 前端負載均衡器,同時在其基礎上實現了動態感知 Ingress 并根據 Ingress 的定義動態生成 前端 web 負載均衡器的配置文件,比如 Nginx Ingress Controller 本質上就是一個 Nginx,只不過它能根據 Ingress 資源的定義動態生成 Nginx 的配置文件,然后動態 Reload。個人覺得 Ingress Controller 的重大作用是將前端負載均衡器和 Kubernetes 完美地結合了起來,一方面在云、容器平臺下方便配置的管理,另一方面實現了集群統一的流量入口,而不是像 nodePort 那樣給集群打多個孔。
所以,總的來說要使用 Ingress,得先部署 Ingress Controller 實體(相當于前端 Nginx),然后再創建 Ingress (相當于 Nginx 配置的 k8s 資源體現),Ingress Controller 部署好后會動態檢測 Ingress 的創建情況生成相應配置。Ingress Controller 的實現有很多種:有基于 Nginx 的,也有基于 HAProxy的,還有基于 OpenResty 的 Kong Ingress Controller 等,更多 Controller 見:https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/,本文使用基于 Nginx 的 Ingress Controller:ingress-nginx。
helm 裸機部署 Nginx Ingress Controller
基于 Nginx 的 Ingress Controller 有兩種,一種是 k8s 社區提供的 ingress-nginx,另一種是 Nginx 社區提供的 kubernetes-igress,關于兩者的區別見 這里。
在這里我們部署 k8s 社區提供的 ingress-nginx,Ingress Controller 對外暴露方式采用 hostNetwork,在裸機環境下更多其他暴露方式見:https://kubernetes.github.io/ingress-nginx/deploy/baremetal/
使用 Helm 官方提供的 Chart stable/nginx-ingress,修改 values 文件:
- 使用 DaemonSet 控制器,默認是 Deployment:controller.kind 設為 DaemonSet;
- pod 使用主機網絡:controller.hostNetwork 設為 true;
- 在hostNetwork 下 pod 使用集群提供 dns 服務:controller.dnsPolicy 設為 ClusterFirstWithHostNet;
- Service 類型設為 ClusterIP,默認是 LoadBalancer:controller.service.type 設為 ClusterIP;
- 默認后端鏡像使用 docker hub 提供的鏡像,Google 國內無法訪問;
修改后的 values 文件:https://raw.githubusercontent.com/qhh0205/helm-charts/master/nginx-ingress-values.yml
helm 部署
驗證部署是否成功
[root@master ~]# kubectl get pod NAME READY STATUS RESTARTS AGE nginx-ingress-controller-mg8df 1/1 Running 2 2m14s nginx-ingress-default-backend-577857cd9c-gfsnd 1/1 Running 0 2m14s瀏覽器訪問節點 ip 出現:default backend - 404 頁面,部署成功。
至此 Nginx Ingress Controller 已部署完成,接下來講解如何通過 Ingress 結合 Ingress Controller 實現集群服務對外訪問。
使用 Ingress 對外暴露服務
為了快速體驗 Ingress,下面部署一個 nginx 服務,然后通過 Ingress 對外暴露 nginx service 進行訪問。
首先部署 nginx 服務:
Deployment + Service:nginx.yml
kubectl create -f nginx.yml
接下來創建 Ingress 對外暴露 nginx service 80 端口:
ingress.yml:
說明:
- kubernetes.io/ingress.class: "nginx":Nginx Ingress Controller 根據該注解自動發現 Ingress;
- host: nginx.kube.com:對外訪問的域名;
- serviceName: nginx:對外暴露的 Service 名稱;
- servicePort: 80:nginx service 監聽的端口;
注意:創建的 Ingress 必須要和對外暴露的 Service 在同一命名空間下!
將域名 nginx.kube.com 綁定到 k8s 任意節點 ip 即可訪問:http://nginx.kube.com
上面的示例不支持 https 訪問,下面舉一個支持 https 的 Ingress 例子:通過 Ingress 訪問 kubernetes dashboard 服務。
通過 Ingress 訪問 kubernetes dashboard(支持 HTTPS 訪問)
之前我們使用 helm 以 nodePort 的方式部署了 kubernetes dashboard:「helm 部署 kubernetes-dashboard」,從集群外部只能通過 nodeIP:nodePort 端口號 訪問,接下來基于之前部署的 kubernetes-dashboard 配置如何通過 Ingress 訪問,并且支持 HTTPS 訪問,HTTP 自動跳轉到 HTTPS。 :
首先,練習使用,先用自簽名證書來代替吧:
使用生成的證書創建 k8s Secret 資源,下一步創建的 Ingress 會引用這個 Secret:
kubectl create secret tls kube-dasboard-ssl --key kube-dashboard.key --cert kube-dashboard.crt -n kube-system創建 Ingress 資源對象(支持 HTTPS 訪問):
kube-dashboard-ingress.yml
kubectl create -f kube-dashboard-ingress.yml -n kube-system
說明:
- kubernetes.io/ingress.class: "nginx":Inginx Ingress Controller 根據該注解自動發現 Ingress;
- nginx.ingress.kubernetes.io/backend-protocol: Controller 向后端 Service 轉發時使用 HTTPS 協議,這個注解必須添加,否則訪問會報錯,可以看到 Ingress Controller 報錯日志:kubectl logs -f nginx-ingress-controller-mg8df
2019/08/12 06:40:00 [error] 557#557: *56049 upstream sent no valid HTTP/1.0 header while reading response header from upstream, client: 192.168.26.10, server: dashboard.kube.com, request: “GET / HTTP/1.1”, upstream: “http://10.244.1.8:8443/”, host: “dashboard.kube.com”
報錯原因主要是 dashboard 服務后端只支持 https,但是 Ingress Controller 接到客戶端的請求時往后端 dashboard 服務轉發時使用的是 http 協議,解決辦法就是給 創建的 Ingress 設置:nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" 注解。解決方法參考自 StackOverflow:https://stackoverflow.com/questions/48324760/ingress-configuration-for-dashboard
- secretName: kube-dasboard-ssl:https 證書 Secret;
- host: dashboard.kube.com:對外訪問的域名;
- serviceName: kubernetes-dashboard:集群對外暴露的 Service 名稱;
- servicePort: 443:service 監聽的端口;
注意:創建的 Ingress 必須要和對外暴露的 Service 在同一命名空間下!
將域名 dashboard.kube.com 綁定到 k8s 任意節點 ip 即可訪問:https://dashboard.kube.com
相關文檔
https://kubernetes.io/docs/concepts/services-networking/ingress/ | 官方文檔
https://mritd.me/2017/03/04/how-to-use-nginx-ingress/ | Kubernetes Nginx Ingress 教程
https://github.com/nginxinc/kubernetes-ingress | Inginx Ingress Controller:nginx 社區提供
https://github.com/kubernetes/ingress-nginx | Inginx Ingress Controller:k8s 社區提供
https://github.com/nginxinc/kubernetes-ingress/blob/master/docs/nginx-ingress-controllers.md | 兩種基于 nginx 的 Ingress Controller 區別
https://kubernetes.github.io/ingress-nginx/deploy/ | Inginx Ingress Controller k8s 社區版安裝文檔
https://kubernetes.github.io/ingress-nginx/deploy/baremetal/ | 在 裸機環境下 Inginx Ingress Controller 對外暴露方案
總結
以上是生活随笔為你收集整理的使用 Kubernetes Ingress 对外暴露服务的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 3D人物建模到底需要掌握哪些技术,大佬年
- 下一篇: 转载-高仙机器人落地北京杭州深圳多个城市