目录
1:下载井安装 helm(已有 helm 环境可忽略此步骤)
2:下载井修改 Ingress controller 参数(已有离线包可忽略此步骤)
(1)将controller 的registry 仓库地址修改为国内的
(3)将 admissionwebhook 的镜像地址修改为国内的
(5)dnsPolicy设置为ClusterFirstWithHostNet
(6)nodeselector添加ingress:“true”
(1)给需要部署Ingress controller 的节点打标签
四:Ingress Nginx实现域名重定向 Redirect
五:Ingress Nginx实现前后端分离 Rewrite
3:查看该 service 的地址,并通过/api-a访问测试
5:创建该 ingress
一:基本概念
service 的作用体现在两个方面,对集群内部,它不断跟踪 pod的变化,更新 endpoint(端点)中对应 pod 的对象,提供了 ip 不断变化的 pod 的服务发现机制;对集群外部,他类似负载均衡器,可以在集群内外部对 pod 进行访问。
在 Kubernetes 中,Pod 的 IP 地址和 service 的 ClusterIp 仅可以在集群网络内部使用,对于集群外的应用是不可见的。为了使外部的应用能够访问集群内的服务,Kubernetes 目前提供了以下几种方案:
NodePort:将 service 暴露在节点网络上,NodePort 背后就是 Kube-Proxy,Kube-Proxy 是沟通service 网络、Pod 网络和节点网络的桥梁。测试环境使用还行,当有几十上百的服务在集群中运行时,NodePort 的端口管理就是个灾难。因为每个端口只能是一种服务,端口范围只能是30000-32767。
LoadBalancer:通过设置 LoadBalancer 映射到云服务商提供的 LoadBalancer 地址。这种用法仅用于在公有云服务提供商的云平台上设置 Service 的场景。受限于云平台,且通常在云平台部署LoadBalancer 还需要额外的费用。在 service 提交后,Kubernetes 就会调用 cloudProvider 在公有云上为你创建一个负载均衡服务,并且把被代理的 Pod 的 IP 地址配置给负载均衡服务做后端。
externalIPs:service 允许为其分配外部 IP,如果外部 IP 路由到集群中一个或多个 Node 上,Service 会被暴露给这些 externalIPs。通过外部 IP 进入到集群的流量,将会被路由到 Service 的Endpoint上。
Ingress:只需一个或者少量的公网 IP 和 LB,即可同时将多个 HTTP 服务暴露到外网,实现七层反向代理。可以简单理解为 service的 service,它其实就是一组基于域名和 URL 路径,把用户的请求转发到一个或多个 service 的规则。
注意:
目前比较流行的Ingresscontroller 有ingress-nginx(由 Kubemetes 官方维护)nginx-ingress(由 Nginx 官方维护,注意和 Ingress-nginx 的区别)、Traefik、Istio 等。
1:Ingress 组成
特性 | Ingress | Ingress Controller |
---|---|---|
定义 | Kubernetes API 对象,通过 YAML 文件配置 | 具体实现反向代理和负载均衡的程序 |
作用 | 定义请求转发到 Service 的规则(如域名、URL 路径等) | 解析 Ingress 规则,并实际处理请求转发 |
实现方式 | 声明式配置(YAML) | 以 Pod 形式运行,包含反向代理(如 Nginx)和监控集群变化的守护进程 |
功能 | 提供外部 URL、负载均衡、SSL/TLS 终止、基于域名的路由等 | 动态生成代理配置(如 Nginx 配置),更新 Upstream,并重载应用新配置 |
是否内置 | 是 Kubernetes 原生 API 对象 | 非 Kubernetes 自带组件,需单独部署(如 Nginx、Traefik、AWS ALB 等) |
常见实现 | 无具体实现,依赖 Ingress Controller | - Kubernetes 官方维护:ingress-nginx、GCE - 第三方:Traefik、HAProxy、Istio Gateway |
配置更新机制 | 用户通过 kubectl apply 更新 Ingress 资源 | 自动监控集群变化,动态调整代理规则 |
暴露方式 | 不直接暴露,需通过 Ingress Controller 接入外部流量 | 需通过 Service(如 LoadBalancer 或 NodePort)或 HostNetwork 暴露到集群入口 |
适用场景 | 声明式定义路由规则,支持多域名、路径匹配、TLS 等复杂路由需求 | 实际处理流量,支持高性能代理、自定义扩展(如鉴权、限流) |
2:Ingress工作过程
用户访问一个业务的流程如下:
(1)用户在浏览器中输入域名
(2)域名解析至业务的入口 IP(一般为外部负载均衡器,比如阿里的 SLB 或者 DMZ 的网关)。
(3)外部负载均衡器反向代理至 kubernetes 的入口(一般为 Ingress,或者通过 NodePort 暴露的服务等)。
(4)Ingress 根据自身的配置找到对应的 Service,再代理到对应的 Service 上。
(5)最后到达 Service 对应的某一个 Pod 上。
可见,在一般情况下,Ingress 主要是一个用户 kubernetes 集群业务的入口。是业务能够正常提供服务的核心,所以在生产环境中,推荐使用单独的服务器作为Ingress controller。controller 可以使用 Traefik、Istio、Nginx、HaProxy 等作为 Ingress controller。因为相对于其他 IngressController,管理人员更熟悉 Nginx 或者 HaProxy 等服务,所以本章主要讲解 Ingress Nginx 的安装与常用配置,这也是 kubernetes 官方提供的 Ingress controller。
3:Ingress 工作原理
(1)ingress-controller 通过和 kubernetes APIServer 交互,动态的去感知集群中 ingress 规则
变化,
(2)然后读取它,按照自定义的规则,规则就是写明了哪个域名对应哪个 service,生成一段 nginx 配置,
(3)再写到nginx-ingress-controller 的pod 里,这个 ingress-controller 的 pod 里运行着一个Nginx 服务,控制器会把生成的 nginx 配置写入 /etc/nginx.conf 文件中,
(4)然后reload 一下使配置生效。以此达到域名区分配置和动态更新的作用。
二:安装Ingress Nginx Controller
由于 Ingress Controller 相当于 kubernetes 集群中服务的“大门”因此在生产环境中,一定要保障Controller 的稳定性和可用性。为了提高 Ingress Controller 的可用性,我们-般采用单独的服务器作为Controller 节点,以此保障 Ingress controller 的 Pod 资源不会被其他服务的 Pod 影响。
Ingress Nginx 官方提供了多种部署方式,本节课将采用 Helm 的方式进行安装,并且将 IngressController 安装在 k8s-node01 节点。
1:下载井安装 helm(已有 helm 环境可忽略此步骤)
[root@k8s-master ~]# wget https://get.helm.sh/helm-v3.9.4-linux-amd64.tar.gz
[root@k8s-master ~]# tar zxvf helm-v3.9.4-linux-amd64.tar.gz
[root@k8s-master ~]# mv linux-amd64/helm /usr/local/bin/
2:下载井修改 Ingress controller 参数(已有离线包可忽略此步骤)
[root@k8s-master ~]# helm repo \
add ingress-nginx https://kubernetes.github.io/ingress-nginx
"ingress-nginx" has been added to your repositories
[root@k8s-master ~]# helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "ingress-nginx" chart repository
Update complete. Happy Helming!
[root@k8s-master ~]# helm pull ingress-nginx/ingress-nginx --version 4.7.1
[root@k8s-master ~]# tar xvf ingress-nginx-4.7.1.tgz
[root@k8s-master ~]# vim ingress-nginx/values.yaml
(1)将controller 的registry 仓库地址修改为国内的
此处要注意注释掉这里的摘要信息。
(2)修改opentelemetry 镜像地址
(3)将 admissionwebhook 的镜像地址修改为国内的
(4)修改hostNetwork 的值为 true
设置为 true 时,该 Pod 将与其所在节点共享网络命名空间。
(5)dnsPolicy设置为ClusterFirstWithHostNet
kubernetes 可以在 pod 级别通过 dnspolicy 字段设置 DNS 策略。目前支持的 DNS 策略如下:
Default: 继承 pod 所在宿主机的域名解析设置。
ClusterFirst: 将优先使用 kubernetes 环境的 dns 服务(如 coreDNS 提供的域名解析服务),将无法解析的域名转发到系统配置的上游 DNS 服务器:
ClusterFirstWithHostNet:适用与以 hostNetwork 模式运行的 pod
None: 忽略集群的 DNS 配置,需要手工通过 dnsConfig 自定义 DNS 配置。这个选项在 1.9 版本中开始引入,到 1.10 版本时升级为 Beta,到 1.14 版本时达到稳定版本。
(6)nodeselector添加ingress:“true”
此配置能够将 ingress 安装在带有“ingress:true”标签的节点上。
(7)修改kind类型为 Deamonset
kind:DeamonSet
注意:
如果已经下载好了离线的 helm 和 ingress-nginx,可以直接解压并安装,不必下载。
3:部署ingress
(1)给需要部署Ingress controller 的节点打标签
(2)创建namespace
(3)安装ingress-nginx
#安装
注意最后有一个点
#卸载(不必要)
helm uninstall ingress-nginx -n ingress-nginx
#查看安装信息
三:Ingress Nginx 使用入门
首先从最简单的配置开始,假如公司有一个web 服务的容器,需要为其添加一个域名,此时可以使用Ingerss 实现该功能。
1:创建一个用于学习的 namespace
2:创建一个 nginx 作为 web 服务
3:创建一个该 web 容器的 service
4:创建 ingress 指向上-步中的 service
路径类型 | 匹配规则 | 示例 | 注意事项 |
---|---|---|---|
ImplementationSpecific | 匹配方式由 Ingress Controller 决定,可能等同于 Prefix 或 Exact | 取决于 IngressClass 的实现 | 不同 Ingress Controller(如 Nginx、Traefik)可能有不同的默认行为 |
Exact | 精确匹配 URL 路径,区分大小写 | /api/v1 仅匹配 /api/v1 ,不匹配 /api/v1/ 或 /api/v1/data | 适用于严格路径匹配,如 REST API 的固定端点 |
Prefix | 前缀匹配,按 / 分割的路径元素匹配,区分大小写 | /api/ 匹配 /api/v1 、/api/data ,但不匹配 /apis 或 /api/v1extra | 最后一个元素必须是完整子路径(如 /foo/bar 不匹配 /foo/barbar ) |
5:创建该 ingress
注意:
不要删除此 ingress,否则,后面的 ssl无法访问
6:客户端访问测试
创建的 Ingress 绑定的域名为 nginx.test.com,由于本书的 Ingresscontroller 是以hostNetwork 模式部署的,因此将域名解析至 Ingresscontroller 所在的节点即可。如果Ingresscontroller 上层还有一层网关,解析至网关 IP 即可。接下来通过域名 nginx.test.com 即可访问 web 服务器。
可以看到通过上述简单的 Ingress 资源定义就可以实现以域名的方式访问服务,不需要再去维护复杂的 Ngmx 配置文件,大大降低了运维的复杂度和出错的频率。
接下来通过一些其他配置实现企业内常用的功能,比如重定向、前后端分离、错误友好页面等。
四:Ingress Nginx实现域名重定向 Redirect
当一个服务需要更换域名时,并不能对其直接更改,需要一个过渡的过程。在这个过程中,需要将旧域名的访问跳转到新域名,此时可以使用 Redirect 功能。待旧域名无访问时,再停止旧域名。
在 Nginx作为代理服务器时,Redirect可用于域名的重定向,比如访问 old.com被重定向到new.com.Ingress 可以更简单地实现 Redirect 功能。接下来用 nginx.redirect.com 作为旧域名,baidu.com作为新域名进行演示。
1:编辑 Ingress 文件
2:创建 Ingress
3:测试
在客户端的 hosts 文件添加域名 nginx,redirect.com,IP 地址为 k8s-node01 节点的 IP 地址。
使用域名 nginx.redirect.com 访问网站,打开的是 baidu,com,说明跳转成功。
五:Ingress Nginx实现前后端分离 Rewrite
现在大部分应用都是前后端分离的架构,也就是前端用某个域名的根路径进行访问,后端接口采用/api 进行访问,用来区分前端和后端。或者同时具有很多个后端,需要使用/api-a到A服务,/api-b到B服务,但是由于A和B服务可能并没有/api-a和/api-b的路径,因此需要将/api-x重写为“/”,才可以正常到A或者B服务,否则将会出现 404的报错。此时可以通过 Rewrite 功能达到这种效果。
1:创建一个应用模拟后端服务
2:创建 service 暴露应用
[root@k8s-master ~]# kubectl expose deployment backend-api --port 80 -n study-ingress
3:查看该 service 的地址,并通过/api-a访问测试
4:编辑ingress,实现 rewrite
配置项 | 作用 | 示例 | 说明 | |
---|---|---|---|---|
nginx.ingress.kubernetes.io/rewrite-target | 重写请求路径,将匹配的路径部分替换为指定值 | rewrite-target: /$2 | 将匹配的第二个捕获组 ((.*) ) 作为新路径转发到后端服务 | |
path 正则表达式 | 定义路径匹配规则,支持正则表达式捕获组 | `path: /api-a(/ | $)(.*)` | 匹配 /api-a 或 /api-a/ 开头的路径,并捕获后续子路径((.*) ) |
捕获组引用 ($1 , $2 ) | 在 rewrite-target 中引用正则表达式捕获的内容 | rewrite-target: /$2 | $2 表示第二个捕获组(即 (.*) 匹配的部分) |
5:创建该 ingress
6:访问测试
六:Ingress Nginx 实现 SSL 配置
生产环境对外的服务一般需要配置 HTTPS 协议,使用 Ingress 也可以非常方便地添加 HTTPS 的证书”。由于是学习环境,并没有权威证书,因此需要使用 0penssL 生成一个测试证书(如果是生产环境,那么证书为在第三方公司购买的证书,无须自行生成)。
1:生成证书
参数 | 作用 | 示例 | 注意事项 |
---|---|---|---|
req | OpenSSL 子命令,用于创建证书请求(CSR)或自签名证书 | openssl req | 必须作为主命令使用 |
-x509 | 直接生成自签名证书(而非证书请求 CSR) | -x509 | 适用于测试或内部环境,生产环境建议使用 CA 签发的证书 |
-nodes | 不加密私钥(即无密码保护) | -nodes | 方便自动化处理,但安全性较低,生产环境建议加密私钥(去除此选项) |
-days | 设置证书有效期(天) | -days 365 | 过期后需重新生成,生产环境建议根据安全策略调整(如 90 天) |
-newkey | 生成新密钥对并指定算法和长度 | -newkey rsa:2048 | RSA 2048 是当前最低安全标准,更高安全性可用 rsa:4096 或 ecdsa |
-keyout | 指定私钥输出文件名 | -keyout tls.key | 需妥善保管私钥,避免泄露 |
-out | 指定证书输出文件名 | -out tls.crt | 证书文件(.crt 或 .pem )需与私钥配对使用 |
-subj | 设置证书主题(Subject),简化交互式输入 | -subj "/CN=nginx.test.com" | 可扩展其他字段(如 /O=公司名/C=国家 ),但 CN(Common Name)必须与域名匹配 |
2:创建证书的 secret
3:编辑 ingress
4:创建此 ingress
5:访问测试
七:Ingress Nginx实现基本认证
有些网站可能需要通过密码来访问,对于这类网站可以使用 nginx 的 basic-auth 设置密码访问,具体方法如下,由于需要使用 htpasswd 工具,因此需要安装 httpd。
1:安装 httpd
2:使用 htpasswd 创建用户
3:基于之前创建的密码文件创建 secret
4:编辑 ingress,包含密码认证
注解(Annotation) | 作用 | 示例值 | 注意事项 |
---|---|---|---|
nginx.ingress.kubernetes.io/auth-type | 指定认证类型为 Basic Auth | basic | 仅支持 basic (HTTP 基础认证) |
nginx.ingress.kubernetes.io/auth-secret | 指定存储用户名和密码的 Kubernetes Secret 名称 | auth-secret | Secret 需通过 htpasswd 生成,且必须包含 auth 键值对 |
host | 定义客户端访问的域名(需与 Ingress 规则匹配) | auth.test.com | 需确保域名解析正确,且与其他 Ingress 规则无冲突 |
5:部署此 ingress
6:访问测试
在客户端添加域名 auth.test.com 的解析