ingress进阶

  • Nginx Ingress 安装
  • Nginx Ingress Redirect
  • Nginx Ingress Rewrite
  • Nginx Ingress SSL
  • Nginx Ingress 基本认证
  • Nginx Ingress 黑白名单
  • Nginx Ingress 匹配请求头
  • Nginx Ingress 速率限制
  • Nginx Ingress 灰度/金丝雀发布
  • Nginx Ingress自定义错误页面
  • Nginx Ingress监控(已有Prometheus)

Ingress介绍:

ingress进阶

ingress架构一般是ingress前端还会有一台负载均衡。实现公私网分开

官方文档: 

      Ingress-nginx:kubernetes官方维护的ingress(推荐)

       Nginx-ingress:nginx官方维护的ingress

差别:https://github.com/nginxinc/kubernetes-ingress/blob/master/docs/nginx-ingress-controllers.md

Ingress-nginx的官方文档(推荐):https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#rewrite
Nginx-ingress的官方文档:https://docs.nginx.com/nginx-ingress-controller/configuration/ingress-resources/advanced-configuration-with-annotations/

Ingress-nginx Github:https://github.com/kubernetes/ingress-nginx
Nginx-ingress Github:https://github.com/nginxinc/kubernetes-ingress/blob/master/docs/nginx-ingress-controllers.md

其他类型的ingress:Traefik、HAProxy、Istio

ingress部署建议:

  1. 找几台专门的服务器进行配置ingress,QoS
  2. hostNetwork:true:使用NodePort性能不好,直接使用宿主机网络效率更高
  3. 滚动更新方式建议OnDelete:业务上线,如果出现一个pod无法正常重启,其他pod将不会更新,防止服务崩溃(DaemonSet的更新方式 1:RollingUpdate -- 只有maxUnavailable可以设置,没有maxSurge 2: OnDelete --只有手动删除旧的DaemonSet Pod,才会更新新的Pod)

IngressRedirect:

创建一个nginx应用,暴露服务

kubectl create ns ingress-test
kubectl -n ingress-test create deployment web --image=nginx
kubectl -n ingress-test expose deployment web --port=80 --target-port=80

查看下svc服务

ingress进阶

创建ingress规则

vim nginx-ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: ingress-test 
  annotations:
    kubernetes.io/ingress.class: "nginx" #声名需要使用nginx方式解析ingress
spec:
  rules: # 一个Ingress可以配置多个rules
  - host: example.ingredemo.com # 域名配置,可以不写(不建议),支持匹配,一般写法:*.bar.com
    http:
      paths: # 相当于nginx的location配合,同一个host可以配置多个path 例如“/”或“/abc”
      - path: "/"
        pathType: Prefix
        backend:
          service:
            name: web
            port:
              number: 80

kubectl create -f nginx-ingress.yaml

ingress进阶

域名重定向并指定返回状态码

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: ingress-test
  annotations:
    kubernetes.io/ingress.class: "nginx" #声名需要使用nginx方式解析ingress
    nginx.ingress.kubernetes.io/permanent-redirect: https://www.baidu.com # 转发到百度官网
    nginx.ingress.kubernetes.io/permanent-redirect-code: '308' # 返回308状态码
spec:
  rules: # 一个Ingress可以配置多个rules
  - host: example.ingredemo.com # 域名配置,可以不写(不建议),支持匹配,一般写法:*.bar.com
    http:
      paths: # 相当于nginx的location配合,同一个host可以配置多个path 例如“/”或“/abc”
      - path: "/"
        pathType: Prefix
        backend:
          service:
            name: web
            port:
              number: 80

跳转结果:

ingress进阶
ingress进阶

可以进入ingress-nginx空间进入pod查看下nginx配置

ingress进阶

kubectl -n ingress-nginx exec -it ingress-nginx-controller-zr8gm -- bash

ingress进阶

路径rewrite重写

常用于动静分离和前后端分离

nginx.ingress.kubernetes.io/rewrite-target必须重定向流量的目标 URI
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: ingress-test
  annotations:
    kubernetes.io/ingress.class: "nginx" #声名需要使用nginx方式解析ingress
    nginx.ingress.kubernetes.io/rewrite-target: /$2 # $2代表匹配下面path路径的something之后的第二个元祖,即(.*)中的内容,在此入口定义中,捕获的任何字符都(.*)将分配给占位符$2,然后将其用作注释中的参数rewrite-target
