k8s(八)Ingress详解

文章目录

  • 前言
  • 一、k8s中的Ingress
    • [1.1 Ingress服务](#1.1 Ingress服务)
      • [1.1.1 为什么需要 Ingress?------ 先理解 k8s 服务暴露的痛点](#1.1.1 为什么需要 Ingress?—— 先理解 k8s 服务暴露的痛点)
      • [1.1.2 Ingress 的核心组成:2 个关键部分](#1.1.2 Ingress 的核心组成:2 个关键部分)
        • [1.1.2.1 Ingress 资源:定义路由规则](#1.1.2.1 Ingress 资源:定义路由规则)
          • [1.1.2.1.1 Ingress 工作原理](#1.1.2.1.1 Ingress 工作原理)
        • [1.1.2.2 Ingress Controller:执行路由规则](#1.1.2.2 Ingress Controller:执行路由规则)
    • [1.2 Ingress 的核心功能](#1.2 Ingress 的核心功能)
      • [1.2.1 关键区别:Ingress vs Service](#1.2.1 关键区别:Ingress vs Service)
    • [1.3 Ingress 的工作流程](#1.3 Ingress 的工作流程)
    • [1.4 部署ingress-nginx-controller(示例)](#1.4 部署ingress-nginx-controller(示例))
        • [1.4.1 准备与获取清单](#1.4.1 准备与获取清单)
        • [1.4.2 修改ClusterRole资源配置](#1.4.2 修改ClusterRole资源配置)
      • [1.5 Ingress暴露服务的三种方式(重点)](#1.5 Ingress暴露服务的三种方式(重点))
        • [1.5.1 方式一:Deployment + Service(type=LoadBalancer)](#1.5.1 方式一:Deployment + Service(type=LoadBalancer))
        • [1.5.2 方式二:DaemonSet + HostNetwork + nodeSelector(示例详解)](#1.5.2 方式二:DaemonSet + HostNetwork + nodeSelector(示例详解))
          • [1.5.2.1 给node打标签,仅在`node02`运行:](#1.5.2.1 给node打标签,仅在node02运行:)
          • [1.5.2.2 将**Deployment**改为**DaemonSet**,启用HostNetwork并指定node:](#1.5.2.2 将Deployment改为DaemonSet,启用HostNetwork并指定node:)
          • [1.5.2.3 在所有node上传镜像并加载:](#1.5.2.3 在所有node上传镜像并加载:)
          • [1.5.2.4 启动Controller,验证监听端口(在node02):](#1.5.2.4 启动Controller,验证监听端口(在node02):)
          • [1.5.2.5 创建ingress规则](#1.5.2.5 创建ingress规则)
          • [1.5.2.6 创建Ingress(两种API示例):](#1.5.2.6 创建Ingress(两种API示例):)
          • [1.5.2.7 测试:](#1.5.2.7 测试:)
        • [1.5.3 方式三:Deployment + Service(type=NodePort)](#1.5.3 方式三:Deployment + Service(type=NodePort))
          • [1.5.3.1 下载nginx-ingress-controller和ingress-nginx暴露端口配置文件](#1.5.3.1 下载nginx-ingress-controller和ingress-nginx暴露端口配置文件)
          • [1.5.3.2 示例:HTTP代理访问](#1.5.3.2 示例:HTTP代理访问)
          • [1.5.3.3 Ingress HTTP代理访问虚拟主机](#1.5.3.3 Ingress HTTP代理访问虚拟主机)
          • [1.5.3.4 示例:HTTPS代理访问](#1.5.3.4 示例:HTTPS代理访问)
          • [1.5.3.5 示例:BasicAuth认证](#1.5.3.5 示例:BasicAuth认证)
          • [1.5.3.6 示例:重写(Rewrite)](#1.5.3.6 示例:重写(Rewrite))
      • [1.6 常见检查与排错要点](#1.6 常见检查与排错要点)
      • [1.7 总结](#1.7 总结)
  • 结尾

前言

在 Kubernetes(k8s)集群的日常运维与服务管理中,"如何安全、高效地将内部服务暴露给外部访问" 是核心需求之一。随着集群内微服务数量增多,传统的 NodePort 端口管理混乱、LoadBalancer 成本高昂等问题逐渐凸显,而 Ingress 作为七层反向代理解决方案,凭借 "统一入口、动态路由、灵活扩展" 的特性,成为解决这一痛点的关键技术。

本文将从 Ingress 的核心概念入手,系统梳理其与 Service 的区别、核心组成与工作原理,再通过详细的部署示例(包括 HostNetwork、NodePort、LoadBalancer 三种暴露方式),带您掌握 Ingress 的实际应用,并提供常见排错思路,为集群外部流量管理提供完整的技术参考。

一、k8s中的Ingress

在 Kubernetes 中:

  • Pod IPService 的 ClusterIP 仅在集群内部可见。
  • 为了让外部应用访问集群内服务,K8s 提供了多种方案:

1)NodePort

  • 将 Service 暴露在节点网络 上(由 kube-proxy 负责连接 service / pod / 节点网络)。
  • 适合测试;当服务数量多,端口管理困难 (端口范围固定为 30000-32767,且每个端口仅服务一种服务)。

2)LoadBalancer

  • 需要云厂商支持,K8s 调用 CloudProvider 在公有云创建 LB,并将后端指向 Pod IP;
  • 通常需要额外费用 ;更适合公有云

3)externalIPs

  • 为 service 分配外部 IP;当该 IP 路由到集群节点,流量将被路由到 Service 的 Endpoints。

4)Ingress(七层反向代理)

  • 仅用一个或少量的公网 IP/LB ,即可同时将多个 HTTP/HTTPS 服务暴露到外网;
  • 可理解为"service 的 service ":基于域名/URL 路径将请求转发到一个或多个 service。

1.1 Ingress服务

在 Kubernetes(k8s)生态中,Ingress 是实现集群外部流量(如来自互联网的 HTTP/HTTPS 请求)路由到集群内部服务(Service)的核心资源,本质是一套"流量入口规则定义"和"统一入口管理"的解决方案。

1.1.1 为什么需要 Ingress?------ 先理解 k8s 服务暴露的痛点

在 Ingress 出现前,k8s 暴露服务到集群外主要依赖 NodePortLoadBalancer,但这两种方式存在明显局限:

  • NodePort:为每个服务分配集群节点的随机端口(30000-32767),端口管理混乱,且无法直接处理域名、HTTPS 等场景;
  • LoadBalancer:依赖云厂商的负载均衡器(如 AWS ELB、阿里云 SLB),每个服务需单独创建一个 LoadBalancer,成本高、资源浪费严重。

Ingress 正是为解决这些痛点而生:它通过一个统一的入口(Ingress Controller) ,集中管理所有外部流量的路由规则,支持域名、路径、HTTPS、负载均衡等高级功能,实现"一个入口管所有服务"。

1.1.2 Ingress 的核心组成:2 个关键部分

Ingress 并非单一组件,而是由"规则定义 "和"规则执行"两部分协同工作:

组成部分 作用 类比场景
Ingress 资源 是 k8s 中的一种 CRD(自定义资源),用于声明式定义路由规则(如"xxx.com/abc 路由到服务 A") 相当于"交通指挥手册"
Ingress Controller 是实际"执行规则"的组件(通常是一个运行在集群内的 Pod),监听 Ingress 资源变化并转发流量 相当于"交通指挥员"
1.1.2.1 Ingress 资源:定义路由规则

Ingress 资源通过 YAML 文件声明路由逻辑,核心配置包括:

  • 域名(host) :指定外部请求的域名(如 example.com);
  • 路径(paths) :指定域名下的具体路径(如 /api/web);
  • 后端服务(backend):对应路径要转发到的集群内 Service 及端口;
  • TLS 配置:用于 HTTPS 加密(指定证书 Secret)。
1.1.2.1.1 Ingress 工作原理
  1. Ingress Controller 与 APIServer 交互,动态的去感知 Ingress 规则变化;
  2. 读取规则并按自定义模板生成 Nginx 配置
  3. 再写到nginx-ingress-controller的pod里,这个ingress-controller的pod里运行着一个Nginx服务,控制器会把生成的 nginx配置写入 /etc/nginx.conf文件中
  4. 执行 reload 使配置生效,实现按域名分流与动态更新。
1.1.2.2 Ingress Controller:执行路由规则

Ingress 资源本身只是"规则文本",必须通过 Ingress Controller 才能生效。它的核心工作流程是:

  1. 监听:通过 k8s API 监听 Ingress 资源、Service、Endpoint 的变化;
  2. 生成配置 :根据 Ingress 规则,动态生成反向代理配置(如 Nginx 的 nginx.conf);
  3. 转发流量:对外暴露一个固定入口(通常是 NodePort 或 LoadBalancer),接收外部流量并按规则转发到内部 Service。

主流 Ingress Controller 实现

  • Nginx Ingress Controller:基于 Nginx 反向代理,最常用、生态最成熟;
  • Traefik:云原生设计,支持自动发现、动态配置,适合微服务场景;
  • HAProxy Ingress:基于 HAProxy,性能优异,适合高并发场景;
  • Istio Ingress Gateway:属于服务网格(Istio)的一部分,支持更复杂的流量治理(如灰度发布、流量镜像)。

1.2 Ingress 的核心功能

Ingress 不仅解决"统一入口"问题,还支持多种高级流量管理能力:

  1. 域名路由 :将不同域名的请求转发到不同服务(如 api.example.com 到 API 服务,web.example.com 到 Web 服务);
  2. 路径路由 :同一域名下,按路径转发到不同服务(如 example.com/api 到 API 服务,example.com/web 到 Web 服务);
  3. HTTPS 终结:在 Ingress Controller 层统一处理 HTTPS 加密/解密(证书存储在 k8s Secret 中),内部服务无需关心加密;
  4. 负载均衡:自动为后端多个 Pod 分配流量(依赖 Service 的 Endpoint 列表);
  5. 路径重写 :将外部路径(如 /v1/api)重写为内部服务期望的路径(如 /api);
  6. 访问控制 :支持基于 IP、HTTP 头的黑白名单(如 Nginx Ingress 的 nginx.ingress.kubernetes.io/whitelist-source-range 注解);
  7. 限流与缓存:部分控制器(如 Nginx Ingress)支持对请求限流、静态资源缓存,减轻后端服务压力。

1.2.1 关键区别:Ingress vs Service

很多初学者会混淆 Ingress 和 Service,两者的核心区别如下:

维度 Ingress Service
作用范围 集群外部流量的"入口路由管理" 集群内部/外部流量的"服务发现与负载均衡"
流量类型 仅支持 HTTP/HTTPS(部分支持 TCP/UDP) 支持 TCP/UDP/HTTP 等所有协议
依赖关系 依赖 Service(路由最终指向 Service) 直接关联 Pod(通过标签选择器)
核心能力 域名、路径路由、HTTPS 等高级规则 固定访问地址(ClusterIP)、负载均衡

简单来说:Service 是"服务的地址",Ingress 是"如何找到这个地址的导航"

1.3 Ingress 的工作流程

以"用户访问 example.com/api"为例,完整流程如下:

  1. 用户在浏览器输入 example.com/api,DNS 将域名解析到 Ingress Controller 的外部 IP(通常是云厂商 LoadBalancer 的 IP,或集群节点的 IP+NodePort);
  2. 流量到达 Ingress Controller(运行在集群内的 Pod);
  3. Ingress Controller 检查已配置的 Ingress 规则,发现 example.com/api 需转发到 api-service:80
  4. Ingress Controller 查询 api-service 对应的 Endpoint(即后端 Pod 的 IP 列表);
  5. Ingress Controller 将流量转发到其中一个 api-service 关联的 Pod;
  6. Pod 处理请求后,将响应通过 Ingress Controller 回传给用户。

1.4 部署ingress-nginx-controller(示例)

以下示例以ingress-nginx为例,展示多种对外暴露方式。

1.4.1 准备与获取清单
bash 复制代码
mkdir -p /opt/ingress && cd /opt/ingress
# 官方:
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.25.0/deploy/static/mandatory.yaml
# 国内镜像:
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.25.0/deploy/static/mandatory.yaml
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml

说明:mandatory.yaml文件中包含了很多资源的创建,包括namespace、ConfigMap、role,ServiceAccount等等所有部署ingress-controller需要的资源。

1.4.2 修改ClusterRole资源配置

mandatory.yaml中将Ingress资源权限加入networking.k8s.io(0.25版本开始):

yaml 复制代码
vim mandatory.yaml
......
apiVersion: rbac.authorization.k8s.io/v1
#RBAC相关资源从1.17版本开始改用rbac.authorization.k8s.io/v1,rbac.authorization.k8s.io/v1beta1在1.22版本即将弃用
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

1.5 Ingress暴露服务的三种方式(重点)

1.5.1 方式一:Deployment + Service(type=LoadBalancer)
  • 适合公有云:LB自动创建并绑定公网;将域名解析指向该地址即可对外暴露。

  • 如果要把ingress部署在公有云,那用这种方式比较合适。用Deployment部署ingress-controller,创建一个type为LoadBalancer的service关联这组pod。大部分公有云,都会为LoadBalancer的service自动创建一个负载均衡器,通常还绑定了公网地址。只要把域名解析指向该地址,就实现了集群服务的对外暴露。

1.5.2 方式二:DaemonSet + HostNetwork + nodeSelector(示例详解)
  • 特定节点DaemonSet 方式部署Controller,并使用HostNetwork与宿主机网络打通;
  • 直接占用宿主机80/443
  • 链路最短、性能最好 ;一个node仅能运行一个Controller Pod;适合大并发生产

详解:DaemonSet结合nodeselector来部署ingress-controller到特定的node上,然后使用HostNetwork直接把该pod与宿主机node的网络打通,直接使用宿主机的80/433端口就能访问服务。这时,ingress-controller所在的node机器就很类似传统架构的边缘节点,比如机房入口的nginx服务器。该方式整个请求链路最简单,性能相对NodePort模式更好。缺点是由于直接利用宿主机节点的网络和端口,一个node只能部署一个ingress-controller pod。 比较适合大并发的生产环境使用。

实施步骤:

1.5.2.1 给node打标签,仅在node02运行:
bash 复制代码
kubectl label node node02 ingress=true
kubectl get nodes --show-labels
1.5.2.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
......
1.5.2.3 在所有node上传镜像并加载:
bash 复制代码
cd /opt/ingress
# 假设已有压缩包 ingree.contro.tar.gz
tar zxvf ingree.contro.tar.gz
docker load -i ingree.contro.tar
1.5.2.4 启动Controller,验证监听端口(在node02):
bash 复制代码
kubectl get pod -n ingress-nginx -o wide
kubectl get cm,daemonset -n ingress-nginx -o wide
netstat -lntp | grep nginx
# 在node02查看,期望监听:80 / 443 / 8181 / 10254


说明:8181为默认backend端口(未匹配到规则时流量进入此处)。若需高可用,可在多节点部署,并在前面加LVS + keepalived做负载均衡。

1.5.2.5 创建ingress规则
yaml 复制代码
###创建一个 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
1.5.2.6 创建Ingress(两种API示例):
yaml 复制代码
# 方法一:extensions/v1beta1(1.22 即将弃用)
vim ingress-app.yaml	
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-app-ingress
spec:
  rules:
  - host: www.benet.com
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-app-svc
          servicePort: 80
# 方法二:networking.k8s.io/v1(推荐)
vim ingress-app.yaml	
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-app-ingress
spec:
  rules:
  - host: www.mgb.com
    http:
      paths:
      - path: /
        pathType: Prefix  # 也可使用 Exact
        backend:
          service:
            name: nginx-app-svc
            port:
              number: 80

路径匹配:

  • Prefix:基于前缀匹配,如/0805可匹配/0805、/0805/yjs/0805/yjs/zjl`。
  • Exact:完全匹配,如/0805只能匹配/0805
1.5.2.7 测试:
bash 复制代码
kubectl apply -f service-nginx.yaml
kubectl apply -f ingress-app.yaml
kubectl get ingress
# /etc/hosts 添加解析:
# 192.168.10.127 www.mgb.com
curl www.mgb.com

可进入Controller Pod查看生成的/etc/nginx/nginx.conf,确认server www.mgb.com段落。

1.5.3 方式三:Deployment + Service(type=NodePort)
  • 以Deployment部署Controller,并创建NodePort类型的 Service暴露;
  • 由于NodePort是随机端口,通常前置一层负载均衡
  • 多一层NAT,大流量场景可能影响性能。

实施步骤:

1.5.3.1 下载nginx-ingress-controller和ingress-nginx暴露端口配置文件
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
1.5.3.2 示例: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.benet.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-svc
            port:
              number: 80

部署与测试:

bash 复制代码
kubectl apply -f ingress-nginx.yaml
kubectl get svc -n ingress-nginx
# 假设 NodePort 为 80:32383/TCP
# hosts 添加:192.168.10.120 www.mgb.com
curl http://www.mgb.com:31905

可以在两个Pod内修改index.html以区分返回:this is web1/web2

1.5.3.3 Ingress HTTP代理访问虚拟主机
bash 复制代码
mkdir /opt/ingress-nodeport/vhost
cd /opt/ingress-nodeport/vhost
yaml 复制代码
# 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
yaml 复制代码
# 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
yaml 复制代码
# ingress-nginx.yaml(双主机名)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress1
spec:
  rules:
    - host: www1.mgb.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.mgb.com
      http:
        paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: svc-2
              port:
                number: 80

测试:

bash 复制代码
# NodePort 假设为 32383
curl www1.mgb.com:32383
curl www2.mgb.com:32383
1.5.3.4 示例: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
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.mgb.com
      secretName: tls-secret
  rules:
    - host: www3.mgb.com
      http:
        paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: nginx-svc-01
              port:
                number: 80
bash 复制代码
kubectl apply -f ingress-https.yaml

kubectl get svc -n ingress-nginx

测试:

bash 复制代码
# NodePort 假设 443:32336
# hosts 添加:192.168.10.126 www3.mgb.com
# 浏览器访问:https://www3.mgb.com:32336
1.5.3.5 示例: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
yaml 复制代码
# 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.mgb.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-svc
            port:
              number: 80

参考:https://kubernetes.github.io/ingress-nginx/examples/auth/basic/

1.5.3.6 示例:重写(Rewrite)
  • 常用注解:
    • 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.mgb.com:31905
spec:
  rules:
  - host: re.mgb.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          # 仅用于跳转,svc 名可随意
          service:
            name: nginx-svc
            port:
              number: 80

测试:

bash 复制代码
# hosts 添加:192.168.10.126 re.mgb.com
# 浏览器访问:http://re.mgb.com:31905cu

1.6 常见检查与排错要点

  • 查看Controller运行与端口
bash 复制代码
kubectl get pod -n ingress-nginx -o wide
kubectl get cm,daemonset -n ingress-nginx -o wide
netstat -lntp | grep nginx
  • 进入Pod检查Nginx配置
bash 复制代码
kubectl exec -it <controller-pod> -n ingress-nginx -- /bin/bash
more /etc/nginx/nginx.conf
# 查找:start server <host> ... end server <host>
  • 调度失败 (nodeSelector不匹配):
    • 给目标节点加对应标签,或删除YAML中的nodeSelector

1.7 总结

  • Ingress 是K8s集群对外的请求入口,对多个service进行再抽象;
  • 一般所称Ingress 包含两部分:Ingress资源对象 +Ingress Controller
  • Controller有多种实现(社区原生ingress-nginx等),按需求选择;
  • 对外暴露可选LoadBalancer / HostNetwork(DaemonSet)/ NodePort 等方式,需结合基础环境与业务选择;
  • 生产常用方案:DaemonSet + HostNetwork (高性能)或公有云LB(便捷托管)。

建议:在生产中配合多节点部署 + 前置LB / Anycast / eBPF LB 与完善的监控/告警(Prometheus采集10254),并对证书与访问控制(TLS、BasicAuth、WAF/限速)进行加固。

结尾

通过本文的梳理与实践,我们可以清晰地看到:Ingress 并非单一组件,而是 "规则定义(Ingress 资源)+ 规则执行(Ingress Controller)" 的协同体系。它不仅解决了传统服务暴露方式的痛点,更通过域名路由、HTTPS 终结、访问控制等高级功能,为 k8s 集群的外部流量管理提供了灵活且可扩展的方案。

在实际生产环境中,Ingress 的选型与部署需结合业务场景:公有云环境优先选择 LoadBalancer 方式以简化运维,大并发场景推荐 DaemonSet + HostNetwork 以保障性能,测试或小规模集群可使用 NodePort 快速验证。同时,配合多节点部署、前置负载均衡(如 LVS、云厂商 LB)及监控告警(如 Prometheus 采集 Controller metrics),能进一步提升 Ingress 服务的稳定性与安全性。

随着云原生技术的发展,Ingress 也在不断演进(如结合 ServiceMesh 实现更精细的流量治理),掌握其核心原理与实践方法,将为后续集群架构的优化与扩展奠定重要基础。

相关推荐
水上冰石29 分钟前
查看k8s下Jenkins的插件在宿主机的路径
容器·kubernetes·jenkins
孤岛悬城30 分钟前
58 k8s之pod
云原生·容器·kubernetes
可爱又迷人的反派角色“yang”35 分钟前
k8s(五)
linux·运维·docker·云原生·容器·kubernetes
oMcLin36 分钟前
如何在Ubuntu 22.10上通过配置K3s轻量级Kubernetes集群,提升边缘计算环境的资源管理能力?
ubuntu·kubernetes·边缘计算
optimistic_chen1 小时前
【Docker入门】容器技术
linux·运维·服务器·docker·容器
小明_GLC1 小时前
理解Docker、镜像Images、容器Container
docker·容器
努力搬砖的咸鱼1 小时前
用 Docker 部署你的第一个微服务
docker·微服务·云原生·容器
水上冰石1 小时前
如何查看k8s按照的jenkins插件的路径
容器·kubernetes·jenkins
鱼跃鹰飞1 小时前
经典面试题:K8S的自动缩扩容和崩溃恢复
java·容器·kubernetes
江湖有缘1 小时前
Fenrus + Docker 实战:构建简洁高效的浏览器新标签页
运维·docker·容器