【问题标题】:Ingress nginx cache入口 nginx 缓存
【发布时间】:2020-06-07 12:10:28
【问题描述】:

我正在试图弄清楚如何使用带有一些特定规则的 nginx 代理缓存。例如,当我托管 Ghost 或 Wordpress 时,我不想缓存管理部分。使用服务器 sn-p,我尝试了很多不同的组合,但管理部分的缓存仍然存在问题。

nginx.ingress.kubernetes.io/proxy-buffering: "on"
nginx.ingress.kubernetes.io/server-snippet: |-
  proxy_ignore_headers X-Accel-Expires Expires Cache-Control;
  proxy_ignore_headers Set-Cookie;
  proxy_cache app_cache;
  proxy_cache_lock on;
  proxy_cache_valid any 30m;
  add_header X-Cache-Status $upstream_cache_status;

我想在管理区域使用 nginx 代码 sn-p 用于 (ghost|sinout) 路径绕过缓存,但我丢失了 proxy_pass 上下文,导致 502 网关错误。

这是当前缓存每个页面的入口配置,也是管理路径:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/proxy-buffering: "on"
    nginx.ingress.kubernetes.io/server-snippet: |-
      proxy_cache my_blog_cache;
      proxy_cache_lock on;
      proxy_cache_valid any 30m;
      add_header X-Cache-Status $upstream_cache_status;
      proxy_ignore_headers X-Accel-Expires Expires Cache-Control;
  name: my-blog
  namespace: web
spec:
  rules:
  - host: blog.example.com
    http:
      paths:
      - backend:
          serviceName: ingress-541322b8660dbd2ceb1e8ff1813f0dd5
          servicePort: 2368
        path: /
  tls:
  - hosts:
    - blog.example.com
    secretName: my-blog-cert
status:
  loadBalancer:
    ingress:
    - ip: 1.2.3.4

这是我试图获取但与入口注释不兼容的 nginx 配置:

   location / {
        proxy_cache my_blog_cache;
        proxy_cache_valid 200 30m;
        proxy_cache_valid 404 1m;
        proxy_pass http://ghost_upstream;
        proxy_ignore_headers X-Accel-Expires Expires Cache-Control;
        proxy_ignore_headers Set-Cookie;
        proxy_hide_header Set-Cookie;
        proxy_hide_header X-powered-by;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        expires 10m;
    }
    location /content/images {
        alias /path/to/ghost/content/images;
        access_log off;
        expires max;
    }
    location /assets {
        alias /path/to/ghost/content/themes/uno-master/assets;
        access_log off;
        expires max;
    }
    location /public {
        alias /path/to/ghost/core/built/public;
        access_log off;
        expires max;
    }
    location /ghost/scripts {
        alias /path/to/ghost/core/built/scripts;
        access_log off;
        expires max;
    }
    location ~ ^/(?:ghost|signout) { 
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_pass http://ghost_upstream;
        add_header Cache-Control "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0";
    }

感谢您的帮助!

