K8s进阶之初识Ingress

概述

官方文档:https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/

Service对集群之外暴露服务的主要方式有两种:NotePort和LoadBalancer,但是这两种方式,都有一定的缺点:

  • NodePort方式的缺点是会占用很多集群机器的端口,那么当集群服务变多的时候,这个缺点就愈发明显
  • LB方式的缺点是每个service需要一个LB,浪费、麻烦,并且需要kubernetes之外设备的支持

基于这种现状,kubernetes提供了Ingress资源对象,Ingress只需要一个NodePort或者一个LB就可以满足暴露多个Service的需求。工作机制大致如下图表示:
image

实际上,Ingress相当于一个7层的负载均衡器,是kubernetes对反向代理的一个抽象,它的工作原理类似于Nginx,可以理解成在Ingress里建立诸多映射规则,Ingress Controller通过监听这些配置规则并转化成Nginx的反向代理配置 , 然后对外部提供服务。在这里有两个核心概念:

  • ingress:kubernetes中的一个对象,作用是定义请求如何转发到service的规则
  • ingress controller:具体实现反向代理及负载均衡的程序,对ingress定义的规则进行解析,根据配置的规则来实现请求转发,实现方式有很多,比如Nginx, Contour, Haproxy等等

Ingress的工作原理如下:

  • 用户编写Ingress规则,说明哪个域名对应kubernetes集群中的哪个Service
  • Ingress控制器动态感知Ingress服务规则的变化,然后生成一段对应的Nginx反向代理配置
  • Ingress控制器会将生成的Nginx配置写入到一个运行着的Nginx服务中,并动态更新
  • 到此为止,其实真正在工作的就是一个Nginx了,内部配置了用户定义的请求转发规则

image

Ingress-nginx介绍

项目地址:https://github.com/kubernetes/ingress-nginx
文档教程:https://kubernetes.github.io/ingress-nginx/

ingress-nginxKubernetesIngress 控制器,使用NGINX作为反向代理和负载均衡器。

部署MetalLB

参考这篇文章:K8s进阶之MetalLB实现LoadBalancer

部署Ingress-nginx

选择版本

我的k8s版本是1.26,所以我选择v1.11.6版本
image

部署方式

Ingress-nginx部署方式有三种,分别是Helmkubectl以及使用第三方插件的方式进行安装。
image

基于kubectl进行部署

# 下载配置文件
[root@master01 ~/ingress]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.6/deploy/static/provider/cloud/deploy.yaml

# 将ingress-nginx-controller的类型修改为LoadBalancer(原来为LoadBalancer,以防万一)
[root@master01 ~/ingress]# sed -i s#NodePort#LoadBalancer#g deploy.yaml

# 开始部署应用
[root@master01 ~/ingress]# kubectl apply -f deploy.yaml

# 检查资源
[root@master01 ~/ingress]# kubectl get all -n ingress-nginx
# pod资源
NAME                                            READY   STATUS      RESTARTS   AGE
pod/ingress-nginx-admission-create-p87gx        0/1     Completed   0          10m
pod/ingress-nginx-admission-patch-87g8d         0/1     Completed   2          10m
pod/ingress-nginx-controller-58554b9b99-x8gdr   1/1     Running     0          10m

# service资源
NAME                                         TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)                      AGE
service/ingress-nginx-controller             LoadBalancer   10.96.3.174   10.0.0.150     80:32543/TCP,443:32705/TCP   3m30s
service/ingress-nginx-controller-admission   ClusterIP      10.96.1.131   <none>        443/TCP                      3m30s

# deployment资源
NAME                                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/ingress-nginx-controller   1/1     1            1           10m

# replicaSet资源
NAME                                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/ingress-nginx-controller-58554b9b99   1         1         1       10m

# job资源
NAME                                       COMPLETIONS   DURATION   AGE
job.batch/ingress-nginx-admission-create   1/1           18s        10m
job.batch/ingress-nginx-admission-patch    1/1           28s        10m

上述资源解释

Pods
  • ingress-nginx-admission-create
    类型:Job 创建的 Pod(已完成)
    作用:初始化 Ingress Nginx 的准入控制器配置,例如创建验证 Webhook 所需的证书和配置。完成后自动退出(状态为 Completed)。

  • ingress-nginx-admission-patch
    类型:Job 创建的 Pod(已完成)
    作用:修补 Ingress Nginx 控制器的配置,确保它能正确与准入控制器通信。完成后自动退出。

  • ingress-nginx-controller
    类型:Deployment 管理的 Pod(运行中)
    核心作用:作为 Ingress 控制器,负责监听 Kubernetes Ingress 资源的变化,并根据规则将外部流量路由到集群内的服务。
    工作方式:通过 NodePort 或 LoadBalancer 类型的 Service 暴露到集群外部。

service

ingress-nginx-controller

  • 类型:NodePort(原为 LoadBalance)
  • 作用:将 Ingress 控制器暴露到集群外部。
  • 80:32055/TCP:HTTP 端口,外部请求通过节点的 32055 端口转发到控制器的 80 端口。
  • 443:32405/TCP:HTTPS 端口,外部请求通过节点的 32405 端口转发到控制器的 443 端口。
  • 注意:在裸机环境中,LoadBalancer 类型的 Service 无法自动分配外部 IP,需手动配置(如使用 MetalLB)或切换为 NodePort。

ingress-nginx-controller-admission

  • 类型:ClusterIP
  • 作用:作为准入控制器的内部通信端点,用于验证和校验 Ingress 资源的创建或更新请求(通过 Webhook)。
Jobs

ingress-nginx-admission-create

  • 作用:创建准入控制器所需的证书和配置,确保 Ingress 资源验证的安全性。
  • 状态:COMPLETIONS 1/1 表示任务已成功完成。

ingress-nginx-admission-patch

  • 作用:修补 Ingress 控制器的配置,确保其与准入控制器正确集成。
  • 状态:COMPLETIONS 1/1 表示任务已成功完成。

创建ingress的资源配置文件详解

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: comprehensive-ingress
  namespace: default
  annotations:
    # 基础配置
    kubernetes.io/ingress.class: "nginx"                     # 指定 Ingress 控制器
    nginx.ingress.kubernetes.io/ssl-redirect: "true"         # 强制 HTTPS 重定向
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"   # 即使无 TLS 也重定向
    nginx.ingress.kubernetes.io/proxy-body-size: "50m"      # 请求体大小限制
    
    # 性能优化
    nginx.ingress.kubernetes.io/proxy-read-timeout: "180"   # 代理读取超时
    nginx.ingress.kubernetes.io/proxy-send-timeout: "180"   # 代理发送超时
    nginx.ingress.kubernetes.io/proxy-buffer-size: "16k"    # 代理缓冲区大小
    
    # 安全配置
    nginx.ingress.kubernetes.io/enable-cors: "true"          # 启用 CORS
    nginx.ingress.kubernetes.io/cors-allow-origin: "*"       # CORS 允许源
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, OPTIONS"  # CORS 允许方法
    
    # 会话亲和性(Sticky Session)
    nginx.ingress.kubernetes.io/affinity: "cookie"           # 基于 Cookie 的会话亲和性
    nginx.ingress.kubernetes.io/session-cookie-name: "route" # 会话 Cookie 名称
    nginx.ingress.kubernetes.io/session-cookie-hash: "sha1"  # 会话 Cookie 哈希算法
    
    # 负载均衡策略
    nginx.ingress.kubernetes.io/load-balance: "round_robin"  # 轮询负载均衡
    # nginx.ingress.kubernetes.io/load-balance: "ip_hash"    # IP 哈希负载均衡
    
    # 自定义 Nginx 配置
    nginx.ingress.kubernetes.io/configuration-snippet: |
      add_header X-Content-Type-Options nosniff;
      add_header X-Frame-Options "SAMEORIGIN";
      add_header X-XSS-Protection "1; mode=block";