spec:
  rules: # 一个Ingress可以配置多个rules
  - host: example.ingredemo.com # 域名配置,可以不写(不建议),支持匹配,一般写法:*.bar.com
    http:
      paths: # 相当于nginx的location配合,同一个host可以配置多个path 例如“/”或“/abc”
      - path: /something(/|$)(.*) # 将此路径重定向到annotations中rewrite重定向匹配的路径
        pathType: Prefix
        backend:
          service:
            name: web
            port:
              number: 80
ingress进阶

example.ingredemo.com/something 重写为 example.ingredemo.com

Nginx Ingress SSL

参考文档:https://kubernetes.github.io/ingress-nginx/user-guide/tls/

KEY_FILE=tls.key
CERT_FILE=tls.cert
HOST=example.ingredemo.com
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ${KEY_FILE} -out ${CERT_FILE} -subj "/CN=${HOST}/O=${HOST}"

将cert和key配置成secret

CERT_NAME=tls-secret
kubectl -n ingress-test create secret tls ${CERT_NAME} --key tls.key --cert tls.crt

nginx-ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: ingress-test
  annotations:
    kubernetes.io/ingress.class: "nginx" #声名需要使用nginx方式解析ingress
    # nginx.ingress.kubernetes.io/ssl-redirect: "false" # 可以选择关闭自动跳转,默认配置了ssl都会自动跳转
spec:
  tls:
  - hosts:
    - example.ingredemo.com
    secretName: tls-secret
  rules: # 一个Ingress可以配置多个rules
  - host: example.ingredemo.com # 域名配置,可以不写(不建议),支持匹配,一般写法:*.bar.com
    http:
      paths: # 相当于nginx的location配合,同一个host可以配置多个path 例如“/”或“/abc”
      - path: "/"
        pathType: Prefix
        backend:
          service:
            name: web
            port:
              number: 80
ingress进阶

默认情况下,如果为该入口启用了 TLS,控制器会使用 308 永久重定向响应将 HTTP 客户端重定向到 HTTPS 端口 443。ssl-redirect: "false"可以在 NGINX配置映射中全局禁用此功能,也可以使用nginx.ingress.kubernetes.io/ssl-redirect: "false"特定资源中的注释在每个入口禁用此功能。

为dashboard配置ingress

参考文档:

ssl-passthrough

backend-protocol

生成新证书(一般都使用厂商直接提供的证书,实验使用自签证书进行测试)

KEY_FILE=server.key
CERT_FILE=server.pem
HOST=dashboard.ingredemo.com
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ${KEY_FILE} -out ${CERT_FILE} -subj "/CN=${HOST}/O=${HOST}"

CERT_NAME=kubernetes-dashboard-new
kubectl -n kubernetes-dashboard create secret tls ${CERT_NAME} --key server.key --cert server.pem

修改dash的deployment
kubectl get -n kubernetes-dashboard deployment kubernetes-dashboard -o yaml > dashboard-bak.yaml

cp dashboard-bak.yaml dashboard-deployment.yaml && vim dashboard-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  selector:
    matchLabels:
      k8s-app: kubernetes-dashboard
  template:
    metadata:
      labels:
        k8s-app: kubernetes-dashboard
    spec:
      containers:
      - args:
        - --auto-generate-certificates=false  # 禁止自动生成证书
        - --tls-key-file=tls.key
        - --tls-cert-file=tls.crt
        - --token-ttl=21600
        - --authentication-mode=basic,token
        - --namespace=kubernetes-dashboard
        image: kubernetesui/dashboard:v2.0.3
#        livenessProbe:
#          failureThreshold: 3
#          httpGet:
#            path: /
#            port: 8443
#            scheme: HTTPS
#          initialDelaySeconds: 30
#          periodSeconds: 10
#          successThreshold: 1
#          timeoutSeconds: 30
        name: kubernetes-dashboard
        ports:
        - containerPort: 8443
          protocol: TCP
