Recommended way of serving static content like videos/images on k8s - kubernetes

I'm pretty green with Kubernetes but have some experience with Google Container Engine. I'm struggling to find a good solution for serving media content from applications.
I've currently got media stored in a public bucket on Google Cloud Platform, and i'm running an NGINX proxy on local to take any path /images to the bucket for example:
location /videos {
proxy_pass https://storage.googleapis.com/bucket-name/videos;
proxy_intercept_errors on;
error_page 500 502 503 504 404 = #localmedia;
}
What way would you recommend to serve media content on applications running on k8s?

If you need to serve static files form Google Cloud Storage the best way is to use directly the custom domain bucket feature no use K8S.
https://cloud.google.com/storage/docs/hosting-static-website
Basically you need to create your bucket as public with the name of the domain or subdomain you want to use and pint it as a CNAME to the special domain c.storage.googleapis.com
With that said, what is the main reason to use k8s?

Related

google cloud CDN always serve my static file through only 1 IP

I have my google bucket connect with a load balancer and CDN enabled in google cloud, but I really don't get how google CDN working for static file, checking in the log viewer i can see the "statusDetails: response_from_cache" and "cacheHit: true" so i can say that the CDN is working properly.
Trying to issue a request for the image in my google CDN bucket from a computer located in Europe, the file return from the frontend IP address of my load balancer. Also the same IP address served my image if i make the request from a computer located in Asia.
So the same IP address was used for serving my static image ignore the location where the request coming from, checking the log viewer again, i can see that both of the request has claimed to go through google CDN, again google log viewer tell me that CDN working properly.
i think that the CDN should serve the file from the nearest server to the end-users, what is the point for using google CDN if the file always served from only 1 single IP address for all user over the world?
I have a free account of cloudflare, once i configure my DNS, the image file go through cloudflare network and if i do the test as above, i will see my static image file returned from multiple IP address which is nearest to my end-users.
Could somebody help me to understand what is the purpose for using google CDN in this case ? did i miss something in the configuration process for google CDN?
Thanks a lot in advance.
Google Cloud CDN uses Google's global edge network to serve content
closer to users and it leverages Google Cloud global external HTTP(S)
load balancers to provide routing, health checking, and Anycast IP
support. The HTTP(S) load balancing configuration specifies the
frontend IP addresses and ports on which Cloud CDN receives requests
and the backends that originate responses to those requests.
Google CDN has a special feature of ‘single anycast IP for the whole
network’ letting all contents served through the load balancer
frontend IP resulting in low latency. So rather than having one load
balancer per region, you can simplify your architecture and have
every instance behind a single global load balancer. Also it has a
feature of HTTP/2 which supports the latest HTTP protocol for faster
performance. For additional information, you can check here.
Cloud CDN reduces latency by serving assets directly at Google's
network edge. To know more about the caching using Cloud CDN, refer
to this caching-overview docs.

Google cloud platform - Set up a 301 redirect from www

When I was on AWS, setting up a 301 redirect for my website from www.example.com --> example.com involved simply creating a S3 bucket as a static website and set it up to redirect all traffic to example.com.
I don't see this option on Google cloud storage and I can't think of any way to do this with the HTTP load balancer.
Is the only way doing it involves patching my backend to notice addresses that start with www and strip the www and redirect ?
Google has a way of using buckets as backends for the http load balancer.
It is still in alpha but you can read about it and ask them to try it here. Use it with a html file to redirect like suggested here and my guess it should work.
Alternatively, I use Cloudflares free service, which allows for 3 free redirects. Saving you the trouble of configuring redirects in your backend. This can be done with some other CDN services as well I don't know which.

How to use S3 as static web page and EC2 as REST API for it together? (AWS)

