K8s Ingress 详解与部署实战

前言

[一、Ingress 基本概念](#一、Ingress 基本概念)

[1. Ingress 是什么?](#1. Ingress 是什么?)

[2. 为什么需要 Ingress?](#2. 为什么需要 Ingress?)

[二、Ingress 核心组成](#二、Ingress 核心组成)

[1. Ingress 资源对象(规则定义)](#1. Ingress 资源对象(规则定义))

[2. Ingress Controller(规则执行器)](#2. Ingress Controller(规则执行器))

[三、Ingress 工作原理](#三、Ingress 工作原理)

[四、Ingress 暴露服务方式](#四、Ingress 暴露服务方式)

[✅ 方式一:Deployment + LoadBalancer Service](#✅ 方式一:Deployment + LoadBalancer Service)

[✅ 方式二:DaemonSet + HostNetwork + nodeSelector(推荐生产)](#✅ 方式二:DaemonSet + HostNetwork + nodeSelector(推荐生产))

[1. 节点打标签](#1. 节点打标签)

[2. 修改部署文件 (将 Deployment 改为 DaemonSet,启用 HostNetwork 并指定 node)](#2. 修改部署文件 (将 Deployment 改为 DaemonSet,启用 HostNetwork 并指定 node))

[3. 验证部署](#3. 验证部署)

4.创建ingress规则

6.创建ingress

[✅ 方式三:Deployment + NodePort Service](#✅ 方式三:Deployment + NodePort Service)

[五、Deployment + NodePort Service 配置案例](#五、Deployment + NodePort Service 配置案例)

[1. HTTP 代理访问](#1. HTTP 代理访问)

[补充:Ingress HTTP 代理访问虚拟主机](#补充:Ingress HTTP 代理访问虚拟主机)

[2. HTTPS 代理访问](#2. HTTPS 代理访问)

[3. BasicAuth 认证](#3. BasicAuth 认证)

[4. 路径重写](#4. 路径重写)

[5. 路径匹配类型](#5. 路径匹配类型)

六、故障排查与监控

[1. 常用检查命令](#1. 常用检查命令)

[2. 常见问题排查](#2. 常见问题排查)

八、生产环境建议

[1. 部署架构选择](#1. 部署架构选择)

[2. 高可用方案](#2. 高可用方案)

[3. 安全加固](#3. 安全加固)

[4. 监控告警](#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-clusterrole
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
rules:
  - apiGroups:
      - ""
    resources:
      - configmaps
      - endpoints
      - nodes
      - pods
      - secrets
    verbs:
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - nodes
    verbs:
      - get
  - apiGroups:
      - ""
    resources:
      - services
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - "extensions"
      - "networking.k8s.io"    # (0.25版本)增加 networking.k8s.io Ingress 资源的 api 
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - events
    verbs:
      - create
      - patch
  - apiGroups:
      - "extensions"
      - "networking.k8s.io"   # (0.25版本)增加 networking.k8s.io/v1 Ingress 资源的 api 
    resources:
      - ingresses/status
    verbs:
      - update

2. Ingress Controller(规则执行器)

  • 作用:实际处理流量的组件

  • 功能:监控 Ingress 规则变化,生成配置并执行

  • 常见实现

    • ingress-nginx(官方维护)

    • Traefik

    • HAProxy Ingress

    • Istio Gateway

重要:Ingress Controller 才是真正的流量入口,Ingress 对象只是告诉 Controller 如何转发


三、Ingress 工作原理

详细流程:

  1. Controller 通过 API Server 监听 Ingress 资源变化

  2. 读取所有 Ingress 规则,生成对应的 Nginx 配置

  3. 将配置写入 Controller Pod 的 /etc/nginx/nginx.conf

  4. 执行 nginx -s reload 重新加载配置

  5. 外部请求到达时,按配置规则进行路由转发


四、Ingress 暴露服务方式

✅ 方式一:Deployment + LoadBalancer Service

适用场景:公有云环境

架构特点

  • 云厂商自动创建负载均衡器

  • LB 绑定公网 IP,域名解析指向该 IP

  • 全托管,配置简单

部署示例

yaml

复制代码
apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
spec:
  type: LoadBalancer
  ports:
  - port: 80
    targetPort: 80
  selector:
    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-controller
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
# 删除Replicas
# replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: ingress-nginx
      app.kubernetes.io/part-of: ingress-nginx
  template:
    metadata:
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
      annotations:
        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: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-app-svc
spec:
  type: ClusterIP
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  selector:
    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.com
    http:
      paths:
      - path: /
        pathType: Prefix  # 也可使用 Exact
        backend:
          service:
            name: nginx-app-svc
            port:
              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: 2
  selector:
    matchLabels:
      name: nginx
  template:
    metadata:
      labels:
        name: nginx
    spec:
      containers:
        - name: nginx
          image: nginx
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  selector:
    name: nginx
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-test
spec:
  rules:
  - host: www.uuz.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-svc
            port:
              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: 2
  selector:
    matchLabels:
      name: nginx1
  template:
    metadata:
      labels:
        name: nginx1
    spec:
      containers:
        - name: nginx1
          image: soscscs/myapp:v1
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: svc-1
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  selector:
    name: nginx1
    
    
# deployment2.yaml(v2)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment2
spec:
  replicas: 2
  selector:
    matchLabels:
      name: nginx2
  template:
    metadata:
      labels:
        name: nginx2
    spec:
      containers:
        - name: nginx2
          image: soscscs/myapp:v2
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: svc-2
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  selector:
    name: nginx2
    
    
# ingress-nginx.yaml(双主机名)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress1
spec:
  rules:
    - host: www1.uuz.com
      http:
        paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: svc-1
              port:
                number: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress2
spec:
  rules:
    - host: www2.uuz.com
      http:
        paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: svc-2
              port:
                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: 2
  selector:
    matchLabels:
      name: nginx
  template:
    metadata:
      labels:
        name: nginx
    spec:
      containers:
        - name: nginx
          image: nginx
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc-01
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  selector:
    name: nginx
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-https
spec:
  tls:
    - hosts:
      - www3.uuz.com
      secretName: tls-secret
  rules:
    - host: www3.uuz.com
      http:
        paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: nginx-svc-01
              port:
                number: 80
 
kubectl apply -f ingress-https.yaml

kubectl 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-auth
  annotations:
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - zhangsan'
spec:
  rules:
  - host: auth.uuz.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-svc
            port:
              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-rewrite
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: http://www1.uuz.com:32383
spec:
  rules:
  - host: re.uuz.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          # 仅用于跳转,svc 名可随意
          service:
            name: nginx-svc
            port:
              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(生产)
优势 统一入口、灵活路由、成本低

最佳实践:在生产环境中配合监控告警、证书管理、访问控制等机制,构建安全可靠的入口网关。

相关推荐
塔能物联运维3 小时前
物联网运维中的边缘计算任务调度优化策略
运维·人工智能·物联网·边缘计算
望获linux3 小时前
【实时Linux实战系列】实时 Linux 在边缘计算网关中的应用
java·linux·服务器·前端·数据库·操作系统
真正的醒悟3 小时前
什么是网络割接
运维·服务器·网络
Bruce_Liuxiaowei3 小时前
Win7虚拟机加入域错误排查指南:解决无法启动服务问题
运维·网络·windows·安全·网络安全
聆风吟º3 小时前
无需 VNC / 公网 IP!用 Docker-Webtop+cpolar,在手机浏览器远程操控 Linux
linux·运维·docker
骇客野人4 小时前
【软考备考】 高并发场景如何做负载均衡知识点四
运维·负载均衡
deng-c-f4 小时前
Linux C/C++ 学习日记(22):Reactor模式(二):实现简易的webserver(响应http请求)
linux·c语言·网络编程·reactor·http_server
BTU_YC4 小时前
CentOS 7 虚拟IP配置指南:使用传统network-scripts实现高可用
linux·tcp/ip·centos
陌路204 小时前
LINUX14 进程间的通信 - 管道
linux·网络