#        terminationMessagePath: /dev/termination-log
#        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /certs # 挂载新证书
          name: kubernetes-dashboard-new
        - mountPath: /tmp
          name: tmp-volume
#      schedulerName: default-scheduler
#      serviceAccount: kubernetes-dashboard
#      serviceAccountName: kubernetes-dashboard
      volumes:
      - name: kubernetes-dashboard-new
        secret:
          defaultMode: 420
          secretName: kubernetes-dashboard-new
      - emptyDir: {}
        name: tmp-volume

dashboard-ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: dashboard-ingress
  namespace: kubernetes-dashboard
  annotations:
    kubernetes.io/ingress.class: "nginx" # 声名需要使用nginx方式解析ingress
    nginx.ingress.kubernetes.io/ssl-passthrough: "true" # 该注释指示nginx.ingress.kubernetes.io/ssl-passthrough控制器将 TLS 连接直接发送到后端,而不是让 NGINX 解密通信。
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" # 使用backend-protocol注释可以指示 NGINX 应如何与后端服务通信。(secure-backends在旧版本中替换)有效>值:HTTP、HTTPS、GRPC、GRPCS 和 FCGI 默认情况下 NGINX 使用HTTP
spec:
  rules: # 一个Ingress可以配置多个rules
  - host: dashboard.ingredemo.com # 域名配置,可以不写(不建议),支持匹配,一般写法:*.bar.com
    http:
      paths: # 相当于nginx的location配合,同一个host可以配置多个path 例如“/”或“/abc”
      - path: "/"
        pathType: Prefix
        backend:
          service:
            name: kubernetes-dashboard
            port:
              number: 443
ingress进阶

Nginx Ingress 基本认证

yum -y install httpd-tools
htpasswd -c auth testuser
kubectl -n ingress-test create secret generic basic-auth --from-file=auth

生成一个基于base64加密的字符串

Ingress和Helm和物理卷
Ingress和Helm和物理卷

修改ingress
ingress-network.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - foo'
spec:
  rules:
  - host: example.ingredemo.com
    http:
      paths:
      - path: "/"
        pathType: Prefix
        backend:
          service:
            name: web
            port:
              number: 80

输入用户名和密码

Ingress和Helm和物理卷

Nginx Ingress 黑白名单

黑白名单:

       Annotations:只对指定的ingress生效

       ConfigMap:全局生效

黑名单可以使用ConfigMap去配置,白名单建议使用Annotations去配置。

白名单:

可以通过nginx.ingress.kubernetes.io/whitelist-source-range注释指定允许的客户端 IP 源范围。该值是逗号分隔的CIDR列表,例如10.0.0.0/24,172.10.0.1

要为所有 Ingress 规则全局配置此设置,可以在NGINX ConfigMapwhitelist-source-range中设置该值。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: ingress-test
  annotations:
    kubernetes.io/ingress.class: "nginx" #声名需要使用nginx方式解析ingress
    nginx.ingress.kubernetes.io/whitelist-source-range: 192.168.1.11 # 只允许192.168.1.11访问
spec:
  rules: # 一个Ingress可以配置多个rules
  - host: example.ingredemo.com # 域名配置,可以不写(不建议),支持匹配,一般写法:*.bar.com
    http:
      paths: # 相当于nginx的location配合,同一个host可以配置多个path 例如“/”或“/abc”
      - path: "/"
        pathType: Prefix
        backend:
          service:
            name: web
            port:
              number: 80
ingress进阶

登陆192.168.1.11服务器进行访问

vim /etc/hosts

ingress进阶
ingress进阶

黑名单:

拒绝名单来源范围:

可以通过nginx.ingress.kubernetes.io/denylist-source-range注释指定阻止的客户端 IP 源范围。该值是逗号分隔的CIDR列表,例如10.0.0.0/24,172.10.0.1

要为所有 Ingress 规则全局配置此设置,可以在NGINX ConfigMapdenylist-source-range中设置该值。

设置全局黑名单:

kubectl -n ingress-nginx edit cm ingress-nginx-controller

ingress进阶

kubectl -n ingress-nginx delete po --all

登陆192.168.1.11访问:

ingress进阶

