K8s Ingress 详解与部署实战
前言
一、Ingress 基本概念
1. Ingress 是什么?
2. 为什么需要 Ingress?
二、Ingress 核心组成
1. Ingress 资源对象(规则定义)
2. Ingress Controller(规则执行器)
三、Ingress 工作原理
四、Ingress 暴露服务方式
✅ 方式一:Deployment + LoadBalancer Service
✅ 方式二:DaemonSet + HostNetwork + nodeSelector(推荐生产)
1. 节点打标签
2. 修改部署文件 (将 Deployment 改为 DaemonSet,启用 HostNetwork 并指定 node)
3. 验证部署
4.创建ingress规则
6.创建ingress
✅ 方式三:Deployment + NodePort Service
五、Deployment + NodePort Service 配置案例
1. HTTP 代理访问
补充:Ingress HTTP 代理访问虚拟主机
2. HTTPS 代理访问
3. BasicAuth 认证
4. 路径重写
5. 路径匹配类型
六、故障排查与监控
1. 常用检查命令
2. 常见问题排查
八、生产环境建议
1. 部署架构选择
2. 高可用方案
3. 安全加固
4. 监控告警
九、总结
前言
在 Kubernetes 中,如何高效、灵活地暴露服务至集群外部,是每个开发者必须面对的关键挑战。Ingress 作为 Kubernetes 的智能流量入口,通过基于域名和路径的七层路由规则,完美解决了多服务共享入口、精细化流量分发等核心需求。
本文将深入解析 Ingress 的工作原理,详细介绍三种主流的服务暴露方式,并通过丰富的实战示例展示高级功能配置。无论您是正在入门 Kubernetes,还是负责生产环境运维,本文都将为您提供从基础概念到高级实践的完整指南。
一、Ingress 基本概念
1. Ingress 是什么?
Ingress 是 Kubernetes 中用于暴露 HTTP/HTTPS 服务到集群外部的 API 对象,它提供了:
-
基于域名和 URL 路径的路由
-
SSL/TLS 终止
-
负载均衡
-
七层(应用层)反向代理
2. 为什么需要 Ingress?
暴露方式 | 缺点 | Ingress 优势 |
---|---|---|
NodePort | 端口管理困难,范围固定(30000-32767) | 一个IP暴露多个服务 |
LoadBalancer | 需要云厂商支持,费用高 | 成本低,配置灵活 |
externalIPs | 配置复杂,缺乏智能路由 | 基于域名/路径的智能路由 |
Inress 可以理解为 "Service 的 Service"
二、Ingress 核心组成
1. Ingress 资源对象(规则定义)
-
作用:定义路由规则(YAML 格式)
-
功能:指定哪个域名/路径转发到哪个 Service
-
示例:
vim mandatory.yaml ...... #RBAC相关资源从1.17版本开始改用rbac.authorization.k8s.io/v1,#rbac.authorization.k8s.io/v1beta1在1.22版本即将弃用 ------------------------------------------------------------- #部署ingress-nginx apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRole metadata:name: nginx-ingress-clusterrolelabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx rules:- apiGroups:- ""resources:- configmaps- endpoints- nodes- pods- secretsverbs:- list- watch- apiGroups:- ""resources:- nodesverbs:- get- apiGroups:- ""resources:- servicesverbs:- get- list- watch- apiGroups:- "extensions"- "networking.k8s.io" # (0.25版本)增加 networking.k8s.io Ingress 资源的 api resources:- ingressesverbs:- get- list- watch- apiGroups:- ""resources:- eventsverbs:- create- patch- apiGroups:- "extensions"- "networking.k8s.io" # (0.25版本)增加 networking.k8s.io/v1 Ingress 资源的 api resources:- ingresses/statusverbs:- update
2. Ingress Controller(规则执行器)
-
作用:实际处理流量的组件
-
功能:监控 Ingress 规则变化,生成配置并执行
-
常见实现:
-
ingress-nginx(官方维护)
-
Traefik
-
HAProxy Ingress
-
Istio Gateway
-
重要:Ingress Controller 才是真正的流量入口,Ingress 对象只是告诉 Controller 如何转发
三、Ingress 工作原理
详细流程:
-
Controller 通过 API Server 监听 Ingress 资源变化
-
读取所有 Ingress 规则,生成对应的 Nginx 配置
-
将配置写入 Controller Pod 的
/etc/nginx/nginx.conf
-
执行
nginx -s reload
重新加载配置 -
外部请求到达时,按配置规则进行路由转发
四、Ingress 暴露服务方式
✅ 方式一:Deployment + LoadBalancer Service
适用场景:公有云环境
架构特点:
-
云厂商自动创建负载均衡器
-
LB 绑定公网 IP,域名解析指向该 IP
-
全托管,配置简单
部署示例:
yaml
apiVersion: v1 kind: Service metadata:name: ingress-nginxnamespace: ingress-nginx spec:type: LoadBalancerports:- port: 80targetPort: 80selector:app: ingress-nginx
✅ 方式二:DaemonSet + HostNetwork + nodeSelector(推荐生产)
适用场景:高性能、大并发生产环境
架构特点:
-
使用宿主机网络,直接绑定 80/443 端口
-
一个节点只能运行一个 Controller Pod
-
链路最短,性能最佳
-
类似传统架构的边缘节点
部署步骤:
1. 节点打标签
bash
kubectl label node node02 ingress=true kubectl get nodes --show-labels
2. 修改部署文件 (将 Deployment 改为 DaemonSet,启用 HostNetwork 并指定 node)
yaml
vim mandatory.yaml ... apiVersion: apps/v1 # 修改 kind # kind: Deployment kind: DaemonSet metadata:name: nginx-ingress-controllernamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx spec: # 删除Replicas # replicas: 1selector:matchLabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxtemplate:metadata:labels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxannotations:prometheus.io/port: "10254"prometheus.io/scrape: "true"spec:# 使用主机网络hostNetwork: true# 选择节点运行nodeSelector:ingress: "true"serviceAccountName: nginx-ingress-serviceaccount ...... --------------------------------------------------------------- #在所有node节点上传镜像并加载 cd /opt/ingress # 假设已有压缩包 ingree.contro.tar.gz tar zxvf ingree.contro.tar.gz docker load -i ingree.contro.tar
3. 验证部署
bash
kubectl get pod -n ingress-nginx -o wide netstat -lntp | grep nginx # 预期监听端口:80、443、8181、10254
4.创建ingress规则
###创建一个 deploy 和 svc vim service-nginx.yaml apiVersion: apps/v1 kind: Deployment metadata:name: nginx-app spec:replicas: 2selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginximagePullPolicy: IfNotPresentports:- containerPort: 80 --- apiVersion: v1 kind: Service metadata:name: nginx-app-svc spec:type: ClusterIPports:- protocol: TCPport: 80targetPort: 80selector:app: nginx
6.创建ingress
vim ingress-app.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata:name: nginx-app-ingress spec:rules:- host: www.uuz.comhttp:paths:- path: /pathType: Prefix # 也可使用 Exactbackend:service:name: nginx-app-svcport:number: 80 ------------------------------------------------------------------- #测试 kubectl apply -f service-nginx.yaml kubectl apply -f ingress-app.yaml kubectl get ingress # /etc/hosts 添加解析: # 192.168.10.21 www.uuz.com curl www.uuz.com
路径匹配:
-
Prefix
:基于前缀匹配,如 /yuzusoft 可匹配 /yuzusoft、/yuzusoft/0d00 等 -
Exact
:完全匹配,如 /yuzusoft 只能匹配 /yuzusoft
✅ 方式三:Deployment + NodePort Service
适用场景:测试环境或前置负载均衡器场景
架构特点:
-
NodePort 提供随机端口(30000-32767)
-
通常前置 LVS、HAProxy 等负载均衡器
-
多一层 NAT,性能略差
部署示例:
bash
mkdir -p /opt/ingress-nodeport && cd /opt/ingress-nodeport # 清单获取 官方下载地址: wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml # 或国内镜像: wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml # 在所有 node 节点上传镜像包 ingress-controller-0.30.0.tar 到 /opt/ingress-nodeport 目录,并加载镜像 docker load -i ingress-controller-0.30.0.tar # 启动 Controller 与 NodePort Service kubectl apply -f mandatory.yaml kubectl apply -f service-nodeport.yaml #如果K8S Pod 调度失败,在 kubectl describe pod资源时显示: # Warning FailedScheduling ... didn't match node selector # 解决: # 1) 按 YAML 中的 nodeSelector 给节点加标签 kubectl label nodes <node_name> kubernetes.io/os=linux # 2) 或删除 YAML 中的 nodeSelector kubectl get pod,svc -n ingress-nginx
五、Deployment + NodePort Service 配置案例
1. HTTP 代理访问
yaml
vim ingress-nginx.yaml(应用、Service、Ingress) apiVersion: apps/v1 kind: Deployment metadata:name: nginx-app spec:replicas: 2selector:matchLabels:name: nginxtemplate:metadata:labels:name: nginxspec:containers:- name: nginximage: nginximagePullPolicy: IfNotPresentports:- containerPort: 80 --- apiVersion: v1 kind: Service metadata:name: nginx-svc spec:ports:- port: 80targetPort: 80protocol: TCPselector:name: nginx --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata:name: nginx-test spec:rules:- host: www.uuz.comhttp:paths:- path: /pathType: Prefixbackend:service:name: nginx-svcport:number: 80---------------------------------------------------------------- #测试 kubectl apply -f ingress-nginx.yaml kubectl get svc -n ingress-nginx # 假设 NodePort 为 80:32383/TCP # hosts 添加:192.168.10.21 www.uuz.com curl http://www.uuz.com:32383
补充:Ingress HTTP 代理访问虚拟主机
mkdir /opt/ingress-nodeport/vhost cd /opt/ingress-nodeport/vhost# deployment1.yaml(v1) apiVersion: apps/v1 kind: Deployment metadata:name: deployment1 spec:replicas: 2selector:matchLabels:name: nginx1template:metadata:labels:name: nginx1spec:containers:- name: nginx1image: soscscs/myapp:v1imagePullPolicy: IfNotPresentports:- containerPort: 80 --- apiVersion: v1 kind: Service metadata:name: svc-1 spec:ports:- port: 80targetPort: 80protocol: TCPselector:name: nginx1# deployment2.yaml(v2) apiVersion: apps/v1 kind: Deployment metadata:name: deployment2 spec:replicas: 2selector:matchLabels:name: nginx2template:metadata:labels:name: nginx2spec:containers:- name: nginx2image: soscscs/myapp:v2imagePullPolicy: IfNotPresentports:- containerPort: 80 --- apiVersion: v1 kind: Service metadata:name: svc-2 spec:ports:- port: 80targetPort: 80protocol: TCPselector:name: nginx2# ingress-nginx.yaml(双主机名) apiVersion: networking.k8s.io/v1 kind: Ingress metadata:name: ingress1 spec:rules:- host: www1.uuz.comhttp:paths:- path: /pathType: Prefixbackend:service:name: svc-1port:number: 80 --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata:name: ingress2 spec:rules:- host: www2.uuz.comhttp:paths:- path: /pathType: Prefixbackend:service:name: svc-2port:number: 80---------------------------------------------------------------------- #测试 # NodePort 假设为 32383 curl www1.uuz.com:32383 curl www2.uuz.com:32383
2. HTTPS 代理访问
bash
mkdir -p /opt/ingress-nodeport/https && cd /opt/ingress-nodeport/https # 生成自签证书 openssl req -x509 -sha256 -nodes -days 365 \-newkey rsa:2048 -keyout tls.key -out tls.crt \-subj "/CN=nginxsvc/O=nginxsvc" # 创建 secret kubectl create secret tls tls-secret --key tls.key --cert tls.crt kubectl get secret tls-secret -o yaml # ingress-https.yaml apiVersion: apps/v1 kind: Deployment metadata:name: nginx-app spec:replicas: 2selector:matchLabels:name: nginxtemplate:metadata:labels:name: nginxspec:containers:- name: nginximage: nginxports:- containerPort: 80 --- apiVersion: v1 kind: Service metadata:name: nginx-svc-01 spec:ports:- port: 80targetPort: 80protocol: TCPselector:name: nginx --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata:name: nginx-https spec:tls:- hosts:- www3.uuz.comsecretName: tls-secretrules:- host: www3.uuz.comhttp:paths:- path: /pathType: Prefixbackend:service:name: nginx-svc-01port:number: 80kubectl apply -f ingress-https.yamlkubectl get svc -n ingress-nginx--------------------------------------------------------------------------- #测试 # NodePort 假设 443:32133 # hosts 添加:192.168.10.21 www3.uuz.com # 浏览器访问:https://www3.uuz.com:32133
3. BasicAuth 认证
bash
mkdir -p /opt/ingress-nodeport/basic-auth && cd /opt/ingress-nodeport/basic-auth # 生成 basic auth 文件(文件名需为 auth) yum -y install httpd htpasswd -c auth zhangsan # 存为 secret kubectl create secret generic basic-auth --from-file=auth # ingress-auth.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata:name: ingress-authannotations:nginx.ingress.kubernetes.io/auth-type: basicnginx.ingress.kubernetes.io/auth-secret: basic-authnginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - zhangsan' spec:rules:- host: auth.uuz.comhttp:paths:- path: /pathType: Prefixbackend:service:name: nginx-svcport:number: 80
4. 路径重写
常用注解:
-
nginx.ingress.kubernetes.io/rewrite-target: <字符串>
:重定向目标 URI(必填) -
nginx.ingress.kubernetes.io/ssl-redirect: <bool>
:是否仅允许 SSL(Ingress 含证书时默认true
) -
nginx.ingress.kubernetes.io/force-ssl-redirect: <bool>
:即使未启用 TLS 也强制跳转 HTTPS -
nginx.ingress.kubernetes.io/app-root: <字符串>
:定义应用根路径重定向 -
nginx.ingress.kubernetes.io/use-regex: <bool>
:路径是否使用正则
yaml
# ingress-rewrite.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata:name: nginx-rewriteannotations:nginx.ingress.kubernetes.io/rewrite-target: http://www1.uuz.com:32383 spec:rules:- host: re.uuz.comhttp:paths:- path: /pathType: Prefixbackend:# 仅用于跳转,svc 名可随意service:name: nginx-svcport:number: 80-------------------------------------------------------- #测试 # hosts 添加:192.168.10.21 re.uuz.com # 浏览器访问:http://re.uuz.com:32383
5. 路径匹配类型
类型 | 说明 | 示例 |
---|---|---|
Prefix | 前缀匹配 | /app 匹配 /app 、/app/xxx |
Exact | 精确匹配 | /app 只匹配 /app |
六、故障排查与监控
1. 常用检查命令
bash
# 检查 Controller 状态 kubectl get pod -n ingress-nginx -o wide # 检查端口监听 netstat -lntp | grep nginx # 查看生成的 Nginx 配置 kubectl exec -it <controller-pod> -n ingress-nginx -- cat /etc/nginx/nginx.conf # 查看 Ingress 资源 kubectl get ingress --all-namespaces # 检查事件 kubectl describe ingress <ingress-name>
2. 常见问题排查
问题现象 | 可能原因 | 解决方案 |
---|---|---|
503 Service Unavailable | 后端 Service 不存在 | 检查 Service 和 Endpoints |
404 Not Found | 路径配置错误 | 检查 path 和 pathType |
证书错误 | TLS Secret 配置错误 | 检查证书格式和 Secret |
调度失败 | nodeSelector 不匹配 | 给节点打标签或删除 nodeSelector |
八、生产环境建议
1. 部署架构选择
-
高性能场景:DaemonSet + HostNetwork
-
公有云环境:LoadBalancer + 自动伸缩
-
混合环境:NodePort + 外部负载均衡器
2. 高可用方案
-
多节点部署 Ingress Controller
-
前置 LVS + Keepalived 做负载均衡
-
配置 HPA(Horizontal Pod Autoscaler)自动扩缩容
3. 安全加固
-
使用有效的 TLS 证书
-
配置适当的访问控制(BasicAuth、IP白名单)
-
启用 WAF 和速率限制
-
定期更新 Ingress Controller 版本
4. 监控告警
yaml
# Prometheus 监控示例 annotations:prometheus.io/port: "10254"prometheus.io/scrape: "true"
九、总结
特性 | 说明 |
---|---|
定位 | Kubernetes 集群的七层流量入口 |
组成 | Ingress 资源 + Ingress Controller |
核心功能 | 域名路由、SSL终止、负载均衡 |
推荐部署 | DaemonSet + HostNetwork(生产) |
优势 | 统一入口、灵活路由、成本低 |
最佳实践:在生产环境中配合监控告警、证书管理、访问控制等机制,构建安全可靠的入口网关。