使用 Kubernetes Ingress 对外暴露服务
本文主要介紹如何通過 Kubernetes Ingress 資源對象實(shí)現(xiàn)從外部對 k8s 集群中服務(wù)的訪問,介紹了 k8s 對外暴露服務(wù)的多種方法、Ingress 及 Ingress Controller 的概念。涉及到的話題有:
- k8s 對外暴露服務(wù)的方法;
- Ingress 及 Ingress Controller 簡介;
- helm 裸機(jī)部署 Nginx Ingress Controller;
- 使用 Ingress 對外暴露服務(wù);
- 通過 Ingress 訪問 kubernetes dashboard(支持 HTTPS 訪問);
k8s 對外暴露服務(wù)的方法
向 k8s 集群外部暴露服務(wù)的方式有三種: nodePort,LoadBalancer 和本文要介紹的 Ingress。每種方式都有各自的優(yōu)缺點(diǎn),nodePort 方式在服務(wù)變多的情況下會導(dǎo)致節(jié)點(diǎn)要開的端口越來越多,不好管理。而 LoadBalancer 更適合結(jié)合云提供商的 LB 來使用,但是在 LB 越來越多的情況下對成本的花費(fèi)也是不可小覷。Ingress 是 k8s 官方提供的用于對外暴露服務(wù)的方式,也是在生產(chǎn)環(huán)境用的比較多的方式,一般在云環(huán)境下是 LB + Ingress Ctroller 方式對外提供服務(wù),這樣就可以在一個(gè) LB 的情況下根據(jù)域名路由到對應(yīng)后端的 Service,有點(diǎn)類似于 Nginx 反向代理,只不過在 k8s 集群中,這個(gè)反向代理是集群外部流量的統(tǒng)一入口。
Ingress 及 Ingress Controller 簡介
Ingress 是 k8s 資源對象,用于對外暴露服務(wù),該資源對象定義了不同主機(jī)名(域名)及 URL 和對應(yīng)后端 Service(k8s Service)的綁定,根據(jù)不同的路徑路由 http 和 https 流量。而 Ingress Contoller 是一個(gè) pod 服務(wù),封裝了一個(gè) web 前端負(fù)載均衡器,同時(shí)在其基礎(chǔ)上實(shí)現(xiàn)了動態(tài)感知 Ingress 并根據(jù) Ingress 的定義動態(tài)生成 前端 web 負(fù)載均衡器的配置文件,比如 Nginx Ingress Controller 本質(zhì)上就是一個(gè) Nginx,只不過它能根據(jù) Ingress 資源的定義動態(tài)生成 Nginx 的配置文件,然后動態(tài) Reload。個(gè)人覺得 Ingress Controller 的重大作用是將前端負(fù)載均衡器和 Kubernetes 完美地結(jié)合了起來,一方面在云、容器平臺下方便配置的管理,另一方面實(shí)現(xiàn)了集群統(tǒng)一的流量入口,而不是像 nodePort 那樣給集群打多個(gè)孔。
所以,總的來說要使用 Ingress,得先部署 Ingress Controller 實(shí)體(相當(dāng)于前端 Nginx),然后再創(chuàng)建 Ingress (相當(dāng)于 Nginx 配置的 k8s 資源體現(xiàn)),Ingress Controller 部署好后會動態(tài)檢測 Ingress 的創(chuàng)建情況生成相應(yīng)配置。Ingress Controller 的實(shí)現(xiàn)有很多種:有基于 Nginx 的,也有基于 HAProxy的,還有基于 OpenResty 的 Kong Ingress Controller 等,更多 Controller 見:https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/,本文使用基于 Nginx 的 Ingress Controller:ingress-nginx。
helm 裸機(jī)部署 Nginx Ingress Controller
基于 Nginx 的 Ingress Controller 有兩種,一種是 k8s 社區(qū)提供的 ingress-nginx,另一種是 Nginx 社區(qū)提供的 kubernetes-igress,關(guān)于兩者的區(qū)別見 這里。
在這里我們部署 k8s 社區(qū)提供的 ingress-nginx,Ingress Controller 對外暴露方式采用 hostNetwork,在裸機(jī)環(huán)境下更多其他暴露方式見:https://kubernetes.github.io/ingress-nginx/deploy/baremetal/
使用 Helm 官方提供的 Chart stable/nginx-ingress,修改 values 文件:
- 使用 DaemonSet 控制器,默認(rèn)是 Deployment:controller.kind 設(shè)為 DaemonSet;
- pod 使用主機(jī)網(wǎng)絡(luò):controller.hostNetwork 設(shè)為 true;
- 在hostNetwork 下 pod 使用集群提供 dns 服務(wù):controller.dnsPolicy 設(shè)為 ClusterFirstWithHostNet;
- Service 類型設(shè)為 ClusterIP,默認(rèn)是 LoadBalancer:controller.service.type 設(shè)為 ClusterIP;
- 默認(rèn)后端鏡像使用 docker hub 提供的鏡像,Google 國內(nèi)無法訪問;
修改后的 values 文件:https://raw.githubusercontent.com/qhh0205/helm-charts/master/nginx-ingress-values.yml
helm 部署
驗(yàn)證部署是否成功
[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瀏覽器訪問節(jié)點(diǎn) ip 出現(xiàn):default backend - 404 頁面,部署成功。
至此 Nginx Ingress Controller 已部署完成,接下來講解如何通過 Ingress 結(jié)合 Ingress Controller 實(shí)現(xiàn)集群服務(wù)對外訪問。
使用 Ingress 對外暴露服務(wù)
為了快速體驗(yàn) Ingress,下面部署一個(gè) nginx 服務(wù),然后通過 Ingress 對外暴露 nginx service 進(jìn)行訪問。
首先部署 nginx 服務(wù):
Deployment + Service:nginx.yml
kubectl create -f nginx.yml
接下來創(chuàng)建 Ingress 對外暴露 nginx service 80 端口:
ingress.yml:
說明:
- kubernetes.io/ingress.class: "nginx":Nginx Ingress Controller 根據(jù)該注解自動發(fā)現(xiàn) Ingress;
- host: nginx.kube.com:對外訪問的域名;
- serviceName: nginx:對外暴露的 Service 名稱;
- servicePort: 80:nginx service 監(jiān)聽的端口;
注意:創(chuàng)建的 Ingress 必須要和對外暴露的 Service 在同一命名空間下!
將域名 nginx.kube.com 綁定到 k8s 任意節(jié)點(diǎn) ip 即可訪問:http://nginx.kube.com
上面的示例不支持 https 訪問,下面舉一個(gè)支持 https 的 Ingress 例子:通過 Ingress 訪問 kubernetes dashboard 服務(wù)。
通過 Ingress 訪問 kubernetes dashboard(支持 HTTPS 訪問)
之前我們使用 helm 以 nodePort 的方式部署了 kubernetes dashboard:「helm 部署 kubernetes-dashboard」,從集群外部只能通過 nodeIP:nodePort 端口號 訪問,接下來基于之前部署的 kubernetes-dashboard 配置如何通過 Ingress 訪問,并且支持 HTTPS 訪問,HTTP 自動跳轉(zhuǎn)到 HTTPS。 :
首先,練習(xí)使用,先用自簽名證書來代替吧:
使用生成的證書創(chuàng)建 k8s Secret 資源,下一步創(chuàng)建的 Ingress 會引用這個(gè) Secret:
kubectl create secret tls kube-dasboard-ssl --key kube-dashboard.key --cert kube-dashboard.crt -n kube-system創(chuàng)建 Ingress 資源對象(支持 HTTPS 訪問):
kube-dashboard-ingress.yml
kubectl create -f kube-dashboard-ingress.yml -n kube-system
說明:
- kubernetes.io/ingress.class: "nginx":Inginx Ingress Controller 根據(jù)該注解自動發(fā)現(xiàn) Ingress;
- nginx.ingress.kubernetes.io/backend-protocol: Controller 向后端 Service 轉(zhuǎn)發(fā)時(shí)使用 HTTPS 協(xié)議,這個(gè)注解必須添加,否則訪問會報(bào)錯(cuò),可以看到 Ingress Controller 報(bào)錯(cuò)日志: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”
報(bào)錯(cuò)原因主要是 dashboard 服務(wù)后端只支持 https,但是 Ingress Controller 接到客戶端的請求時(shí)往后端 dashboard 服務(wù)轉(zhuǎn)發(fā)時(shí)使用的是 http 協(xié)議,解決辦法就是給 創(chuàng)建的 Ingress 設(shè)置: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 監(jiān)聽的端口;
注意:創(chuàng)建的 Ingress 必須要和對外暴露的 Service 在同一命名空間下!
將域名 dashboard.kube.com 綁定到 k8s 任意節(jié)點(diǎn) ip 即可訪問:https://dashboard.kube.com
相關(guān)文檔
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 社區(qū)提供
https://github.com/kubernetes/ingress-nginx | Inginx Ingress Controller:k8s 社區(qū)提供
https://github.com/nginxinc/kubernetes-ingress/blob/master/docs/nginx-ingress-controllers.md | 兩種基于 nginx 的 Ingress Controller 區(qū)別
https://kubernetes.github.io/ingress-nginx/deploy/ | Inginx Ingress Controller k8s 社區(qū)版安裝文檔
https://kubernetes.github.io/ingress-nginx/deploy/baremetal/ | 在 裸機(jī)環(huán)境下 Inginx Ingress Controller 對外暴露方案
總結(jié)
以上是生活随笔為你收集整理的使用 Kubernetes Ingress 对外暴露服务的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 3D人物建模到底需要掌握哪些技术,大佬年
- 下一篇: 转载-高仙机器人落地北京杭州深圳多个城市