设置单个ingress黑名单配置(此方法测试未生效,建议使用后一种server-snippet方法)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: ingress-test
  annotations:
    kubernetes.io/ingress.class: "nginx" #声名需要使用nginx方式解析ingress
    nginx.ingress.kubernetes.io/denylist-source-range: 192.168.1.12 # 禁止192.168.1.12访问
spec:
  rules: # 一个Ingress可以配置多个rules
  - host: example.ingredemo.com # 域名配置,可以不写(不建议),支持匹配,一般写法:*.bar.com
    http:
      paths: # 相当于nginx的location配合,同一个host可以配置多个path 例如“/”或“/abc”
      - path: "/"
        pathType: Prefix
        backend:
          service:
            name: web
            port:
              number: 80

如果想灵活配置单个ingress的黑名单,使用注释:nginx.ingress.kubernetes.io/server-snippet可以在服务器配置块中添加自定义配置。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: ingress-test
  annotations:
    kubernetes.io/ingress.class: "nginx" #声名需要使用nginx方式解析ingress
    nginx.ingress.kubernetes.io/server-snippet: |
        deny 192.168.1.13;
        allow all;
spec:
  rules: # 一个Ingress可以配置多个rules
  - host: example.ingredemo.com # 域名配置,可以不写(不建议),支持匹配,一般写法:*.bar.com
    http:
      paths: # 相当于nginx的location配合,同一个host可以配置多个path 例如“/”或“/abc”
      - path: "/"
        pathType: Prefix
        backend:
          service:
            name: web
            port:
              number: 80

登陆13服务器返回403状态码

ingress进阶

Nginx Ingress 匹配请求头

使用注释nginx.ingress.kubernetes.io/server-snippet可以在服务器配置块中添加自定义配置。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: ingress-test
  annotations:
    kubernetes.io/ingress.class: "nginx" #声名需要使用nginx方式解析ingress
    nginx.ingress.kubernetes.io/server-snippet: |
        set $agentflag 0;

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

        if ( $agentflag = 1 ) {
          return 301 https://www.baidu.com;
        }
spec:
  rules: # 一个Ingress可以配置多个rules
  - host: example.ingredemo.com # 域名配置,可以不写(不建议),支持匹配,一般写法:*.bar.com
    http:
      paths: # 相当于nginx的location配合,同一个host可以配置多个path 例如“/”或“/abc”
      - path: "/"
        pathType: Prefix
        backend:
          service:
            name: web
            port:
              number: 80

修改设备请求头,成功跳转

Nginx Ingress 速率限制

速率限制

这些注释定义了连接和传输速率的限制。这些可用于减轻DDoS 攻击。

  • nginx.ingress.kubernetes.io/limit-connections:单个 IP 地址允许的并发连接数。超过此限制会返回 503 错误。
  • nginx.ingress.kubernetes.io/limit-rps:每秒从给定 IP 接受的请求数。突发限制设置为此限制乘以突发乘数,默认乘数为 5。当客户端超出此限制时,返回limit-req-status-code 默认值: 503。
  • nginx.ingress.kubernetes.io/limit-rpm:每分钟从给定 IP 接受的请求数。突发限制设置为此限制乘以突发乘数,默认乘数为 5。当客户端超出此限制时,返回limit-req-status-code 默认值: 503。
  • nginx.ingress.kubernetes.io/limit-burst-multiplier:突发大小限制速率的倍数。默认突发乘数为 5,此注释会覆盖默认乘数。当客户端超过此限制时,将返回limit-req-status-code 默认值: 503。
  • nginx.ingress.kubernetes.io/limit-rate-after:初始千字节数,之后对给定连接的响应的进一步传输将受到速率限制。此功能必须在启用代理缓冲的情况下使用。
  • nginx.ingress.kubernetes.io/limit-rate:每秒允许发送到给定连接的千字节数。零值禁用速率限制。此功能必须在启用代理缓冲的情况下使用。
  • nginx.ingress.kubernetes.io/limit-whitelist:要从速率限制中排除的客户端 IP 源范围。该值是逗号分隔的 CIDR 列表。

nginx-ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: ingress-test
  annotations:
    kubernetes.io/ingress.class: "nginx" #声名需要使用nginx方式解析ingress
    nginx.ingress.kubernetes.io/limit-rps: '1' # 设置每秒从给定 IP 接受的请求数