【问题讨论】:

    标签: kubernetes nginx-ingress


    【解决方案1】:

    nginx-ingress 控制器中有一些选项只能使用ConfigMap 进行更改,而其他选项可以使用Annnotations 进行更改,就像您正在做的那样。

    您可以将两者结合起来以达到预期结果,或创建一个custom template

    Here你可以看到一个可能对你有帮助的替代方案。

    【讨论】:

    • 感谢您的回答。使用注解对于特定规则和配置图影响您的整个入口非常有限?或者也许有一些方法可以将模板或配置映射附加到入口?我通过为每个路径位置创建具有特定注释的多个入口找到了替代方案。例如:路径:/ -> 缓存已应用,缓存状态 = 命中路径:/ghost -> 无注释,缓存状态 = 未命中,它可以工作!这是一个好习惯吗?
    • 为您的应用程序创建多个入口是没有问题的,如果它们都获得相同的IP就可以了,您只需要注意未来的维护......正如您所说, annottations 是一个非常有限的 cusmotize 所有 nginx,这就是你可以选择结合 nginx 模板选项的原因。
    【解决方案2】:

    我有完全相同的愿望:直接在 Kubernetes 集群中的 Nginx Ingress 上缓存 Ghost 对其Cache-Control 标头的响应。

    花了几个小时在这里是我的解决方案:

    第一步

    首先,您需要在 Nginx Ingress ConfigMap level 上定义 proxy_cache_path(文档并不清楚如何应用它)。

    就我而言,我通过 Helm 管理 Nginx Ingress 安装,因此我已将其添加到 Helm 值图表中:

    # Default values https://github.com/kubernetes/ingress-nginx/blob/main/charts/ingress-nginx/values.yaml
    controller:
      config:
        http-snippet: "proxy_cache_path /tmp/nginx_my_cache levels=1:2 keys_zone=mycache:2m use_temp_path=off max_size=2g inactive=48h;"
    

    然后应用此更改:

    helm upgrade -f my-nginx-ingress-values.yaml ingress-nginx ingress-nginx/ingress-nginx --recreate-pods
    

    第二步

    现在我们已经设置了proxy_cache_path,我们需要使用注释为特定主机配置 Ingress:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: myingress
      namespace: mynamespace
      annotations:
        kubernetes.io/ingress.class: "nginx"
        # Buffering must be enabled for Nginx disk cache to work.
        nginx.ingress.kubernetes.io/proxy-buffering: "on"
        # See https://www.nginx.com/blog/nginx-caching-guide/
        # Cache Key Zone is configured in Helm config.
        nginx.ingress.kubernetes.io/server-snippet: |
          proxy_cache mycache;
          proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;
          proxy_cache_background_update on;
          proxy_cache_revalidate on;
          proxy_cache_lock on;
          add_header X-Cache-Status $upstream_cache_status;
    

    注意:

    我花了大部分时间弄清楚为什么我仍然收到MISSes。原来这是由于nginx.ingress.kubernetes.io/proxy-buffering default in Ingressoff — 这会禁用 Nginx 缓存,因此您必须将其设置为 on,这就是我们所做的。

    将更改应用到 Ingress。

    调试生成的 Nginx 配置

    您可以而且我认为应该验证用于 Ingress 的结果 nginx.conf 是应用 ConfigMap 和 Ingress 级别注释的结果。

    为此,您可以将 nginx.conf 从 Ingress Controller pod 复制到本地计算机并验证其内容(或将 exec 复制到 pod 并在那里查看):

    # Make sure to use correct namespace where Ingress Controller is deployed
    # and correct Ingress Controller Pod name
    kubectl cp -n default ingress-nginx-controller-xxxx:/etc/nginx/nginx.conf ~/Desktop/nginx.conf
    

    它应该包含我们所做的所有更改!

    调试实际响应缓存

    现在我们已经配置好了所有东西——是时候验证实际的缓存了。请注意,我们添加了 X-Cache-Status 标头,它将指示它是 HIT 还是 MISS

    我个人喜欢 httpie 用于来自终端的 HTTP 请求,您可以使用 curl 或浏览器:

    第一个请求将是MISS

    http https://example.com/myimage.jpg
    HTTP/1.1 200 OK
    Accept-Ranges: bytes
    Cache-Control: public, max-age=31536000
    Connection: keep-alive
    Content-Length: 53588
    Content-Type: image/jpeg
    Date: Wed, 20 Oct 2021 10:39:06 GMT
    ETag: W/"d154-17c3aa43389"
    Last-Modified: Fri, 01 Oct 2021 06:56:52 GMT
    Strict-Transport-Security: max-age=15724800; includeSubDomains
    X-Cache-Status: HIT
    X-Powered-By: Express
    X-Request-ID: 0c73f97cb51d3071f14968720a26a99a
    
    +-----------------------------------------+
    | NOTE: binary data not shown in terminal |
    +-----------------------------------------+
    

    对同一 URL 的第二次请求现在是 HIT 并且没有命中实际的 Ghost 安装,成功!

    http https://example.com/myimage.jpg
    HTTP/1.1 200 OK
    Accept-Ranges: bytes
    Cache-Control: public, max-age=31536000
    Connection: keep-alive
    Content-Length: 53588
    Content-Type: image/jpeg
    Date: Wed, 20 Oct 2021 10:39:43 GMT
    ETag: W/"d154-17c3aa43389"
    Last-Modified: Fri, 01 Oct 2021 06:56:52 GMT
    Strict-Transport-Security: max-age=15724800; includeSubDomains
    X-Cache-Status: HIT
    X-Powered-By: Express
    X-Request-ID: 0c73f97cb51d3071f14968720a26a99a
    
    +-----------------------------------------+
    | NOTE: binary data not shown in terminal |
    +-----------------------------------------+
    

    验证 Ghost 上的日志以仔细检查缓存 HIT 请求实际上是直接从 Nginx 提供的,并且从未命中 Ghost,这也很有用。


    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-25
      • 2017-03-07
      • 1970-01-01
      • 2022-07-08
      • 1970-01-01
      • 2021-01-30
      • 2021-04-30
      • 2019-03-13
      相关资源
      最近更新 更多