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 官方文档

相关推荐
为什么这亚子1 小时前
九、Go语言快速入门之map
运维·开发语言·后端·算法·云原生·golang·云计算
ZHOU西口3 小时前
微服务实战系列之玩转Docker(十八)
分布式·docker·云原生·架构·数据安全·etcd·rbac
牛角上的男孩3 小时前
Istio Gateway发布服务
云原生·gateway·istio
JuiceFS5 小时前
好未来:多云环境下基于 JuiceFS 建设低运维模型仓库
运维·云原生
景天科技苑5 小时前
【云原生开发】K8S多集群资源管理平台架构设计
云原生·容器·kubernetes·k8s·云原生开发·k8s管理系统
wclass-zhengge6 小时前
K8S篇(基本介绍)
云原生·容器·kubernetes
颜淡慕潇6 小时前
【K8S问题系列 |1 】Kubernetes 中 NodePort 类型的 Service 无法访问【已解决】
后端·云原生·容器·kubernetes·问题解决
川石课堂软件测试8 小时前
性能测试|docker容器下搭建JMeter+Grafana+Influxdb监控可视化平台
运维·javascript·深度学习·jmeter·docker·容器·grafana
昌sit!14 小时前
K8S node节点没有相应的pod镜像运行故障处理办法
云原生·容器·kubernetes
A ?Charis17 小时前
Gitlab-runner running on Kubernetes - hostAliases
容器·kubernetes·gitlab