spec:
  rules: # 一个Ingress可以配置多个rules
  - host: example.ingredemo.com # 域名配置,可以不写(不建议),支持匹配,一般写法:*.bar.com
    http:
      paths: # 相当于nginx的location配合,同一个host可以配置多个path 例如“/”或“/abc”
      - path: "/"
        pathType: Prefix
        backend:
          service:
            name: web
            port:
              number: 80
ingress进阶

初始千字节数限制(测试未成功):

nginx-ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: ingress-test
  annotations:
    kubernetes.io/ingress.class: "nginx" #声名需要使用nginx方式解析ingress
    nginx.ingress.kubernetes.io/proxy-buffering: "on"
    nginx.ingress.kubernetes.io/limit-rate-after: "1"
spec:
  rules: # 一个Ingress可以配置多个rules
  - host: example.ingredemo.com # 域名配置,可以不写(不建议),支持匹配,一般写法:*.bar.com
    http:
      paths: # 相当于nginx的location配合,同一个host可以配置多个path 例如“/”或“/abc”
      - path: "/"
        pathType: Prefix
        backend:
          service:
            name: web
            port:
              number: 80

查看访问主机IP从速率限制中添加白名单:

ingress进阶
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: ingress-test
  annotations:
    kubernetes.io/ingress.class: "nginx" #声名需要使用nginx方式解析ingress
    nginx.ingress.kubernetes.io/limit-rps: '1'
    nginx.ingress.kubernetes.io/limit-whitelist: "192.168.1.1" # 解除此ip速率限制
spec:
  rules: # 一个Ingress可以配置多个rules
  - host: example.ingredemo.com # 域名配置,可以不写(不建议),支持匹配,一般写法:*.bar.com
    http:
      paths: # 相当于nginx的location配合,同一个host可以配置多个path 例如“/”或“/abc”
      - path: "/"
        pathType: Prefix
        backend:
          service:
            name: web
            port:
              number: 80
ingress进阶

Nginx Ingress 灰度/金丝雀发布

可以使用service进行灰度发布,这里的灰度发布使用的方式是ingress方式,优点是可以通过参数和细节(请求头、cookie等)进行负载均衡,缺点是需要部署更多的service和ingress,同一个域名,不同的ingress,新的ingress和旧的ingress域名相同(相同的前提是开启金丝雀部署)

Nginx Ingress支持通过配置注解(Annotations)来实现不同场景下的发布和测试,可以满足灰度发布、蓝绿发布、A/B测试等业务场景。具体实现过程如下:为服务创建两个Ingress,一个为常规Ingress,另一个为带nginx.ingress.kubernetes.io/canary: "true"注解的Ingress,称为Canary Ingress;为Canary Ingress配置流量切分策略Annotation,两个Ingress相互配合,即可实现多种场景的发布和测试

ingress进阶

通过向与生产服务不同的服务发送少量请求来“金丝雀”一组新的更改。金丝雀注释使 Ingress 规范能够充当请求的替代服务,根据所应用的规则路由到该请求。nginx.ingress.kubernetes.io/canary: "true"设置后可以启用以下用于配置 Canary 的注释:

  • nginx.ingress.kubernetes.io/canary-by-header:用于通知 Ingress 将请求路由到 Canary Ingress 中指定的服务的标头。当请求头设置为 时always,它将被路由到金丝雀。当标头设置为 时never,它永远不会被路由到金丝雀。对于任何其他值,标头将被忽略,并且请求将按优先级与其他金丝雀规则进行比较。
  • nginx.ingress.kubernetes.io/canary-by-header-value:要匹配的标头值,用于通知 Ingress 将请求路由到 Canary Ingress 中指定的服务。当请求标头设置为该值时,它将被路由到金丝雀。对于任何其他标头值,该标头将被忽略,并且请求将按优先级与其他金丝雀规则进行比较。该注解必须与 nginx.ingress.kubernetes.io/canary-by-header一起使用。该注释是nginx.ingress.kubernetes.io/canary-by-header的扩展,允许自定义标头值而不是使用硬编码值。如果未定义nginx.ingress.kubernetes.io/canary-by-header注释,则此注释不会产生任何影响。
  • nginx.ingress.kubernetes.io/canary-by-header-patterncanary-by-header-value:这与 PCRE 正则表达式匹配的工作方式相同。请注意,canary-by-header-value设置后此注释将被忽略。当给定的正则表达式在请求处理过程中导致错误时,该请求将被视为不匹配。
  • nginx.ingress.kubernetes.io/canary-by-cookie:用于通知 Ingress 将请求路由到 Canary Ingress 中指定的服务的 cookie。当cookie值设置为 时always,它将被路由到金丝雀。当 cookie 设置为 时never,它永远不会被路由到金丝雀。对于任何其他值,cookie 将被忽略,并且请求将按优先级与其他金丝雀规则进行比较。
  • nginx.ingress.kubernetes.io/canary-weight:基于整数 (0 -) 应路由到金丝雀 Ingress 中指定的服务的随机请求的百分比。权重为 0 意味着此金丝雀规则不会向金丝雀入口中的服务发送任何请求。均值的权重<weight-total>意味着所有请求都将发送到 Ingress 中指定的替代服务。<weight-total>默认为 100,可以通过 增加nginx.ingress.kubernetes.io/canary-weight-total
  • nginx.ingress.kubernetes.io/canary-weight-total:流量总权重。如果未指定,则默认为 100。

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

