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(生产)
优势 统一入口、灵活路由、成本低

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

相关推荐
AlfredZhao37 分钟前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334667 小时前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪8 小时前
linux 拷贝文件或目录到指定的位置
linux
大树881 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠1 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质1 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
bush41 天前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行5201 天前
Linux 11 动态监控指令top
linux
Inhand陈工1 天前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
酣大智1 天前
ARP代理--工作原理
运维·网络·arp·arp代理