K8S Ingress 常用配置

目录


介绍

本次所有操作都是在K8S 1.26.14 上面操作,太老的版本不知道会不会有问题。

更多 Ingress 配置请查看ingress-nginx 官网

ingress 安装 基本使用请查看

点击跳转

域名重定向

配置成功以后再次访问会直接跳转到百度首页。

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: prometheus-ingress
  namespace: monitoring
  annotations:
    ## 配置域名重定向,将百度的域名改成自己业务需要的即可
    nginx.ingress.kubernetes.io/permanent-redirect: https://www.baidu.com
spec:
  ingressClassName: nginx
  rules:
  - host: prometheus.monitoring.cn
    http:
      paths:
      - backend:
          service:
            name: prometheus-k8s
            port:
              name: web
        path: /
        pathType: Prefix
  tls:
  - hosts:
    - prometheus.monitoring.cn
    secretName: prometheus.monitoring.cn

修改域名重定向的同时还可以修改状态码,默认是301,本次修改成308.

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: prometheus-ingress
  namespace: monitoring
  annotations:
    ## 配置域名重定向,将百度的域名改成自己业务需要的即可
    nginx.ingress.kubernetes.io/permanent-redirect: https://www.baidu.com
    ## 修改状态码
    nginx.ingress.kubernetes.io/permanent-redirect-code: '308'
spec:
  ingressClassName: nginx
  rules:
  - host: prometheus.monitoring.cn
    http:
      paths:
      - backend:
          service:
            name: prometheus-k8s
            port:
              name: web
        path: /
        pathType: Prefix
  tls:
  - hosts:
    - prometheus.monitoring.cn
    secretName: prometheus.monitoring.cn

再次访问的时候可以看到状态码已经修改了(在网页调试里面查看)

前后端分离配置

部署好以后用这个域名访问即可prometheus.monitoring.cn/test,在nginx上面这个配置就是地址重写。

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: prometheus-ingress
  namespace: monitoring
  annotations:
    nginx.ingress.kubernetes.io/use-regex: "true"  ## 启用正则表达式匹配路径
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  ingressClassName: nginx
  rules:
  - host: prometheus.monitoring.cn
    http:
      paths:
      - backend:
          service:
            name: prometheus-k8s
            port:
              name: web
        path: /test(/|$)(.*)
        pathType: ImplementationSpecific
  tls:
  - hosts:
    - prometheus.monitoring.cn
    secretName: prometheus.monitoring.cn

默认证书配置

测试环境可以用openssl 生成一个证书即可,正常生产环境是需要购买的证书才可以的要不浏览器会提示不安全。

比如申请的域名是以 *.monitoring.cn 的证书 就可以设置默认域名。

在 K8S上面创建证书。

bash 复制代码
## 创建证书
kubectl create secret tls monitoring.cn --key monitoring.cn.key --cert monitoring.cn_bundle.pem -n ingress-nginx

## 查看创建的证书
[root@master01 ~]# kubectl get secrets -n ingress-nginx
NAME                                  TYPE                 DATA   AGE
monitoring.cn                          kubernetes.io/tls    2      65s

修改 ingress-nginx 配置

bash 复制代码
kubectl edit daemonsets.apps -n ingress-nginx ingress-nginx-controller

### 找到这一行
    spec:
      containers:
      - args:
        - /nginx-ingress-controller
        ###  在此处添加 "- --default-ssl-certificate=ingress-nginx/monitoring.cn"   等号后面写命名空间/后面加上名字 (不是非得创建到 'ingress-nginx'理论上那个命名空间都可以)
        - --default-ssl-certificate=ingress-nginx/monitoring.cn
        - --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller
        - --election-id=ingress-nginx-leader

保存退出即可。

使用方法:

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: prometheus-ingress
  namespace: monitoring
spec:
  ingressClassName: nginx
  rules:
  - host: prometheus.monitoring.cn
    http:
      paths:
      - backend:
          service:
            name: prometheus-k8s
            port:
              name: web
        path: /
        pathType: Prefix