实验:创建新的deployment以及service和ingress,修改nginx页面,添加v2后缀

kubectl -n ingress-test create deployment web-v2 --image=nginx
kubectl -n ingress-test expose deployment web-v2 --port=80 --target-port=80

部署后修改下html页面

ingress进阶

创建金丝雀版本ingress

nginx-ingress-canary.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress-canary-v2
  namespace: ingress-test
  annotations:
    kubernetes.io/ingress.class: "nginx" #声名需要使用nginx方式解析ingress
    nginx.ingress.kubernetes.io/canary: "true" 
    nginx.ingress.kubernetes.io/canary-weight: "50"
    #nginx.ingress.kubernetes.io/canary-by-cookie: always
    #nginx.ingress.kubernetes.io/canary-by-header: always
    #nginx.ingress.kubernetes.io/canary-by-header-value: canary
spec:
  rules: # 一个Ingress可以配置多个rules
  - host: example.ingredemo.com # 域名配置,可以不写(不建议),支持匹配,一般写法:*.bar.com
    http:
      paths: # 相当于nginx的location配合,同一个host可以配置多个path 例如“/”或“/abc”
      - path: "/"
        pathType: Prefix
        backend:
          service:
            name: web-v2
            port:
              number: 80
ingress进阶
ingress进阶

基于header:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress-canary-v2
  namespace: ingress-test
  annotations:
    kubernetes.io/ingress.class: "nginx" #声名需要使用nginx方式解析ingress
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "50"
    nginx.ingress.kubernetes.io/canary-by-header: always # 基于header优先级大于基于weight
    nginx.ingress.kubernetes.io/canary-by-header-value: canary
spec:
  rules: # 一个Ingress可以配置多个rules
  - host: example.ingredemo.com # 域名配置,可以不写(不建议),支持匹配,一般写法:*.bar.com
    http:
      paths: # 相当于nginx的location配合,同一个host可以配置多个path 例如“/”或“/abc”
      - path: "/"
        pathType: Prefix
        backend:
          service:
            name: web-v2
            port:
              number: 80

添加请求头进行测试

curl -H "always:canary" example.ingredemo.com

ingress进阶

基于cookie

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress-canary-v2
  namespace: ingress-test
  annotations:
    kubernetes.io/ingress.class: "nginx" #声名需要使用nginx方式解析ingress
    nginx.ingress.kubernetes.io/canary: "true" 
    nginx.ingress.kubernetes.io/canary-weight: "50"
    nginx.ingress.kubernetes.io/canary-by-cookie: always # cookie优先级大于weight
    nginx.ingress.kubernetes.io/canary-by-cookie: canary-cookie
spec:
  rules: # 一个Ingress可以配置多个rules
  - host: example.ingredemo.com # 域名配置,可以不写(不建议),支持匹配,一般写法:*.bar.com
    http:
      paths: # 相当于nginx的location配合,同一个host可以配置多个path 例如“/”或“/abc”
      - path: "/"
        pathType: Prefix
        backend:
          service:
            name: web-v2
            port:
              number: 80

