《Service 服务》系列,共包含以下文章:
- Service 概念与实战
- Service 类型:NodePort、ClusterlP、LoadBalancer、ExternalName
- 虚拟 IP 与 Service 的代理模式
- 集群外部的请求访问集群内应用的最佳方式:Ingress
😊 如果您觉得这篇文章有用 ✔️ 的话,请给博主一个一键三连 🚀🚀🚀 吧 (点赞 🧡、关注 💛、收藏 💚)!!!您的支持 💖💖💖 将激励 🔥 博主输出更多优质内容!!!
集群外部的请求访问集群内应用的最佳方式:Ingress
- 1.Ingress 是什么
- 2.使用 Ingress Controller 创建 Ingress
- 3.Ingress 注解
- 4.基于 Ingress 的高可用架构
Kubernetes 通过 Service 为 Pod 提供了统一的入口地址,并使用 NodePort 和 LoadBalance 类型的 Service 让 外部的请求 可以访问 集群内部的应用。
但是,使用 NodePort 和 LoadBalance 类型有以下缺点:
- NodePort 类型通过在每个节点上暴露一个端口作为外部访问的入口,因此当 Service 很多时,这种方式会占用集群的大量端口。
- LoadBalance 类型需要为每一个 Service 都定义一个负载均衡器,会浪费资源。
因此,Kubernetes 提供了 Ingress 域名访问应用 的方式,这也是从集群外部访问集群内应用的最佳方式。
1.Ingress 是什么
Ingress 的本质是,定义了一组从域名(或 URL)到 Service 的路由转发规则。Ingress 不会公开端口信息和所使用的协议,而是通过配置 HTTP 或 HTTPS 的路由规则,来实现从集群外部访问集群内应用的 URL 并实现负载均衡功能。
要创建和配置 Ingress 路由转发规则,则需要使用 Ingress Controller。它可以由任何具有 反向代理 功能的应用(如 Nginx 和 Haproxy)来实现。
Ingress 的工作机制如下图所示。
2.使用 Ingress Controller 创建 Ingress
下面来演示如何使用 Ingress Controller 创建 Ingress,从而实现从集群外部访问集群内部的应用。首先部署 Ingress Controller,再部署应用服务,最后创建 Ingress 的路由规则从集群外部访问集群内部的应用。
在 GitHub 上搜索 kubernetes/ingress-nginx
。🚀 https://github.com/kubernetes/ingress-nginx
🚀
ingress-nginx
is an Ingress controller for Kubernetes using NGINX as a reverse proxy and load balancer.
安装 NGINX Ingress Controller(使用 ingress-nginx
项目的官方清单)。
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.3/deploy/static/provider/baremetal/deploy.yaml
输出的信息如下:
检查 Ingress Controller Pod 是否已启动。
kubectl get pods -n ingress-nginx -o wide
检查是否能看到 NodePort 服务。
kubectl get services -n ingress-nginx
从 Ingress-NGINX 控制器 v1.0.0
版本开始,需要一个 ingressclass
对象。在默认安装中,已经创建了一个名为 nginx
的 ingressclass
对象。
kubectl get ingressclasses -n ingress-nginx
如果这只是 Ingresss-NGINX 控制器的实例,您应该在入口类中添加注释 ingressclass.kubernetes.io/is-default-class
。
kubectl annotate ingressclasses nginx ingressclass.kubernetes.io/is-default-class="true" -n ingress-nginx
🚀 在集群中,我们可以设定一个默认的 IngressClass,以便处理所有没有指定 IngressClass 的 Ingress 资源。通过将
ingressclass.kubernetes.io/is-default-class
注解的值设定为true
,来使没有设置 ingressClassName 的 Ingress 使用此默认的 IngressClass。 修改后必须新创建的 Ingress 才会默认使用。
尝试使用上一步中的 NodePort 连接 Ingress 控制器。
curl 10.107.109.133
如果您尚未配置任何后端服务,您应该会看到来自 Nginx 的 404 Not Found
。现在这样就可以了。
如果您看到 Nginx 的响应,则表明 Ingress Controller 正在运行并且您可以访问它。
部署一个小型测试应用程序(httpd
Web 服务器)来验证您的 Ingress 控制器。
创建以下 YAML 文件并将其命名为 simple-web-server-with-ingress.yaml
。
apiVersion: v1
kind: Namespace
metadata:name: web
---
apiVersion: apps/v1
kind: Deployment
metadata:name: web-servernamespace: web
spec:selector:matchLabels:app: webtemplate:metadata:labels:app: webspec:containers:- name: httpdimage: httpd:2.4.53-alpineports:- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:name: web-server-servicenamespace: web
spec:selector:app: webports:- protocol: TCPport: 5000targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: web-server-ingressnamespace: web
spec:ingressClassName: nginxrules:- host: web.example.comhttp:paths:- path: /pathType: Prefixbackend:service:name: web-server-serviceport:number: 5000
部署应用程序:
kubectl apply -f simple-web-server-with-ingress.yaml
查看 Pod、Deployment、Service 和 Endpoint 的信息。
kubectl get pod,deploy,svc,ep -n web -o wide
查看创建的 Ingress。
kubectl get ingress -n web
验证您是否可以使用 NodePort 访问您的应用程序。
curl 10.107.109.133 -H 'Host: web.example.com'
如果成功,您应该看到 <html><body><h1>It Works!</h1></body></html>
。
编辑 hosts
文件加入 IP 地址与域名的对应关系,如下:
10.107.109.133 web.example.com
通过域名访问应用,如下图所示。
3.Ingress 注解
有时默认的配置并不一定能满足实际的需求,这时可以通过修改 Ingress 的 注解(annotations
)来实现对特定参数的配置。在每次修改 Ingress 注解后,Ingress Controller 会立即加载新的配置。
下面是官方提供的一个示例。该示例将完成文件上传功能。但默认情况下上传的请求大小是 1 MB,修改注解可以改变请求的大小限制。例如,下面将请求的大小设置为 2 MB。
apiVersion: extensions/v1beta1
kind: Ingress
metadata:name: openbayes-server-ingannotations:nginx.ingress.kubernetes.io/proxy-body-size: "2048"nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:rules:- http:paths:- path: /apibackend:serviceName: openbayes-server-svcservicePort: 80
下表为常用的 Ingress 注解。
| |
---|---|
nginx.ingress.kubernetes.io/app-root | 定义应用根目录 |
nginx.ingress.kubernetes.io/rewrite-target | 执行 URL 重定向 |
nginx.ingress.kubernetes.io/use-regex | 开启路径正则匹配 |
nginx.ingress.kubernetes.io/affinity | 开启会话的粘连 |
nginx.ingress.kubernetes.io/ssl-redirect | 开启 HTTP 到 HTTPS 的跳转 |
nginx.ingress.kubernetes.io/force-ssl-redirect | 即使未启用 TLS 也会强制重定向到 HTTP |
4.基于 Ingress 的高可用架构
Ingress 的路由规则是由 Ingress Controller 创建和维护的,因此,Ingress Controller 的 高可用性 就显得非常重要了。如果在 Kubernetes 集群中只存在一个 Ingress Controller,则必然会造成 单点故障。为了解决这个问题,可以采用 Ingress Controller 的 多副本部署,并将其作为 DaemonSet 的守护进程在每个节点上启动一个。
为了最大限度地利用 Ingress 进行路由,建议可以将 Ingress Controller 以独占方式部署,这样可以避免业务应用与 Ingress 服务争用资源。
下图展示了基于 Ingress 的高可用架构,其中引入了 KeepAlived 以实现从公网域名到机房的公网 IP 地址服务器的路由解析。