With AWS services we have the Web application running from the S3 bucket and accessing the data through the REST API from Load Balancer (which is set of Node.js applications running on EC2 instance).
Currently we have specified URL's as following:
API Load Balancer: api.somedomain.com
Static Web App on S3: somedomain.com
But having this setup brought us a set of problems since requests are CORS with this setup. We could workaround CORS with special headers, but that doesn't work with all browsers.
What we want to achieve is running API on the same domain but with different path:
API Load Balancer: somedomain.com/api
Static Web App on S3: somedomain.com
One of the ideas was to attach the API Load Balancer to the CDN and forward all request to Load Balancer if query is coming on the "/api/*" path. But that doesn't work since our API is using not only HEAD and GET requests, but also POST, PUT, DELETE.
Another idea is using second EC2 instance instead of S3 bucket to host website (using some web server like nginx or apache). But that gives too much overhead when everything is in place already (S3 static content hosting). Also if using this scenario we wouldn't get all the benefits of Amazon CloudFront performance.
So, could your recommend how to combine Load Balancer and S3, so they would run on same domain, but with different paths? (API on somedomain.com/api and Web App on somedomain.com)
Thank you!
You can't have an EC2 instance and an S3 bucket with the same host name. Consider what happens when a web browser makes a request to that host name. DNS resolves it to an IP address (or addresses) and the packets of the request are delivered to that address. The address either terminates at the EC2 instance or the S3 bucket, not both.
As I understand your situation, you have static web pages hosted on S3 that include JavaScript code that makes various HTTP requests to the EC2 instance. If the S3 web pages are on a different host than the EC2 instance then the same origin policy will prevent the browser from even attempting some of the requests.
The only solutions I can see are:
Make all requests to the EC2 instance, with it fetching the S3 contents and delivering it to the browser whenever a web page is asked for.
Have your JavaScript use iframes and change the document.domain in the the web pages to a common parent origin. For example, if your web pages are at www.example.com and your EC2 instance is at api.example.com, the JavaScript would change document.domain to just example.com and the browser would permit iframes from from www.example.com to communicate with api.example.com.
Bite the bullet and use CORS. It's really not hard, and it's supported in all remotely recent browsers (IE 8 and 9 do it, but not in a standard way).
The first method is no good, because you almost might as well not use S3 at all in that case.
The second case should be okay for you. It should work in any browser, because it's not really CORS. So no CORS headers are needed. But it's tricky.
The third, CORS, approach should be just fine. Your EC2 instance just has to return the proper headers telling web pages from the S3 bucket that it's safe for them to talk to the EC2 instance.
Just wanted to add an additional bit to the answer that, if we go with CORS approach and preflight requests adds an overhead to the server and network bandwidth, we may even consider adding header "Access-Control-Max-Age" to the CORS response
Access-Control-Max-Age

How to optimally serve static files with REST API back-end on Heroku

This question may be a bit subjective but I think will offer some valuable concrete information and solutions to proxying to heroku and debugging latency issues.
I have an app built using Sinatra/Mongo that exposes a REST API at api.example.com. It's on Heroku Cedar. Typically I serve static files through nginx at www and proxy requests to /api through to the api subdomain to avoid cross-domain browser complaints. I have a rackspace cloud instance so I put the front-end there temporarily on nginx and setup the proxy. Now latency is horrible when proxying, every 3 or 4 requests it takes longer than 1 minute, otherwise ~150ms. When going directly to the API (browser to api.example.com) average latency is ~40ms. While I know the setup isn't ideal I didn't expect it to be that bad.
I assume this is in part due to proxying from rackspace - server may well be on the west coast - to heroku on amazon ec2 east. My thought at the moment is that getting an amazon ec2 instance and proxying that to my heroku app would alleviate the problem, but I'd like to verify this somehow rather than guessing blindly (it's also more expensive). Is there any reasonable way to determine where the long latency is coming from? Also, any other suggestions as to how to structure this application? I know I can serve static files on Heroku, but I don't like the idea of my API serving my front-end, would rather these be able to scale independently of one another.
Since you're using Heroku to run your API, what I'd suggest is putting your static files into an Amazon S3 bucket, something named 'myapp-static', and then using Amazon Cloudfront to proxy your static files via a DNS CNAME record (static.myapp.com).
What's good about using S3 over Rackspace is that:
Your files will be faster for you to upload from Heroku, since both your app and storage are on the same network (AWS).
S3 is built for serving static files directly, without the overhead of running your own server proxying requests.
What's good about using Cloudfront is that it will cache your static files as long as you want (reducing multiple HTTP requests), and serve files from an endpoint closest to the user. EG: If a user in California makes an API request and gets a static file from you, it will be served from them from the AWS California servers as opposed to your East Coast Heroku instances.
Lastly, what you'll do on your application end is send the user a LINK to your static asset (eg: http://static.myapp.com/images/background.png) in your REST API, this way the client is responsible for downloading the content directly, and will be able to download the asset as fast as possible.

redirect root domain name to amazon s3

My domain is rather long. I need to use it without www.
All the info I find on the net is about cnames.
How do I redirect the whole domain to an amazon s3 bucket, not only a subdomain?
Amazon recently announced support for root domain hosting via S3. The instructions for setting this up can be found here. Note that you will have to setup two buckets to accomplish this, and that you will have to use Route 53 for your DNS hosting.
Try wwwizer
What you need to do is to create a cname www pointing to your s3 bucket url (bucket name will need to match) and then create an A record to the ip given by wwwizer.
Another way is to use a url redirecting service or use a free web host (like godaddy's ad supported hosting) and on the index file issue a redirect to www.yourdomain.com.
There might be other solutions that rely on finding out the ips of the amazon s3 front end servers but they are error prone.