NGINX 将提供默认证书,但不会强制 HTTPS 重定向。就是用HTTP访问也行HTTPS访问也行。

如果需要强制转换HTTPS访问 在后面添加 tls 即可

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: prometheus-ingress
  namespace: monitoring
spec:
  ingressClassName: nginx
  rules:
  - host: prometheus.monitoring.cn
    http:
      paths:
      - backend:
          service:
            name: prometheus-k8s
            port:
              name: web
        path: /
        pathType: Prefix
  tls:
  - hosts:
    - prometheus.monitoring.cn

指定证书配置

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: prometheus-ingress
  namespace: monitoring
spec:
  ingressClassName: nginx
  rules:
  - host: prometheus.monitoring.cn
    http:
      paths:
      - backend:
          service:
            name: prometheus-k8s
            port:
              name: web
        path: /
        pathType: Prefix
  tls:
  - hosts:
    - prometheus.monitoring.cn
    secretName: prometheus.monitoring.cn  ## 这行要是注释了就是用默认的证书,没注释就是使用指定证书。

白名单配置

白名单建议使用 annotations 配置,这个只对的单个Ingress生效。

添加 nginx.ingress.kubernetes.io/whitelist-source-range 注释以实现白名单。未授权的 IP 访问会提示 403。

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: prometheus-ingress
  namespace: monitoring
  annotations:   ## 多个IP 用逗号隔开。
    nginx.ingress.kubernetes.io/whitelist-source-range: 192.168.1.175
spec:
  tls:
    - hosts:
        - prometheus.monitoring.cn
  ingressClassName: nginx
  rules:
  - host: prometheus.monitoring.cn
    http:
      paths:
      - backend:
          service:
            name: prometheus-k8s
            port:
              name: web
        path: /
        pathType: Prefix

黑名单配置

黑名单建议使用 ConfigMap 配置,此配置对整个集群段 Ingress 都生效。

Annotations 配置

这个注释可以指定具体的IP地址也可以写IP段的地址以逗号分隔,举例:192.168.1.0/24,192.168.1.2

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: prometheus-ingress
  namespace: monitoring
  annotations: ## 添加这个注释以开启黑名单设置
    nginx.ingress.kubernetes.io/denylist-source-range: 172.31.163.46
spec:
  tls:
    - hosts:
        - prometheus.monitoring.cn
  ingressClassName: nginx
  rules:
  - host: prometheus.monitoring.cn
    http:
      paths:
      - backend:
          service:
            name: prometheus-k8s
            port:
              name: web
        path: /
        pathType: Prefix
ConfigMap 配置

注意:此操作全局生效,修改完保存即可生效,老版本的 Ingress-nginx 可能需要重启pod。

bash 复制代码
kubectl edit cm -n ingress-nginx ingress-nginx-controller
yaml 复制代码
apiVersion: v1
data:
  allow-snippet-annotations: "true"
  ## 添加如下配置即可,IP 段也可以添加用逗号隔开即可。
  denylist-source-range: 172.31.163.46
kind: ConfigMap
metadata:
  annotations:
    meta.helm.sh/release-name: ingress-nginx
    meta.helm.sh/release-namespace: ingress-nginx
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.8.1
    helm.sh/chart: ingress-nginx-4.7.1
  name: ingress-nginx-controller
  namespace: ingress-nginx

匹配请求头

当请求头匹配到是用手机访问段就跳转到百度。

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: prometheus-ingress
  namespace: monitoring
  annotations:
    nginx.ingress.kubernetes.io/server-snippet: |
         set $agentflag 0;

         if ($http_user_agent ~* "(Mobile)" ){
            set $agentflag 1;
         }

         if ( $agentflag = 1 ) {
           return 301 https://www.baidu.com;
         }
spec:
  tls:
    - hosts:
        - prometheus.monitoring.cn
  ingressClassName: nginx
  rules:
  - host: prometheus.monitoring.cn
    http:
      paths:
      - backend:
          service:
            name: prometheus-k8s
            port:
              name: web
        path: /
        pathType: Prefix

速率限制

本次仅展示部分 Ingress 配置。

限制客户端的最大连接数

nginx.ingress.kubernetes.io/limit-connections 是用于限制每个客户端与后端服务的最大并发连接数。当前设置段同一客户端最大连接数是10,个这种限制可以帮助防止某些类型的 DoS攻击。超出这个限制的连接请求将被 NGINX 阻止,返回 HTTP 503 错误。

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: default
  annotations:
    nginx.ingress.kubernetes.io/limit-connections: "10"
spec:
限制每秒钟段并发连接数

nginx.ingress.kubernetes.io/limit-rps 是用于限制每秒钟每个客户端 IP 地址可以发送到后端服务的请求数量,当前设置为每秒并发五个连接。

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: default
  annotations:
    nginx.ingress.kubernetes.io/limit-rps: "5"
spec:
  rules:
限制每分钟段并发请求

这个和每秒的那个限制基本一致。当前配置是每分钟允许同一个客户端并发100个请求。

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: default
  annotations:
    nginx.ingress.kubernetes.io/limit-rpm: "100"
spec:
突发访问限制

nginx.ingress.kubernetes.io/limit-burst-multiplier 是用于控制请求速率限制中的突发请求数。它在配置 limit-rps(每秒请求数限制)或 limit-rpm(每分钟请求数限制)时一起使用,以允许短时间内超过设定请求速率的突发请求。

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: default
  annotations:
    nginx.ingress.kubernetes.io/limit-rps: "10"
    nginx.ingress.kubernetes.io/limit-burst-multiplier: "2"
spec:

工作原理:

这意味着在一个短时间窗口内,最多可以处理 20 个请求(超过 limit-rps 限制的 10 个正常请求数),之后请求速率将受 limit-rps 的限制。

限制传输速度

nginx.ingress.kubernetes.io/limit-rate-after 是用于控制在限制速率(Rate Limiting)生效之前将以当前带宽的最大速率,这项设置与 nginx.ingress.kubernetes.io/limit-rate 配合使用,用于管理响应速率的上限。

注意:此功能必须在启用代理缓冲的情况下使用。如果需要全局配置修改ConfigMap即可。

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: default
  annotations:
    nginx.ingress.kubernetes.io/proxy-buffering: "on"     # 启用代理缓冲(默认情况是禁用段的)
	nginx.ingress.kubernetes.io/proxy-buffers: "8 16k"    # 8 个 16KB 缓冲区
    nginx.ingress.kubernetes.io/proxy-buffer-size: "16k"  # 初始缓冲区大小 16KB
    nginx.ingress.kubernetes.io/limit-rate: "1024"        # 每秒最多传输 1024 字节(1KB)
    nginx.ingress.kubernetes.io/limit-rate-after: "5120"  # 传输超过 5120 字节后开始限速(5k)
spec:

也可以直接使用这条 "nginx.ingress.kubernetes.io/limit-rate: "1024",既每秒传输1Kb(必须启用代理缓冲)

工作原理:

  • 客户端在请求前 5120 字节的数据时,数据会以网络能够支持的最高速率传输。
  • 当传输的数据量超过 5120 字节后,速率限制生效,传输速率限制为 1024 字节/秒(1KB/秒)。
速率限制白名单

nginx.ingress.kubernetes.io/limit-whitelist 是用于指定不受速率限制(rate limiting)影响的客户端 IP 地址或 IP 地址范围。

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: default
  annotations:
    nginx.ingress.kubernetes.io/limit-rate: "1024" # 每秒传输限制 1KB
    nginx.ingress.kubernetes.io/limit-whitelist: "192.168.1.0/24,10.0.0.1" # 白名单
spec:

白名单中的 IP 不受每秒传输1Kb速度的限制。

灰度发布

基于权重配置

nginx.ingress.kubernetes.io/canary-weight:基于整数百分比的随机请求应路由到金丝雀入口中指定的服务。权重为 0 表示此金丝雀规则不会将任何请求发送到金丝雀入口中的服务。

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  labels:
    k8s.kuboard.cn/layer: web
    k8s.kuboard.cn/name: test01
  name: test01
  namespace: apps
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    ## 有百分之10的流量回到这个服务,剩下百分之90的流量到下面的那个服务。
    nginx.ingress.kubernetes.io/canary-weight: "10"
spec:
  ingressClassName: nginx
  rules:
  - host: example.com
    http:
      paths:
      - backend:
          service:
            name: test01
            port:
              number: 80
        path: /
        pathType: Prefix
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  labels:
    k8s.kuboard.cn/layer: web
    k8s.kuboard.cn/name: test02
  name: test02
  namespace: apps
spec:
  ingressClassName: nginx
  rules:
  - host: example.com
    http:
      paths:
      - backend:
          service:
            name: test02
            port:
              number: 80
        path: /
        pathType: Prefix
基于 Header 控制流量走向
yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  labels:
    k8s.kuboard.cn/layer: web
    k8s.kuboard.cn/name: test01
  name: test01
  namespace: apps
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "X-Canary"
    nginx.ingress.kubernetes.io/canary-by-header-value: "always"
spec:
  ingressClassName: nginx
  rules:
  - host: example.com
    http:
      paths:
      - backend:
          service:
            name: test01
            port:
              number: 80
        path: /
        pathType: Prefix
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  labels:
    k8s.kuboard.cn/layer: web
    k8s.kuboard.cn/name: test02
  name: test02
  namespace: apps
spec:
  ingressClassName: nginx
  rules:
  - host: example.com
    http:
      paths:
      - backend:
          service:
            name: test02
            port:
              number: 80
        path: /
        pathType: Prefix

测试方法

不添加请求头的时候是访问 test02 。

bash 复制代码
[root@master01 ~]# curl example.com
test022222

添加请求头的时候是访问 test01(请求时候命令行里面的键值对必须和 Ingress 里面的对应上)。

yaml 复制代码
[root@master01 ~]# curl -H "X-Canary: always" example.com
test0111111

nginx.ingress.kubernetes.io/canary-by-cookie:用于通知 Ingress 将请求路由到 Canary Ingress 中指定的服务的 cookie。当 cookie 值设置为 时always,它将被路由到 Canary。当 cookie 设置为 时never,它将永远不会被路由到 Canary。对于任何其他值,将忽略 cookie,并根据优先级将请求与其他 Canary 规则进行比较。

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  labels:
    k8s.kuboard.cn/layer: web
    k8s.kuboard.cn/name: test01
  name: test01
  namespace: apps
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-cookie: "canary-user"
spec:
  ingressClassName: nginx
  rules:
  - host: example.com
    http:
      paths:
      - backend:
          service:
            name: test01
            port:
              number: 80
        path: /
        pathType: Prefix
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  labels:
    k8s.kuboard.cn/layer: web
    k8s.kuboard.cn/name: test02
  name: test02
  namespace: apps
spec:
  ingressClassName: nginx
  rules:
  - host: example.com
    http:
      paths:
      - backend:
          service:
            name: test02
            port:
              number: 80
        path: /
        pathType: Prefix

测试方法

将 cookie 的值设置为always是将访问test01,将值设置为never将访问 test02.

bash 复制代码
[root@master01 ~]# curl -b "canary-user=always" example.com
test0111111

或者(不写cookie 或者值乱写也是访问test02)

yaml 复制代码
[root@master01 ~]# curl -b "canary-user=never" example.com
test022222

Canary 规则按优先顺序进行评估。优先顺序如下:canary-by-header -> canary-by-cookie -> canary-weight

自定义错误页面

定义服务托管页面后段程序(为了演示使用 nginx 部署)。

部署自定义页面 配置文件。

yaml 复制代码
apiVersion: v1
kind: ConfigMap
metadata:
  name: custom-error-pages
  namespace: apps
