Impossible to use Google Cloud CDN cache with ingress controller, Transfer-Encoding header

3/15/2018

I try to configure Google Cloud CDN to my container engine project.

Following the documentation It has either a Content-Length header or a Transfer-Encoding header in order to be cached.

My backend use gzip compression so I have Transfer-Encoding: chunked

The problem is it seems the ingress load balancer remove the Transfer-encoding header so I can't have a "cache hit"

I used "kubectl port-forward" to connect direclty to an instance backend and I have the Transfer-encoding header.

But when I connect to the external IP, the header has disappear.

Here my ingress configuration

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: gateway-preprod3-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: gateway-preprod2-static-ip
spec:
  tls:
  - secretName: gateway-preprod-secret-2018-with-ca-7
  backend:
    serviceName: gateway-preprod
    servicePort: 80

Here my deployment configuration

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: gateway-preprod
spec:
  replicas: 1
  strategy:
    type: RollingUpdate
  minReadySeconds: 50
  template:
    metadata:
      labels:
        app: gateway-preprod
    spec:
      containers:
      - name: gateway-preprod
        image: eu.gcr.io/writecontrol-1055/gateway:v305
        env:
        - name: writecontrolEnv
          value: preprod
        ports:
        - containerPort: 80

In the opposite, for certain ressources not GZIP compressed, the Content-length header is given and I have a successful "cache hit"

The kubernetes version is 1.7.12-gke.1

Here an URL to test it : https://preprod-writecontrol.ovh

-- maxiplay
google-cloud-cdn
google-cloud-platform
google-kubernetes-engine
kubernetes-ingress
transfer-encoding

1 Answer

3/27/2018

I am not sure why your response has Transfer-Encoding header. This header is not meant to be at the source (your application) and it is usually added by other hops, such as proxies like Cloud HTTP Load Balancer (=Ingress).

More info on Transfer-Encoding here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding


I was able to get CDN working with a GZIP response myself using the Content-Encoding header instead:

First read the caching requirements at https://cloud.google.com/cdn/docs/caching. You need a Content-Length and/or Cache-Control: public header. So code these headers into your application server.

After enabling CDN on the load balancer created by Ingress, make two requests, and if you see Age header on the second request (as I did below), it means your request is now being served from CDN.

curl -vH Accept-Encoding:gzip 35.186.195.233
> [...]
>
< HTTP/1.1 200 OK
< Content-Encoding: gzip
< Date: Tue, 27 Mar 2018 19:38:20 GMT
< Content-Length: 87
< Content-Type: application/x-gzip
< Via: 1.1 google
< Cache-Control: max-age=600,public

��H����Q(�/�IQ�
* Connection #0 to host 35.186.195.233 left intact
K-*��ϳR0�33���/.�K�M�R�)+OM�55575��L�4ѭ�N+L���K��4A

And the second request (note the Age header):

$ curl -vH Accept-Encoding:gzip 35.186.195.233
[...]
>
< HTTP/1.1 200 OK
< Cache-Control: max-age=600,public
< Content-Encoding: gzip
< Date: Tue, 27 Mar 2018 19:42:01 GMT
< Content-Length: 87
< Content-Type: application/x-gzip
< Via: 1.1 google
< Age: 314
<
��H����Q(�/�IQ�
* Connection #0 to host 35.186.195.233 left intact
K-*��ϳR0�33���/.�K�M�R�)+OM�55575��L�4ѭ�N+L���K��4A
-- AhmetB - Google
Source: StackOverflow