spec:
  ingressClassName: nginx  # 指定 Ingress 类(与 annotation 作用相同)
  
  # TLS 配置(HTTPS)
  tls:
  - hosts:
    - www.example.com      # 域名
    - api.example.com
    secretName: example-tls-secret  # 存储 TLS 证书的 Secret 名称
  
  # 路由规则
  rules:
  - host: www.example.com
    http:
      paths:
      # 静态资源路径
      - path: /static
        pathType: Prefix
        backend:
          service:
            name: static-service
            port:
              number: 80
              
      # 应用主页路径
      - path: /
        pathType: Prefix
        backend:
          service:
            name: webapp-service
            port:
              number: 8080
              
  - host: api.example.com
    http:
      paths:
      # API 网关路径
      - path: /v1
        pathType: Prefix
        backend:
          service:
            name: api-gateway-service
            port:
              number: 8081
              
      # 特殊路径 - 重写配置
      - path: /legacy(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: legacy-service
            port:
              number: 8082
          # 路径重写:移除 /legacy 前缀
          annotations:
            nginx.ingress.kubernetes.io/rewrite-target: /$2
            
      # 特殊路径 - 自定义超时
      - path: /long-running
        pathType: Prefix
        backend:
          service:
            name: batch-service
            port:
              number: 8083
          # 为特定路径设置更长的超时时间
          annotations:
            nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
            nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
            
  # 默认后端(当所有规则都不匹配时)
  defaultBackend:
    service:
      name: default-service
      port:
        number: 80

pathType规则

Kubernetes Ingress 中,pathType 是一个关键配置项,用于定义路径匹配的方式。
path其中pathType字段有三个值:

  • Exact:精确匹配整个路径,区分大小写,不考虑查询参数。
  • Prefix:前缀匹配路径,会递归检查子路径,但必须以指定路径开头。
  • ImplementationSpecific:由 Ingress 控制器自行决定匹配方式,不同控制器可能有不同实现,Nginx Ingress 控制器将其视为 Prefix 类型

路径匹配优先级规则

  • Exact 类型优先于 Prefix 类型:
    如果存在 /api(Prefix)/api/users(Exact),则 /api/users 请求会匹配到 Exact 规则。
  • 较长的 Prefix 优先于较短的 Prefix:
    /api/v2 优先于 /api,即使它们都是 Prefix 类型。
  • ImplementationSpecific 由控制器自行排序:通常作为 Prefix 处理,但具体取决于控制器实现。

Ingress初体验实战

创建deployment和service

[root@master01 ~/ingress]# cat nginx-deploy.yaml
# service
apiVersion: v1
kind: Service
metadata:
  namespace: default
  name: nginx-svc-clusterip
spec:
  type: ClusterIP
  selector:
    app: nginx
  ports:
  - name: clusterip-nginx
    port: 6789
    targetPort: 80
    protocol: TCP

---
# deploy
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-nginx
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      name: pod-nginx
      labels:
        app: nginx
    spec:
      containers:
      - name: container-nginx
        image: nginx:1.14.1
      restartPolicy: Always

创建ingress

# 定义资源文件
[root@master01 ~/ingress]# cat app-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  # 和service在一个命名空间
  namespace: default
spec:
  ingressClassName: nginx
  rules:
    # 域名
  - host: app.huangsir.com
    # http配置
    http:
      paths:
        # 指定连接后端的方式
      - backend:
          #指定service
          service:
            # 指定service的名称
            name: nginx-svc-clusterip
            # 指定端口,将流量转发到后端指定的端口,因为后端service的端口是80,所以这里是80,注意,这里不是访问的端口
            port:
              number: 80
        # 指定匹配方式
        pathType: Prefix
        # 匹配路径
        path: /
		
# 创建Ingress
[root@master01 ~/ingress]# kubectl apply -f app-ingress.yaml
ingress.networking.k8s.io/app-ingress created

查看创建的Ingress

# 获取ingress
[root@master01 ~/ingress]# kubectl get ing -o wide
NAME          CLASS   HOSTS              ADDRESS   PORTS   AGE
app-ingress   nginx   app.huangsir.com             80      12s
# 查看详情
[root@master01 ~/ingress]# kubectl describe ing app-ingress
Name:             app-ingress
Labels:           <none>
Namespace:        default
Address:          10.96.2.89
Ingress Class:    nginx
Default backend:  <default>
Rules:
  Host              Path  Backends
  ----              ----  --------
  app.huangsir.com
                    /   nginx-svc-clusterip:80 ()
Annotations:        <none>
Events:
  Type    Reason  Age                From                      Message
  ----    ------  ----               ----                      -------
  Normal  Sync    43s (x2 over 83s)  nginx-ingress-controller  Scheduled for sync

访问测试

使用浏览器访问
http://app.huangsir.com
image

进入ingress-controller查看对应的配置

从这里可以看到,当我们创建ingress时,其会自动将对应的配置映射到ingress-nginx-controller的nginx.conf配置文件中

# 进入ingress-controller容器内部
[root@node01 ~]# kubectl exec -it ingress-nginx-controller-58554b9b99-rdnhp -n ingress-nginx -- /bin/bash
# 查看对应的配置
ingress-nginx-controller-58554b9b99-rdnhp:/etc/nginx$ grep -A10 app.huangsir.com nginx.conf
        ## start server app.huangsir.com
        server {
                server_name app.huangsir.com ;

                http2 on;

                listen 80  ;
                listen [::]:80  ;
                listen 443  ssl;
                listen [::]:443  ssl;

                set $proxy_upstream_name "-";

--

未完结

posted @ 2025-05-11 16:35  huangSir-devops  阅读(94)  评论(0)    收藏  举报
作者:你的名字
出处:你的博客链接
本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。