data:
  404.html: |
    <html>
    <head><title>404 Not Found</title></head>
    <body>
    <h1>404 Not Found</h1>
    <p>The page you are looking for was not found.</p>
    </body>
    </html>
  502.html: |
    <html>
    <head><title>502 Bad Gateway</title></head>
    <body>
    <h1>502 Bad Gateway</h1>
    <p>There was a problem with the upstream server.</p>
    </body>
    </html>
  503.html: |
    <html>
    <head><title>503 Service Unavailable</title></head>
    <body>
    <h1>503 Service Unavailable</h1>
    <p>The service is currently unavailable. Please try again later.</p>
    </body>
    </html>

部署 nginx Deployment 服务

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: error-pages
  namespace: apps
spec:
  replicas: 1
  selector:
    matchLabels:
      app: error-pages
  template:
    metadata:
      labels:
        app: error-pages
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
        volumeMounts:
        - name: error-pages
          mountPath: /usr/share/nginx/html
  volumes:
  - name: error-pages
    configMap:
      name: custom-error-pages
---
apiVersion: v1
kind: Service
metadata:
  name: error-pages
  namespace: apps
spec:
  ports:
  - port: 80
  selector:
    app: error-pages

部署 Ingress (同一个命名空间直接写SVC名字即可,要是不同的命名空间情网下看。)

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  labels:
    k8s.kuboard.cn/layer: web
    k8s.kuboard.cn/name: test02
  name: test02
  namespace: apps
  annotations:
    nginx.ingress.kubernetes.io/custom-http-errors: "404,500"
    nginx.ingress.kubernetes.io/default-backend: 'error-pages'
spec:
  ingressClassName: nginx
  rules:
  - host: example.com
    http:
      paths:
      - backend:
          service:
            name: test02
            port:
              number: 80
        path: /
        pathType: Prefix

不同命名空间配置

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: error-pages
  namespace: apps
spec:
  type: ExternalName
  externalName: error-pages.apps.svc.cluster.local
  ports:
    - port: 80

基本认证

创建用户名和密码

bash 复制代码
htpasswd -c auth user

## 没有这个命令直接yum安装
yum install -y httpd-tools

创建 secret

bash 复制代码
kubectl create secret generic auth-secret --from-file=auth -apps

创建Ingress

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  labels:
    k8s.kuboard.cn/layer: web
    k8s.kuboard.cn/name: test02
  name: test02
  namespace: apps
  annotations:
    nginx.ingress.kubernetes.io/auth-type: "basic"   ## 指定使用基本身份验证
    nginx.ingress.kubernetes.io/auth-secret: "auth-secret"  ## 指定刚刚创建的 secret
    nginx.ingress.kubernetes.io/auth-realm: "Authentication Required"  ## 对话框面熟文字(就是在网页弹出的那个输入密码那个对话框的面熟问题,写什么都可以。)
spec:
  ingressClassName: nginx
  rules:
  - host: example.com
    http:
      paths:
      - backend:
          service:
            name: test02
            port:
              number: 80
        path: /
        pathType: Prefix

在页面访问会提示输入账号密码。

官网还有更多Ingress 配置,我这里只列出了经常能用到的。
Ingress-Nginx 官方文档

相关推荐
moppol2 小时前
Serverless 架构入门与实战:AWS Lambda、Azure Functions、Cloudflare Workers 对比
云原生·serverless·aws
IvanCodes2 小时前
一、Docker:一场颠覆应用部署与运维的容器革命
docker·容器
栗子~~3 小时前
Milvus docker-compose 部署
docker·容器·milvus
没有名字的小羊4 小时前
2.安装Docker
运维·docker·容器
xiezhr4 小时前
50 个常用 Docker 命令
运维·docker·容器
退役小学生呀10 天前
三、kubectl使用详解
云原生·容器·kubernetes·k8s
被困者10 天前
Linux部署Sonic前后端(详细版)(腾讯云)
spring cloud·云原生·eureka
程序员小潘10 天前
Kubernetes多容器Pod实战
云原生·容器·kubernetes
进击的码码码码N10 天前
Docker 镜像加速
运维·docker·容器