测试cookie

curl -b "canary-cookie=always" http://example.ingredemo.com

ingress进阶

Nginx Ingress自定义错误页面

参考文档:https://github.com/kubernetes/ingress-nginx/blob/nginx-0.20.0/docs/examples/customization/custom-errors/custom-default-backend.yaml

基于单个ingress(测试未成功):

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: ingress-test
  annotations:
    kubernetes.io/ingress.class: "nginx" #声名需要使用nginx方式解析ingress
    nginx.ingress.kubernetes.io/server-snippet: |
        error_page 404 https://www.baidu.com;
spec:
  rules: # 一个Ingress可以配置多个rules
  - host: example.ingredemo.com # 域名配置,可以不写(不建议),支持匹配,一般写法:*.bar.com
    http:
      paths: # 相当于nginx的location配合,同一个host可以配置多个path 例如“/”或“/abc”
      - path: "/"
        pathType: Prefix
        backend:
          service:
            name: web
            port:
              number: 80

基于全局:

假设一个错误页面定义在ingress-test的web-v2 service中

kubectl -n ingress-test exec -it web-v2-5cfb67668c-64hs7 -- bash

echo 'this is 403,404' > /usr/share/nginx/html/index.html

ingress进阶

修改configmap ingress-nginx-controller

kubectl -n ingress-nginx edit cm ingress-nginx-controller

data:
  custom-http-errors: "404,403"
ingress进阶

修改控制器DaemonSet

kubectl -n ingress-nginx edit ds ingress-nginx-controller

添加

--default-backend-service=ingress-test/web-v2

ingress进阶

删除更新pod

kubectl delete po -n ingress-nginx ingress-nginx-controller-wxkkz

尝试访问域名下一个不存在的页面

ingress进阶

Nginx Ingress监控(已有Prometheus)

ingress nginx 监控:https://kubernetes.github.io/ingress-nginx/user-guide/monitoring/

github项目:https://github.com/kubernetes/ingress-nginx/tree/master/deploy

dashboard:https://github.com/kubernetes/ingress-nginx/tree/master/deploy/grafana/dashboards

ingress默认metrics暴露端口10254,如果是helm,则需要如下修改

ingress进阶

如果不是 helm,需要修改service

服务清单:

    - name: prometheus
      port: 10254
      targetPort: prometheus

然后修改ingress-nginx daemonset或deployment配置

pod控制器清单(deployment/daemonset),如果pod未能更新,直接edit pod添加annotations:

kind: Deployment/DeamonSet
metadata:
  annotations:
    prometheus.io/scrape: "true"
    prometheus.io/port: "10254"

kubectl get pod -n ingress-nginx -owide

curl 192.168.1.13:10254/metrics | head

ingress进阶

将https://github.com/kubernetes/ingress-nginx/blob/main/deploy/prometheus/prometheus.yaml页面下的job_name更新添加到prometheus-additional.yaml

- job_name: 'ingress-nginx-endpoints'
  kubernetes_sd_configs:
  - role: pod
    namespaces:
      names:
      - ingress-nginx
  relabel_configs:
  - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
    action: keep
    regex: true
  - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scheme]
    action: replace
    target_label: __scheme__
    regex: (https?)
  - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
    action: replace
    target_label: __metrics_path__
    regex: (.+)
  - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
    action: replace
    target_label: __address__
    regex: ([^:]+)(?::\d+)?;(\d+)
    replacement: $1:$2
  - source_labels: [__meta_kubernetes_service_name]
    regex: prometheus-server
    action: drop
kubectl create secret generic additional-scrape-configs --from-file=prometheus-additional.yaml --dry-run=client -oyaml > additional-scrape-configs.yaml
kubectl apply -f additional-scrape-configs.yaml -n monitoring

访问prometheus targets:http://prom.test.com/targets

ingress进阶

使用dashboard:import这两个json文件即可

ingress进阶
ingress进阶

发布者:LJH,转发请注明出处:https://www.ljh.cool/38107.html

(0)
上一篇 2023年9月5日 下午12:53
下一篇 2023年9月18日 上午11:30

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注