Skip to content

Instantly share code, notes, and snippets.

@gbrayut
Created June 28, 2022 22:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gbrayut/c52420e63075ad5559ea75b2042e47f9 to your computer and use it in GitHub Desktop.
Save gbrayut/c52420e63075ad5559ea75b2042e47f9 to your computer and use it in GitHub Desktop.
# The manifest below setups up a simple upload server behind gke ingress. Easiest to test from Cloud Shell or another GCE VM
# But there does seem to be a timeout/slowloris mitigation so testing with real world upload speeds is also recommended
# Also, the "right" way to do this is chunked uploads and/or direct to GCS signed URLs.
# But so far I don't see a reason why GCLB HTTPS LBs wouldn't work
# Download test files from http://xcal1.vodafone.co.uk/
curl -vsF file=@5MB.zip http://34.111.109.144:80/upload?token=1234
curl -vsF file=@50MB.zip http://34.111.109.144:80/upload?token=1234
curl -vsF file=@200MB.zip http://34.111.109.144:80/upload?token=1234
# Expected
* Connected to 34.111.109.144 (34.111.109.144) port 80 (#0)
> POST /upload?token=1234 HTTP/1.1
> Host: 34.111.109.144
> User-Agent: curl/7.83.1
> Accept: */*
> Content-Length: 209715401
> Content-Type: multipart/form-data; boundary=------------------------dc9d8398bfcd2ccf
> Expect: 100-continue
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 100 Continue
* We are completely uploaded and fine
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Tue, 28 Jun 2022 22:04:45 GMT
< Content-Length: 37
< Content-Type: text/plain; charset=utf-8
< Via: 1.1 google
<
* Connection #0 to host 34.111.109.144 left intact
{"ok":true,"path":"/files/200MB.zip"}
# If the BackendConfig timeoutSec is too low (default 30 seconds) you might instead see this
# along with server errors msg="failed to acquire the uploaded content" error="unexpected EOF"
* Send failure: Broken pipe
* Closing connection 0
# I could not reproduce a 413 respose (didn't try bloating headers or files larger than 200MB)
k logs -n testing simple-upload-deployment-6c8c87bc44-gsl77
time="2022-06-28T21:32:37Z" level=info msg="starting up simple-upload-server"
time="2022-06-28T21:32:37Z" level=info msg="start listening" cors=false ip=0.0.0.0 port=25478 protected_method="[GET POST HEAD PUT]" root=/tmp/ token=1234 upload_limit=1073741824
time="2022-06-28T21:37:40Z" level=info msg="file uploaded by POST" path=/tmp/5MB.zip size=5242880 url=/files/5MB.zip
time="2022-06-28T21:38:32Z" level=info msg="file uploaded by POST" path=/tmp/5MB.zip size=5242880 url=/files/5MB.zip
time="2022-06-28T21:38:43Z" level=info msg="file uploaded by POST" path=/tmp/200MB.zip size=209715200 url=/files/200MB.zip
time="2022-06-28T21:42:08Z" level=info msg="file uploaded by POST" path=/tmp/5MB.zip size=5242880 url=/files/5MB.zip
time="2022-06-28T21:42:44Z" level=error msg="failed to acquire the uploaded content" error="unexpected EOF"
time="2022-06-28T21:46:30Z" level=error msg="failed to acquire the uploaded content" error="unexpected EOF"
time="2022-06-28T21:51:21Z" level=info msg="file uploaded by POST" path=/tmp/20MB.zip size=20971520 url=/files/20MB.zip
time="2022-06-28T21:55:16Z" level=error msg="failed to acquire the uploaded content" error="unexpected EOF"
time="2022-06-28T22:01:28Z" level=info msg="file uploaded by POST" path=/tmp/50MB.zip size=52428800 url=/files/50MB.zip
time="2022-06-28T22:04:44Z" level=info msg="file uploaded by POST" path=/tmp/200MB.zip size=209715200 url=/files/200MB.zip
# Can also find details in Cloud Logging using query like:
resource.type="http_load_balancer"
jsonPayload.remoteIp="1.2.3.4" # Enter client IP here
Expected:
jsonpayload ... statusDetails: "response_sent_by_backend"
Error:
jsonpayload ... statusDetails: "backend_connection_closed_after_partial_response_sent"
apiVersion: apps/v1
kind: Deployment
metadata:
name: simple-upload-deployment
namespace: testing
labels:
app: simple-upload
spec:
selector:
matchLabels:
app: simple-upload
template:
metadata:
labels:
app: simple-upload
annotations:
sidecar.istio.io/inject: "false"
spec:
containers:
- name: server
image: docker.io/mayth/simple-upload-server
command: ["/usr/local/bin/app"]
args:
- "-upload_limit"
- "1073741824"
- "-token"
- "1234"
- /tmp/
ports:
- containerPort: 25478
# Used for gclb backend health checks
- name: whereami
image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1.2.8
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
annotations:
# https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-features#same_backendconfig_for_all_service_ports
cloud.google.com/backend-config: '{"default": "simple-upload-bc"}'
name: simple-upload
namespace: testing
spec:
type: ClusterIP # use type: LoadBalancer to add a Network TCP LB for testing
selector:
app: simple-upload
ports:
- name: http
port: 80
targetPort: 25478
# this technically isn't required, since all we use it for is a direct health check https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-features#direct_health
- name: whereami
port: 8000
targetPort: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
# https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-features#associating_frontendconfig_with_your_ingress
networking.gke.io/v1beta1.FrontendConfig: "simple-upload-fc"
name: simple-upload-ingress
namespace: testing
spec:
rules:
- http:
paths:
- path: /*
pathType: ImplementationSpecific
backend:
service:
name: simple-upload
port:
number: 80
---
apiVersion: networking.gke.io/v1beta1
kind: FrontendConfig
metadata:
name: simple-upload-fc
namespace: testing
spec:
# https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-features#configuring_ingress_features_through_frontendconfig_parameters
redirectToHttps:
enabled: false
---
apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
name: simple-upload-bc
namespace: testing
spec:
# https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-features#configuring_ingress_features_through_backendconfig_parameters
healthCheck:
checkIntervalSec: 15
requestPath: /healthz
port: 8080 # port for whereami container
type: HTTP
# https://cloud.google.com/load-balancing/docs/backend-service#timeout-setting
timeoutSec: 3600 # 1 hour
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment