文章目录
- [Kubernetes Ingress](#Kubernetes Ingress)
-
- 环境准备
- [Ingress 介绍](#Ingress 介绍)
- [Ingress 控制器](#Ingress 控制器)
- [ingress-nginx 工作流程](#ingress-nginx 工作流程)
- [ingress-nginx 部署前提](#ingress-nginx 部署前提)
- [ingress-nginx 版本](#ingress-nginx 版本)
- [ingress-nginx 部署](#ingress-nginx 部署)
- [Ingress 规则实践](#Ingress 规则实践)
-
- [Ingress 规则说明](#Ingress 规则说明)
- [Ingress 规则实践](#Ingress 规则实践)
-
- 环境准备
-
- [站点 webapp01](#站点 webapp01)
- [站点 webapp02](#站点 webapp02)
- 一、基础通用规则
-
- [1. 多域名虚拟主机(多 host 路由)](#1. 多域名虚拟主机(多 host 路由))
- [2. 同一域名多路径路由(path 分流)](#2. 同一域名多路径路由(path 分流))
- 二、生产核心:路径重写
-
- [3. 路径裁剪(等价 Nginx `proxy_pass /`)](#3. 路径裁剪(等价 Nginx
proxy_pass /))
- [3. 路径裁剪(等价 Nginx `proxy_pass /`)](#3. 路径裁剪(等价 Nginx
- [三、HTTPS 强制 & TLS 证书](#三、HTTPS 强制 & TLS 证书)
-
- [4. 绑定 TLS 证书 + 强制 HTTPS](#4. 绑定 TLS 证书 + 强制 HTTPS)
- 四、限流、防刷、超时优化
-
- [5. 连接数限流、单IP限速](#5. 连接数限流、单IP限速)
- [6. 自定义超时时间](#6. 自定义超时时间)
- 五、跨域配置(前后端分离必备)
-
- [7. 全局跨域放行](#7. 全局跨域放行)
- [六、白名单访问控制(内网 / 后台系统)](#六、白名单访问控制(内网 / 后台系统))
-
- [8. 限制指定IP段访问](#8. 限制指定IP段访问)
- 七、静态资源缓存、请求头透传
-
- [9. 透传真实客户端IP](#9. 透传真实客户端IP)
- [10. 静态资源缓存优化](#10. 静态资源缓存优化)
- [八、灰度 / 权重分流(金丝雀发布)](#八、灰度 / 权重分流(金丝雀发布))
-
- [11. 权重流量拆分](#11. 权重流量拆分)
- 九、错误页面、自定义配置
-
- [12. 自定义后端错误页、关闭目录浏览](#12. 自定义后端错误页、关闭目录浏览)
- [十、生产高频注解 速查表](#十、生产高频注解 速查表)
- 环境清理
Kubernetes Ingress
学习参考:Ingress
环境准备
bash
root@master30:~# kubectl create ns ingress
root@master30:~# kubectl config set-context --current --namespace ingress
Ingress 介绍
Ingress 可为 Service 提供外部可访问的 URL、对其流量作负载均衡、 终止 SSL/TLS,以及基于名称的虚拟托管等能力。 Ingress 控制器 负责完成 Ingress 的工作,通常会使用某个负载均衡器、边缘路由器或其他前端来帮助处理流量。
下面是 Ingress 的一个简单示例,可将所有流量都发送到同一 Service:

Ingress 不会随意公开端口或协议, 将 HTTP 和 HTTPS 以外的服务开放到 Internet 时,通常使用 Service.Type=NodePort 或 Service.Type=LoadBalancer 类型的 Service。
Ingress 控制器
为了让 Ingress 资源工作,集群必须有一个正在运行的 Ingress 控制器。
与作为 kube-controller-manager 可执行文件的一部分运行的其他类型的控制器不同, Ingress 控制器不是随集群自动启动的。 基于此页面,你可选择最适合你的集群的 ingress 控制器实现。
Kubernetes 作为一个项目,目前支持和维护 AWS、 GCE 和 Nginx Ingress 控制器。
ingress-nginx 工作流程
本次实验使用 ingress-nginx 控制器。
项目地址:ingress-nginx。
ingress-nginx 工作流程:
- 先部署 Ingress Controller 实体(相当于前端--Nginx)
- 然后再创建 Ingress (k8s 资源--相当于 Nginx 配置)
- Ingress Controller 与 kubernetes apiserver交互,动态的获取集群中的ingress规则。解析ingress规则,生成proxy服务的配置,比如nginx配置。
- 再写到 ingress proxy 的pod中,如果pod运行的是nginx服务,就生成nginx配置,并放到/etc/nginx/nginx.conf中。
- 然后reload服务。
Ingress 本质是7层http/https代理。
ingress-nginx 部署前提
项目地址: kubernetes/ingress-nginx
- 本次环境使用负载均衡器处理流量,提前部署好 LoadBalancer,例如 metallb。
- 你必须部署一个 Ingress 控制器 才能满足 Ingress 的要求,例如 ingress-nginx。
ingress-nginx 版本
| Supported | Ingress-NGINX version | k8s supported version | Alpine Version | Nginx Version | Helm Chart Version |
|---|---|---|---|---|---|
| 🔄 | v1.11.2 | 1.30, 1.29, 1.28, 1.27, 1.26 | 3.20.0 | 1.25.5 | 4.11.2 |
| 🔄 | v1.11.1 | 1.30, 1.29, 1.28, 1.27, 1.26 | 3.20.0 | 1.25.5 | 4.11.1 |
| 🔄 | v1.11.0 | 1.30, 1.29, 1.28, 1.27, 1.26 | 3.20.0 | 1.25.5 | 4.11.0 |
| 🔄 | v1.10.2 | 1.30, 1.29, 1.28, 1.27, 1.26 | 3.20.0 | 1.25.5 | 4.10.2 |
| 🔄 | v1.10.1 | 1.30, 1.29, 1.28, 1.27, 1.26 | 3.19.1 | 1.25.3 | 4.10.1 |
| 🔄 | v1.10.0 | 1.29, 1.28, 1.27, 1.26 | 3.19.1 | 1.25.3 | 4.10.0 |
| ... |
ingress-nginx 部署
部署方法参考:https://kubernetes.github.io/ingress-nginx/deploy/
!important
需先部署 metallb,并配置地址池
bash
# 下载ingress-nginx控制器安装压缩包;wget从指定URL获取v1.11.2版本的部署资源归档文件
root@master30:~# wget https://cyw.cloud/class/course-materials/softwares/stage03/ingress-nginx-controller-v1.11.2.tar.gz
# 解压ingress控制器安装包;tar -xf解压指定压缩文件,释放部署相关YAML清单到当前目录
root@master30:~# tar -xf ingress-nginx-controller-v1.11.2.tar.gz
# 筛选部署文件中的镜像地址并去重;grep匹配image:字段提取所有镜像行,管道传递给uniq去除重复条目
root@master30:~# grep image: ingress-nginx-controller-v1.11.2/deploy/static/provider/cloud/deploy.yaml|uniq
image: registry.k8s.io/ingress-nginx/controller:v1.11.2@sha256:d5f8217feeac4887cb1ed21f27c2674e58be06bd8f5184cacea2a69abaf78dce # ingress控制器主程序镜像,附带sha256哈希摘要用于镜像完整性校验
image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.4.3@sha256:a320a50cc91bd15fd2d6fa6de58bd98c1bd64b9a6f926ce23a600d87043455a3 # webhook证书生成组件镜像,负责自动管理准入校验的证书生命周期
# 批量替换部署文件中的镜像地址;sed -ir原地修改文件并生成备份,执行两处替换:删除@sha256及后续摘要串,将官方仓库替换为私有仓库hub.cyw.cloud
root@master30:~# sed -ir 's#@sha256.*##;s/registry.k8s.io/hub.cyw.cloud/' ingress-nginx-controller-v1.11.2/deploy/static/provider/cloud/deploy.yaml
# 应用部署清单安装ingress-nginx控制器;kubectl apply从指定yaml文件创建所有关联资源,完成控制器集群部署
root@master30:~# kubectl apply -f ingress-nginx-controller-v1.11.2/deploy/static/provider/cloud/deploy.yaml
ingress-nginx 部署文件 deploy.yaml文件包涵4个部分:
- 创建一个独立的命名空间 ingress-nginx
- 创建 ConfigMap
ConfigMap是存储通用的配置变量的,类似于配置文件,使用户可以将分布式系统中用于不同模块的环境变量统一到一个对象中管理;而它与配置文件的区别在于它是存在集群的"环境"中的,并且支持K8S集群中所有通用的操作调用方式。
创建pod时,对configmap进行绑定,pod内的应用可以直接引用ConfigMap的配置。相当于configmap为应用/运行环境封装配置。
pod使用ConfigMap,通常用于:设置环境变量的值、设置命令行参数、创建配置文件。
- Ingress的RBAC授权的控制,其创建了Ingress用到的ServiceAccount、ClusterRole、Role、RoleBinding、ClusterRoleBinding
- 创建ingress-controller。前面提到过,ingress-controller的作用是将新加入的Ingress进行转化为httpd的配置
查看部署的资源
bash
# 查看ingress-nginx命名空间下所有核心资源运行状态;-n指定目标命名空间,get all批量列出工作负载、服务等常用资源
root@master30:~# kubectl get all -n ingress-nginx
NAME READY STATUS RESTARTS AGE
pod/ingress-nginx-admission-create-xhvp9 0/1 Completed 0 8m14s # 准入证书创建Job生成的Pod,已执行完成并退出,就绪容器数0/1,无重启
pod/ingress-nginx-admission-patch-j47tm 0/1 Completed 2 8m14s # 准入配置补丁Job生成的Pod,执行完成,累计重启2次
pod/ingress-nginx-controller-596db54d7-cgbdd 1/1 Running 0 8m14s # ingress控制器主业务Pod,1个容器全部就绪,正常运行中
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/ingress-nginx-controller LoadBalancer 10.107.255.83 10.1.8.40 80:30973/TCP,443:32344/TCP 14s # 控制器入口服务,LoadBalancer类型,MetalLB分配外部IP,映射80/443端口并对应NodePort端口
service/ingress-nginx-controller-admission ClusterIP 10.106.37.158 <none> 443/TCP 8m15s # 准入校验Webhook服务,集群内部访问,校验Ingress资源合法性
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/ingress-nginx-controller 1/1 1 1 8m14s # 控制器Deployment,1副本就绪,最新版本副本数1,可用副本数1
NAME DESIRED CURRENT READY AGE
replicaset.apps/ingress-nginx-controller-596db54d7 1 1 1 8m14s # 控制器对应副本集,期望副本1,当前副本1,就绪副本1,由Deployment自动管理
NAME COMPLETIONS DURATION AGE
job.batch/ingress-nginx-admission-create 1/1 2m26s 8m14s # 证书创建一次性任务,1次执行已完成,执行耗时2分26秒
job.batch/ingress-nginx-admission-patch 1/1 2m28s 8m14s # Webhook配置补丁一次性任务,1次执行已完成,执行耗时2分28秒
Ingress 规则实践
Ingress 规则说明
规则示例
-
示例1: 没有rule的Ingress规则
-
指定一个没有rule的defaultBackend的方式,所有发送给该IP的流量都被转发到了
defaultBackend所列的Kubernetes service上。yamlapiVersion: networking.k8s.io/v1 # API版本,Ingress归属networking.k8s.io/v1稳定API组,Kubernetes 1.19+正式生效 kind: Ingress # 资源类型,七层HTTP/HTTPS路由控制器,定义外部流量进入集群的转发规则 metadata: # 元数据区块,定义资源的名称、标签等标识属性 name: test-ingress # Ingress资源名称,命名空间内唯一标识该路由规则 spec: # 核心规格配置区块,定义路由转发规则 defaultBackend: # 默认后端配置;所有未匹配到路由规则的请求都会转发到该后端服务 service: # 后端目标Service配置 name: testsvc # 后端Service的名称,指定流量转发的目标服务 port: # 后端服务端口配置 number: 80 # 后端Service的监听端口号,流量最终转发到该端口 -
示例2: 虚拟主机,一个域名对应一个path
yamlapiVersion: networking.k8s.io/v1 # Ingress资源所属API组与版本,networking.k8s.io/v1为Kubernetes 1.19+的稳定正式版本 kind: Ingress # 资源类型,七层HTTP/HTTPS路由入口,定义外部域名与路径的转发规则 metadata: # 元数据区块,定义资源的名称、标签等标识属性 name: myingress # Ingress资源名称,命名空间内唯一标识该路由配置 spec: # 核心规格配置区块,定义具体的路由转发规则 ingressClassName: nginx # 关联的Ingress控制器类名;指定由nginx类型的控制器处理该规则,多控制器场景用于区分归属 rules: # 路由规则列表;每条规则对应一个域名,可配置多域名转发 - host: www.cyw.cloud # 第一条规则的匹配域名;仅访问该域名时命中此条转发逻辑 http: # HTTP协议路由配置区块 paths: # 路径匹配规则列表;同一域名下可配置多个路径分发到不同后端服务 - path: / # URL匹配路径;/表示匹配根路径及所有子路径 pathType: Prefix # 路径匹配类型;Prefix为前缀匹配,请求路径以指定path开头即命中 backend: # 匹配成功后的流量转发目标配置 service: # 后端目标为集群内的Service资源 name: www # 后端Service的名称,流量最终转发到该服务 port: # 后端服务的端口配置 number: 80 # 后端Service的监听端口号 - host: web.cyw.cloud # 第二条规则的独立域名 http: paths: - path: / pathType: Prefix backend: service: name: web # 该域名对应的后端Service名称为web port: number: 80 -
示例3: 一个域名对应对多个path
yamlapiVersion: networking.k8s.io/v1 # Ingress资源所属API组与稳定版本,Kubernetes 1.19+正式启用 kind: Ingress # 资源类型,七层HTTP/HTTPS路由入口,基于域名与路径实现流量分发 metadata: # 元数据区块,定义资源标识属性 name: myingress # Ingress资源名称,命名空间内唯一标识该路由配置 spec: # 核心规格配置区块,定义具体路由转发规则 ingressClassName: nginx # 关联的Ingress控制器类名,指定由nginx控制器处理该路由规则 rules: # 路由规则列表,支持多域名、多路径的转发配置 - host: www.cyw.cloud # 匹配的访问域名,所有该域名的请求进入当前规则的路径匹配 http: # HTTP协议路由配置区块 paths: # 路径匹配规则列表,同一域名下按路径前缀分流到不同后端服务 - path: / # 匹配的URL路径前缀,/表示匹配根路径及所有子路径 pathType: Prefix # 路径匹配类型,Prefix为前缀匹配,请求路径以指定path开头即命中 backend: # 匹配成功后的流量转发目标配置 service: # 后端目标为集群内的Service资源 name: www # 后端Service名称,根路径流量转发到www服务 port: # 后端服务端口配置 number: 80 # 后端Service的监听端口号 - path: /cyw # 匹配的URL路径前缀,仅/cyw开头的请求命中此规则 pathType: Prefix backend: service: name: cyw # 后端Service名称,/cyw路径流量转发到cyw服务 port: number: 80 -
示例4: https 透传
如果后端的svc是https流量,系统ingress直接转发https流量给后端service,则需要配置透传 TLS。
yamlapiVersion: networking.k8s.io/v1 # Ingress资源所属API组与稳定版本,Kubernetes 1.19+正式启用 kind: Ingress # 资源类型,七层HTTP/HTTPS路由入口,基于域名与路径实现流量分发 metadata: # 元数据区块,定义资源标识属性与扩展配置 name: myingress # Ingress资源名称,命名空间内唯一标识该路由配置 annotations: # 资源注解;向Ingress控制器传递自定义行为参数,是nginx控制器功能扩展的核心方式 # 关键:透传 TLS,Ingress 不解密 nginx.ingress.kubernetes.io/ssl-passthrough: "true" # TLS透传开关;启用后Ingress不解密HTTPS流量,直接将加密流量转发给后端,由后端服务完成证书解密 nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" # 后端通信协议;指定Ingress与后端Service之间使用HTTPS协议建立连接,适配后端加密服务 spec: # 核心规格配置区块,定义具体路由转发规则 ingressClassName: nginx # 关联的Ingress控制器类名;指定由nginx类型的控制器处理该路由规则 rules: # 路由规则列表,支持多域名、多路径的转发配置 - host: www.cyw.cloud # 匹配的访问域名;仅该域名的请求进入当前规则的路径匹配逻辑 http: # HTTP协议路由配置区块 paths: # 路径匹配规则列表;同一域名下可按不同路径分流到不同后端服务 - path: / # URL匹配路径前缀;/表示匹配根路径及所有子路径 pathType: Prefix # 路径匹配类型;Prefix为前缀匹配,请求路径以指定path开头即命中规则 backend: # 匹配成功后的流量转发目标配置 service: # 后端目标为集群内的Service资源 name: www # 后端Service的名称;流量最终转发到该服务 port: # 后端服务的端口配置 number: 443 # 后端Service的监听端口号;HTTPS场景对应443端口,与透传/后端HTTPS协议配合
配置说明
- 跟Kubernetes的其他配置一样,ingress的配置也需要
apiVersion,kind和metadata字段。 - Ingress spec 中包含配置一个loadbalancer或proxy server的所有信息。最重要的是,它包含了一个匹配所有入站请求的规则列表。目前ingress只支持http规则。
- 每条http规则包含以下信息:
- 一个
host配置项(比如www.cyw.cloud,默认是*) paths列表(比如:/cyw),每个path都关联一个backend,service:port的组合,比如web:80。在loadbalancer将流量转发到backend之前,所有的入站请求都要先匹配host和path。
IngressClass
Ingress 可以由不同的控制器实现,通常使用不同的配置。 每个 Ingress 应当指定一个类,也就是一个对 IngressClass 资源的引用。 IngressClass 资源包含额外的配置,其中包括应当实现该类的控制器名称。
你可以将一个特定的 IngressClass 标记为集群默认 Ingress 类。 将某个 IngressClass 资源的 ingressclass.kubernetes.io/is-default-class 注解设置为 true 将确保新的未指定 ingressClassName 字段的 Ingress 能够被赋予这一默认 IngressClass.
yaml
apiVersion: networking.k8s.io/v1 # IngressClass所属API组与稳定版本,与Ingress资源同属networking.k8s.io/v1,Kubernetes 1.19+正式启用
kind: IngressClass # 资源类型;用于定义Ingress控制器类别,建立Ingress路由规则与控制器实例的关联映射
metadata: # 元数据区块,定义资源标识与扩展属性
annotations: # 资源注解;用于配置集群级默认行为等扩展参数
ingressclass.kubernetes.io/is-default-class: "true" # 默认Ingress类标记注解;设为true后,创建Ingress时不指定ingressClassName会自动关联该类
...... # 通常省略spec.controller字段,用于声明对应控制器实现,例如k8s.io/ingress-nginx
路径匹配
Ingress 中的每个路径都需要有对应的路径类型(Path Type)。未明确设置 pathType 的路径无法通过合法性检查。
当前支持的路径类型有三种:
Prefix:基于以/分隔的 URL 路径前缀匹配。匹配区分大小写, 并且对路径中各个元素逐个执行匹配操作。 路径元素指的是由/分隔符分隔的路径中的标签列表。 如果每个 p 都是请求路径 p 的元素前缀,则请求与路径 p 匹配。Exact:精确匹配 URL 路径,且区分大小写。ImplementationSpecific:对于这种路径类型,匹配方法取决于 IngressClass。 具体实现可以将其作为单独的pathType处理或者作与Prefix或Exact类型相同的处理。
示例
| 类型 | 路径 | 请求路径 | 匹配与否? |
|---|---|---|---|
| Prefix | / |
(所有路径) | 是 |
| Exact | /foo |
/foo |
是 |
| Exact | /foo |
/bar |
否 |
| Exact | /foo |
/foo/ |
否 |
| Exact | /foo/ |
/foo |
否 |
| Prefix | /foo |
/foo, /foo/ |
是 |
| Prefix | /foo/ |
/foo, /foo/ |
是 |
| Prefix | /aaa/bb |
/aaa/bbb |
否 |
| Prefix | /aaa/bbb |
/aaa/bbb |
是 |
| Prefix | /aaa/bbb/ |
/aaa/bbb |
是,忽略尾部斜线 |
| Prefix | /aaa/bbb |
/aaa/bbb/ |
是,匹配尾部斜线 |
| Prefix | /aaa/bbb |
/aaa/bbb/ccc |
是,匹配子路径 |
| Prefix | /aaa/bbb |
/aaa/bbbxyz |
否,字符串前缀不匹配 |
| Prefix | /, /aaa |
/aaa/ccc |
是,匹配 /aaa 前缀 |
| Prefix | /, /aaa, /aaa/bbb |
/aaa/bbb |
是,匹配 /aaa/bbb 前缀 |
| Prefix | /, /aaa, /aaa/bbb |
/ccc |
是,匹配 / 前缀 |
| Prefix | /aaa |
/ccc |
否,使用默认后端 |
| 混合 | /foo (Prefix), /foo (Exact) |
/foo |
是,优选 Exact 类型 |
多重匹配
在某些情况下,Ingress 中会有多条路径与同一个请求匹配。这时匹配路径最长者优先。 如果仍然有两条同等的匹配路径,则精确路径类型优先于前缀路径类型。
主机名匹配
主机名可以是精确匹配 (例如 "foo.bar.com")或者使用通配符匹配 (例如 "*.foo.com")。 精确匹配要求 HTTP host 头部字段与 host 字段值完全匹配。 通配符匹配则要求 HTTP host 头部字段与通配符规则中的后缀部分相同。
| 主机 | host 头部 | 匹配与否? |
|---|---|---|
*.foo.com |
bar.foo.com |
基于相同的后缀匹配 |
*.foo.com |
baz.bar.foo.com |
不匹配,通配符仅覆盖了一个 DNS 标签 |
*.foo.com |
foo.com |
不匹配,通配符仅覆盖了一个 DNS 标签 |
Ingress 规则实践
以下主要讲解生产环境 Ingress-Nginx 常用规则。
环境准备
站点 webapp01
bash
# 创建webapp01无状态应用Deployment;--image指定运行的容器镜像,--replicas设置期望Pod副本数为2
root@master30:~# kubectl create deployment webapp01 --image=hub.cyw.cloud/library/httpd --replicas=2
# 查看Pod资源并展示app标签列;-L指定额外输出对应标签的列,用于验证Pod的标签信息
root@master30:~# kubectl get pod -L app
NAME READY STATUS RESTARTS AGE
webapp01-57b8567f7c-kq56c 1/1 Running 0 18s # 第一个Pod实例,1个容器全部就绪,运行状态,无重启记录
webapp01-57b8567f7c-vzqj7 1/1 Running 0 18s # 第二个Pod实例,标签自动继承Deployment的app=webapp01
# 进入第一个Pod修改httpd默认首页;-it开启交互式终端,--分隔kubectl参数与容器内命令,bash -c执行指定shell命令写入首页
root@master30:~# kubectl exec -it webapp01-57b8567f7c-kq56c -- bash -c "echo hello webapp01 pod1 > htdocs/index.html"
# 进入第二个Pod修改首页内容,用于区分不同后端实例的响应
root@master30:~# kubectl exec -it webapp01-57b8567f7c-vzqj7 -- bash -c "echo hello webapp01 pod2 > htdocs/index.html"
# 暴露Deployment生成ClusterIP类型Service;--port设置服务监听端口,--target-port指定后端容器的目标端口
root@master30:~# kubectl expose deployment webapp01 --port=80 --target-port=80
站点 webapp02
bash
# 创建webapp02无状态应用Deployment;--image指定容器运行镜像,--replicas设置期望Pod副本数为2
root@master30:~# kubectl create deployment webapp02 --image=hub.cyw.cloud/library/httpd --replicas=2
# 查看Pod列表并筛选webapp02实例;grep按关键词过滤输出,仅展示目标应用的Pod资源
root@master30:~# kubectl get pod |grep webapp02
webapp02-598c447b5b-4j76n 1/1 Running 0 18s # 第一个Pod实例,1个容器全部就绪,运行状态,无重启记录
webapp02-598c447b5b-dddwh 1/1 Running 0 18s # 第二个Pod实例,标签自动继承Deployment的app=webapp02
# 进入第一个Pod批量配置静态页面;-it开启交互式终端,--分隔kubectl参数与容器内命令,bash -c执行多条命令,创建games子目录并写入两级首页内容
root@master30:~# kubectl exec -it webapp02-598c447b5b-4j76n -- bash -c "
echo hello webapp02 pod1 > htdocs/index.html
mkdir htdocs/games
echo hello webapp02 game1 > htdocs/games/index.html"
# 进入第二个Pod配置同结构静态页面;写入区分实例的页面内容,用于后续验证路径转发与负载效果
root@master30:~# kubectl exec -it webapp02-598c447b5b-dddwh -- bash -c "
echo hello webapp02 pod2 > htdocs/index.html
mkdir htdocs/games
echo hello webapp02 game2 > htdocs/games/index.html"
# 暴露webapp02 Deployment生成ClusterIP Service;--port设置服务监听端口,--target-port指定后端容器目标端口
root@master30:~# kubectl expose deployment webapp02 --port=80 --target-port=80
一、基础通用规则
1. 多域名虚拟主机(多 host 路由)
场景:多个域名转发不同业务
bash
# 创建多域名路由Ingress配置文件;vim编辑器新建yaml文件,写入多主机分流的路由规则
root@master30:~# vim multi-host-ingress.yaml
apiVersion: networking.k8s.io/v1 # Ingress资源所属API组与稳定版本
kind: Ingress # 资源类型,七层HTTP/HTTPS路由入口,基于域名路径分发流量
metadata: # 元数据区块,定义资源标识属性
name: multi-host-ingress # Ingress资源名称,命名空间内唯一标识该多域名路由配置
spec: # 核心规格配置区块,定义具体路由转发规则
# 这里一定要指定ingressClassName为nginx
ingressClassName: nginx # 关联的Ingress控制器类名,指定由nginx控制器处理该路由规则
rules: # 路由规则列表,支持多域名独立配置转发目标
- host: webapp01.cyw.cloud # 第一个匹配域名,仅该域名请求命中当前规则
http: # HTTP协议路由配置区块
paths: # 路径匹配规则列表,同一域名下可按路径分流
- path: / # URL匹配路径前缀,/匹配根路径及所有子路径
pathType: Prefix # 路径匹配类型,Prefix为前缀匹配,请求路径以指定path开头即命中
backend: # 匹配成功后的流量转发目标配置
service: # 后端目标为集群内Service资源
name: webapp01 # 后端Service名称,该域名流量转发到webapp01服务
port: # 后端服务端口配置
number: 80 # 后端Service监听端口号
- host: webapp02.cyw.cloud # 第二个独立匹配域名
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: webapp02 # 该域名流量转发到webapp02服务
port:
number: 80
# 应用Ingress配置到集群;-f指定从本地文件读取资源清单,创建或更新对应Ingress资源
root@master30:~# kubectl apply -f multi-host-ingress.yaml
# 查看Ingress资源详细信息;describe输出完整配置、后端端点与事件日志,验证路由规则加载状态
root@master30:~# kubectl describe ingress multi-host-ingress
Name: multi-host-ingress # Ingress资源名称
Labels: <none> # 资源标签,当前未设置
Namespace: ingress # 资源所在命名空间
Address: 10.1.8.40 # Ingress控制器对外暴露的访问地址,即LoadBalancer分配的外部IP
Ingress Class: nginx # 关联的Ingress控制器类名
Default backend: <default> # 默认后端,未匹配规则的流量转发目标,当前使用系统默认
Rules: # 路由规则详情段
Host Path Backends
---- ---- --------
webapp01.cyw.cloud # 第一个域名规则
/ webapp01:80 (10.224.113.173:80,10.224.19.36:80) # 根路径转发到webapp01服务80端口,括号内为后端两个Pod的实际端点地址
webapp02.cyw.cloud # 第二个域名规则
/ webapp02:80 (10.224.113.174:80,10.224.19.44:80) # 根路径转发到webapp02服务80端口,对应两个后端Pod端点
Annotations: <none> # 资源注解,当前未配置自定义注解
Events: # 资源事件记录段
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Sync 2s (x2 over 8s) nginx-ingress-controller Scheduled for sync # 正常事件,控制器已接收规则并安排同步加载,x2表示已同步2次
访问验证
bash
# 修改www.cyw.cloud解析,确保客户端能解析该名称
# 如果有多个域名,建议使用配置DNS-wild匹配
[root@client ~]# echo '10.1.8.40 webapp01.cyw.cloud' >> /etc/hosts
[root@client ~]# echo '10.1.8.40 webapp02.cyw.cloud' >> /etc/hosts
# 注意: 这里我们直接访问域名,没有加端口号
[root@client ~]# curl webapp01.cyw.cloud
hello webapp01 pod1
[root@client ~]# curl webapp01.cyw.cloud
hello webapp01 pod2
[root@client ~]# curl webapp02.cyw.cloud
hello webapp02 pod1
[root@client ~]# curl webapp02.cyw.cloud
hello webapp02 pod2
删除 ingress
bash
root@master30:~# kubectl delete ingress multi-host-ingress
2. 同一域名多路径路由(path 分流)
场景:一个域名,不同路径转发给不同微服务
bash
# 创建同域名多路径分流的Ingress配置文件;vim编辑新建yaml文件,写入单域名下按URL路径分发到不同后端的路由规则
root@master30:~# vim multi-path-ingress.yaml
apiVersion: networking.k8s.io/v1 # Ingress资源所属API组与稳定版本,Kubernetes 1.19+正式启用
kind: Ingress # 资源类型,七层HTTP/HTTPS路由入口,基于域名路径分发流量
metadata: # 元数据区块,定义资源标识属性
name: multi-path-ingress # Ingress资源名称,命名空间内唯一标识该多路径路由配置
spec: # 核心规格配置区块,定义具体路由转发规则
ingressClassName: nginx # 关联的Ingress控制器类名,指定由nginx控制器处理该路由规则
rules: # 路由规则列表,支持单域名下多路径分流配置
- host: www.cyw.cloud # 匹配的访问域名,该域名下所有请求进入当前路径匹配逻辑
http: # HTTP协议路由配置区块
paths: # 路径匹配规则列表,同一域名下按URL前缀分发到不同后端服务
- path: / # URL匹配路径前缀,/匹配根路径及所有未被更长前缀匹配的子路径
pathType: Prefix # 路径匹配类型,Prefix为前缀匹配,请求路径以指定path开头即命中规则
backend: # 匹配成功后的流量转发目标配置
service: # 后端目标为集群内的Service资源
name: webapp01 # 后端Service名称,根路径流量转发到webapp01服务
port: # 后端服务端口配置
number: 80 # 后端Service的监听端口号
- path: /games # URL匹配路径前缀,仅/games开头的请求命中,长前缀优先级高于根路径
pathType: Prefix
backend:
service:
name: webapp02 # 后端Service名称,/games路径流量转发到webapp02服务
port:
number: 80
# 应用多路径Ingress配置到集群;-f指定从本地文件读取资源清单,创建或更新对应Ingress资源
root@master30:~# kubectl apply -f multi-path-ingress.yaml
# 查看多路径Ingress资源详细信息;describe输出完整配置、后端端点与事件日志,验证路径路由规则加载状态
root@master30:~# kubectl describe ingress multi-path-ingress
Name: myingress-3 # 集群内实际的Ingress资源名称
Labels: <none> # 资源标签,当前未设置
Namespace: ingress # 资源所在命名空间
Address: 10.1.8.40 # Ingress控制器对外暴露的访问地址,即LoadBalancer分配的外部IP
Ingress Class: nginx # 关联的Ingress控制器类名
Default backend: <default> # 默认后端,未匹配规则的流量转发目标,当前使用系统默认
Rules: # 路由规则详情段
Host Path Backends
---- ---- --------
www.cyw.cloud # 匹配的业务域名
/ webapp01:80 (10.224.113.173:80,10.224.19.36:80) # 根路径转发到webapp01服务80端口,括号内为两个后端Pod的实际端点地址
/games webapp02:80 (10.224.113.174:80,10.224.19.44:80) # /games路径转发到webapp02服务80端口,对应两个后端Pod端点
Annotations: <none> # 资源注解,当前未配置自定义注解
Events: # 资源事件记录段
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Sync 2s (x2 over 8s) nginx-ingress-controller Scheduled for sync # 正常事件,控制器已接收规则并安排同步加载,x2表示已完成2次同步
访问验证
bash
# 修改www.cyw.cloud解析,确保客户端能解析该名称
# 如果有多个域名,建议使用配置DNS-wild匹配
[root@client ~]# echo '10.1.8.40 www.cyw.cloud' >> /etc/hosts
# 注意: 这里我们直接访问域名,没有加端口号
[root@client ~]# curl www.cyw.cloud
hello webapp01 pod1
[root@client ~]# curl www.cyw.cloud
hello webapp01 pod2
[root@client ~]# curl www.cyw.cloud/games/
hello webapp02 game1
[root@client ~]# curl www.cyw.cloud/games/
hello webapp02 game2
删除 ingress
bash
root@master30:~# kubectl delete ingress multi-path-ingress
二、生产核心:路径重写
3. 路径裁剪(等价 Nginx proxy_pass /)
场景 :前端访问 /api/xxx,后端实际只识别 /xxx,剥离 /api 前缀
bash
# 创建路径重写型Ingress配置文件;vim编辑新建yaml文件,实现URL前缀剥离与路径重写的路由转发
root@master30:~# vim path-trimming-ingress.yaml
apiVersion: networking.k8s.io/v1 # Ingress资源所属API组与稳定版本
kind: Ingress # 资源类型,七层HTTP/HTTPS路由入口
metadata: # 元数据区块,定义资源标识与扩展配置
name: path-trimming-ingress # Ingress资源名称,标识该配置为路径裁剪重写场景
annotations: # 资源注解,传递nginx控制器的自定义行为参数
nginx.ingress.kubernetes.io/use-regex: "true" # 启用正则匹配开关;开启后path字段支持正则表达式语法,用于路径捕获与复杂匹配
nginx.ingress.kubernetes.io/rewrite-target: /$1 # 路径重写目标;将匹配到的第一个捕获组内容作为转发到后端的实际路径,实现前缀剥离
spec: # 核心规格配置区块
ingressClassName: nginx # 关联的Ingress控制器类名,指定由nginx控制器处理
rules: # 路由规则列表
- host: www.cyw.cloud # 匹配的访问域名
http: # HTTP协议路由配置
paths: # 路径匹配规则列表
- path: /webapp01/(.*) # 正则匹配路径;匹配/webapp01/开头的所有路径,括号内为第一个捕获组,提取后续路径内容
pathType: ImplementationSpecific # 路径匹配类型;ImplementationSpecific表示匹配逻辑由控制器实现决定,正则匹配必须使用该类型
backend: # 转发目标后端配置
service: # 后端目标为集群Service
name: webapp01 # 后端Service名称,该前缀流量转发到webapp01服务
port: # 后端服务端口配置
number: 80 # 后端Service监听端口号
- path: /webapp02/(.*) # 匹配/webapp02/开头的路径,捕获后续路径用于重写
pathType: ImplementationSpecific
backend:
service:
name: webapp02 # 后端Service名称为webapp02
port:
number: 80
# 应用路径重写Ingress配置到集群;-f指定从本地文件读取资源清单,创建或更新对应Ingress资源
root@master30:~# kubectl apply -f path-trimming-ingress.yaml
# 查看路径重写Ingress资源详细信息;describe输出完整配置、后端端点与事件日志,验证重写规则加载状态
root@master30:~# kubectl describe ingress path-trimming-ingress
Name: path-trimming-ingress # Ingress资源名称
Labels: <none> # 资源标签,当前未设置
Namespace: ingress # 资源所在命名空间
Address: 10.1.8.40 # Ingress控制器对外暴露的LoadBalancer外部IP
Ingress Class: nginx # 关联的Ingress控制器类名
Default backend: <default> # 默认后端,未匹配规则的流量转发目标
Rules: # 路由规则详情段
Host Path Backends
---- ---- --------
www.cyw.cloud # 匹配的业务域名
/webapp01/(.*) webapp01:80 (10.224.113.173:80,10.224.19.36:80) # 正则路径规则,转发到webapp01服务,括号内为后端Pod端点
/webapp02/(.*) webapp02:80 (10.224.113.174:80,10.224.19.44:80) # 第二条正则路径规则,转发到webapp02服务
Annotations: nginx.ingress.kubernetes.io/rewrite-target: /$1 # 路径重写目标注解,捕获组替换实现前缀剥离
nginx.ingress.kubernetes.io/use-regex: true # 正则匹配启用注解
Events: # 资源事件记录段
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Sync 0s (x4 over 13m) nginx-ingress-controller Scheduled for sync # 正常事件,控制器已接收规则并完成4次同步加载
访问验证
bash
[root@client ~]# curl www.cyw.cloud/webapp01/
hello webapp01 pod1
[root@client ~]# curl www.cyw.cloud/webapp01/
hello webapp01 pod1
[root@client ~]# curl www.cyw.cloud/webapp02/
hello webapp02 pod1
[root@client ~]# curl www.cyw.cloud/webapp02/
hello webapp02 pod1
删除 ingress
bash
root@master30:~# kubectl delete ingress path-trimming-ingress
三、HTTPS 强制 & TLS 证书
4. 绑定 TLS 证书 + 强制 HTTPS
环境准备
bash
# 生成2048位RSA私钥文件;genrsa生成RSA私钥,-out指定输出文件名,2048为密钥长度
root@master30:~# openssl genrsa -out www.key 2048
# 基于私钥生成证书签名请求CSR;req证书请求子命令,-new生成新请求,-key指定关联私钥,-subj非交互式填写证书主题信息
root@master30:~# openssl req -new -key www.key -out www.csr -subj "/C=CN/ST=JS/L=NJ/O=LM/OU=DEVOPS/CN=www.cyw.cloud/emailAddress=webadmin@cyw.cloud"
# 自签发有效期10年的TLS证书;x509证书处理子命令,-req输入为CSR格式,-days有效期天数,-in指定输入文件,-signkey指定自签名私钥
root@master30:~# openssl x509 -req -days 3650 -in www.csr -signkey www.key -out www.crt
# 创建TLS类型Secret存入集群供Ingress使用;create secret tls创建TLS保密字典,www-tls为资源名称,--cert传入证书文件,--key传入私钥文件
root@master30:~# kubectl create secret tls www-tls --cert=./www.crt --key=./www.key
生产标配:https访问, 80 端口也会自动跳转 443
bash
# 创建HTTPS加密的Ingress配置文件;vim编辑新建yaml文件,配置TLS证书绑定与HTTP强制跳转HTTPS规则
root@master30:~# vim tls-ingress.yaml
apiVersion: networking.k8s.io/v1 # Ingress资源所属API组与稳定版本
kind: Ingress # 资源类型,七层HTTP/HTTPS路由入口
metadata: # 元数据区块,定义资源标识与扩展配置
name: tls-ingress # Ingress资源名称,标识该配置为TLS加密路由场景
annotations: # 资源注解,传递nginx控制器的自定义行为参数
nginx.ingress.kubernetes.io/ssl-redirect: "true" # SSL重定向开关;启用后HTTP请求自动重定向到HTTPS端口,强制访问走加密通道
nginx.ingress.kubernetes.io/force-ssl-redirect: "true" # 强制SSL重定向;忽略后端配置,强制所有HTTP请求跳转至HTTPS,杜绝明文传输
spec: # 核心规格配置区块
ingressClassName: nginx # 关联的Ingress控制器类名,指定由nginx控制器处理
tls: # TLS加密配置列表;定义HTTPS证书与域名的绑定关系,在Ingress层完成TLS终止解密
- hosts: # 证书对应的域名列表,需与证书中的CN/备用域名匹配
- www.cyw.cloud
secretName: www-tls # 存储TLS证书与私钥的Secret资源名称,控制器从该Secret读取证书文件
rules: # 路由规则列表
- host: www.cyw.cloud # 匹配的访问域名,与TLS证书域名保持一致
http: # HTTP协议路由配置
paths: # 路径匹配规则列表
- path: / # URL匹配路径前缀,/匹配根路径及所有子路径
pathType: Prefix # 路径匹配类型,Prefix为前缀匹配
backend: # 匹配成功后的流量转发目标配置
service: # 后端目标为集群内的Service资源
name: webapp01 # 后端Service名称,HTTPS解密后的流量转发到该服务
port: # 后端服务端口配置
number: 80 # 后端Service的监听端口号
# 应用TLS类型Ingress配置到集群;-f指定从本地文件读取资源清单,创建或更新对应Ingress资源
root@master30:~# kubectl apply -f tls-ingress.yaml
# 查看TLS Ingress资源详细信息;describe输出完整TLS配置、路由规则与事件日志,验证证书绑定与规则加载状态
root@master30:~# kubectl describe ingress tls-ingress
Name: tls-ingress # Ingress资源名称
Labels: <none> # 资源标签,当前未设置
Namespace: ingress # 资源所在命名空间
Address: # Ingress对外访问地址,暂未分配
Ingress Class: nginx # 关联的Ingress控制器类名
Default backend: <default> # 默认后端,未匹配规则的流量转发目标
TLS: # TLS加密配置详情
www-tls terminates www.cyw.cloud # 使用www-tls证书终止该域名的TLS连接,Ingress负责解密HTTPS流量
Rules: # 路由规则详情段
Host Path Backends
---- ---- --------
www.cyw.cloud # 匹配的业务域名
/ webapp01:80 (10.224.19.54:80,10.224.19.56:80) # 根路径转发到webapp01服务80端口,括号内为两个后端Pod端点地址
Annotations: nginx.ingress.kubernetes.io/force-ssl-redirect: true # 强制SSL重定向注解已生效
nginx.ingress.kubernetes.io/ssl-redirect: true # SSL重定向注解已生效
Events: # 资源事件记录段
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Sync 11s nginx-ingress-controller Scheduled for sync # 正常事件,控制器已接收规则并安排同步加载
访问验证
bash
# 使用 -L 跟随 301/302/307/308 所有重定向
[root@client ~]# curl -Lk http://www.cyw.cloud/
hello webapp01 pod1
[root@client ~]# curl -Lk http://www.cyw.cloud/
hello webapp01 pod2
# 访问https站点
[root@client ~]# curl -k https://www.cyw.cloud/
hello webapp01 pod1
[root@client ~]# curl -k https://www.cyw.cloud/
hello webapp01 pod2
#参数解析
# -L / --location:自动跟随 301/302 等 HTTP 重定向(curl 默认不跟着跳转)腾讯云
#-k / --insecure:跳过 HTTPS 证书校验,**不检查证书是否可信**(自签证书、内网测试常用
!warning
⚠️ 风险提醒:生产环境禁止使用 -k,会存在中间人劫持风险,仅开发 / 内网调试临时用curl
删除 ingress
bash
root@master30:~# kubectl delete ingress tls-ingress
四、限流、防刷、超时优化
5. 连接数限流、单IP限速
yaml
annotations:
# 单IP最大并发连接
nginx.ingress.kubernetes.io/limit-connections: "50"
# 单IP每秒请求数
nginx.ingress.kubernetes.io/limit-rps: "20"
6. 自定义超时时间
yaml
annotations: # 资源注解区块;向nginx Ingress控制器传递自定义代理行为参数,精细化控制七层转发的超时策略
nginx.ingress.kubernetes.io/proxy-connect-timeout: "10" # 代理连接超时时间;单位秒,定义Ingress与后端服务建立TCP连接的最大等待时长,超时则返回连接失败
nginx.ingress.kubernetes.io/proxy-read-timeout: "60" # 代理读取超时时间;单位秒,定义Ingress读取后端响应的最大间隔时长,长请求、慢接口场景需适当调大
nginx.ingress.kubernetes.io/proxy-send-timeout: "60" # 代理发送超时时间;单位秒,定义Ingress向后端发送请求数据的最大间隔时长,适配大报文、文件上传类场景
五、跨域配置(前后端分离必备)
7. 全局跨域放行
yaml
annotations: # 资源注解区块;向nginx Ingress控制器传递跨域相关配置,控制浏览器跨域请求的访问权限
nginx.ingress.kubernetes.io/enable-cors: "true" # 开启CORS跨域资源共享;启用后Ingress会自动添加跨域响应头,允许浏览器跨域调用当前接口
nginx.ingress.kubernetes.io/cors-allow-origin: "*" # 跨域允许的请求源;*表示放行所有来源域名的跨域请求,生产环境建议配置指定域名提升安全性
nginx.ingress.kubernetes.io/cors-allow-methods: "GET,POST,PUT,DELETE,OPTIONS" # 跨域允许的HTTP方法;指定浏览器跨域时可使用的请求方法,包含预检请求所需的OPTIONS方法
六、白名单访问控制(内网 / 后台系统)
8. 限制指定IP段访问
场景:管理后台、内部系统,只允许公司内网IP
yaml
annotations:
# 只放行 10.1.8.0/24 网段
nginx.ingress.kubernetes.io/whitelist-source-range: "10.1.8.0/24,127.0.0.1/32"
七、静态资源缓存、请求头透传
9. 透传真实客户端IP
yaml
annotations: # 资源注解区块;配置客户端真实IP获取相关参数,解决多层代理场景下后端服务无法获取访问者源IP的问题
nginx.ingress.kubernetes.io/x-forwarded-for: "true" # 启用X-Forwarded-For请求头;开启后Ingress会将客户端真实IP追加到请求头中传递给后端,便于业务侧记录访问来源
nginx.ingress.kubernetes.io/proxy-real-ip-cidr: "10.0.0.0/8" # 可信代理网段白名单;仅来自该CIDR范围内的上游代理,其传递的X-Forwarded-For信息才会被信任,防止恶意用户伪造客户端真实IP
10. 静态资源缓存优化
yaml
annotations: # 资源注解区块;配置nginx Ingress的反向代理缓存能力,缓存静态响应以降低后端服务负载、提升访问速度
nginx.ingress.kubernetes.io/proxy-cache: "true" # 启用代理缓存开关;开启后Ingress会按照规则缓存后端响应,相同请求直接返回缓存内容,无需转发到后端
nginx.ingress.kubernetes.io/proxy-cache-valid: "200 302 10m" # 缓存有效期规则;指定HTTP状态码对应的缓存时长,此处表示200、302状态的响应缓存10分钟,到期后自动失效回源刷新
八、灰度 / 权重分流(金丝雀发布)
11. 权重流量拆分
场景:线上灰度,90%流量走稳定版,10%走测试版
yaml
annotations: # 资源注解区块;配置nginx Ingress的金丝雀灰度发布能力,实现新旧版本服务按比例分流验证
nginx.ingress.kubernetes.io/canary: "true" # 启用金丝雀发布开关;标记当前Ingress为金丝雀路由规则,与同域名的主Ingress并存,将部分流量导入新版本后端服务
nginx.ingress.kubernetes.io/canary-weight: "10" # 金丝雀流量权重;单位为百分比,取值范围0-100,此处设置10表示10%的访问流量会被转发到金丝雀版本后端,剩余90%流量走主版本路由
九、错误页面、自定义配置
12. 自定义后端错误页、关闭目录浏览
yaml
annotations: # 资源注解区块;向nginx Ingress控制器传递错误页面自定义配置,统一拦截处理后端返回的异常状态码
nginx.ingress.kubernetes.io/custom-http-errors: "404,500,502,503" # 自定义HTTP错误码列表;指定需要拦截的错误状态码,后端返回这些状态时Ingress会返回预设的统一错误页面,替代默认的nginx错误页,优化访问体验
十、生产高频注解 速查表
| 注解 | 作用 |
|---|---|
force-ssl-redirect: true |
80 强制跳转 HTTPS |
rewrite-target |
路径重写、裁剪路由前缀 |
whitelist-source-range |
IP白名单 |
limit-rps / limit-connections |
防CC、限流 |
enable-cors |
前后端跨域 |
proxy-read-timeout |
解决接口超时断开 |
x-forwarded-for |
后端获取真实客户端IP |
环境清理
bash
root@master30:~# kubectl delete ns ingress