Deploy gRPC supporting application on AWS using ALB - amazon-web-services

I have two microservices communicating using gRPC.Both are docker applications deployed on ECS. How do I configure them to use AWS ALB?In documentation it says ALB supports HTTP/2, however I can only see HTTP1 settings.
My application has one gRPC port and one health check API at 8080.How do I configure that on ALB?

I don't believe you can.
ALBs "support" HTTP2 but only in so far as they can accept HTTP2 and de-multiplex it before forwarding on HTTP1.
You can use AWS's newer "NLB" though that has other wrinkles.
More details of doing this https://blog.prefab.cloud/blog/grpc-aws-some-gotchas

As of 30th October 2020, it is now possible to do this, as end-to-end support for HTTP/2 has finally been added to ALBs.
Annoucement about this: https://aws.amazon.com/about-aws/whats-new/2020/10/application-load-balancers-enable-grpc-workloads-end-to-end-http-2-support/
Check these blog posts to understand how to set it up on ECS:
Using Fargate Launch type: https://aws.amazon.com/blogs/opensource/containerize-and-deploy-a-grpc-application-on-aws-fargate/
Using EC2 Launch type: https://dev.to/chaitan94/deploying-a-grpc-service-in-ecs-with-the-ec2-launch-type-2aa

Related

Deploy grpc web application on AWS ECS

Deploying a grpc service on AWS was pretty straight forward thanks to the built in support in their load balancer, but as far as I can tell they don't have a built in solution for grpc-web?
What would be the easiest way to add support for grpc-web for a low volume service running in ECS?

Kubernetes with an UDP loadbalancer with sticky sessions based on IP

I'm trying to deploy an UDP-based application on kubernetes, but I'm having troubles finding a suitable cloud provider that has an UDP loadbalancer with IP-based sticky sessions.
I have tried using DigitalOcean Kubernetes Service (DOKS) but they don't support UDP loadbalancers.
EKS (AWS' kubernetes service) provides UDP support with NLB for example, but they don't seem to have sticky sessions on that type of loadbalancer, only on the classic LB.
Is there another cloud provider (I'm thinking of GCE or Azure) that provides my required functionalities out of the box?
I'm asking this here to know if anyone else has had the same problem and maybe has already tried various solutions, and has already found the perfect fit.
I know in Nginx Ingress Controller (which I know works with AWS and NLB with UDP support as you stated) can expose UDP services and supports sticky sessions. I have not done this in AWS or any other cloud provider, but I have with similar use cases on bare-metal.
As #jordanm posted, the answer was to apply the stickiness parameter through the ec2 console.

Kubernetes ELB service: How to disable TLS 1.0 and 1.1?

I am running Kubernetes on AWS, and exposing services using a Service with type: LoadBalancer, which provisions an ELB. Is there any way to control the ELB cipher configuration with annotations on this service? I need to disable TLS 1.0 and 1.1.
I am aware that I can do this by hand, but I would like for Kubernetes to do this for me, otherwise I'll have to remember to do it again the next time a new ELB is provisioned (Kubernetes upgrade, config change, etc).
If I understood you right, you would like to adjust security policies directly from Service.yml file.
From what I see, here you can find a list of all the annotations that are supported at the moment.
There is one called "aws-load-balancer-ssl-negotiation-policy". For me it looks exactly as the one you are looking for.
// ServiceAnnotationLoadBalancerSSLNegotiationPolicy is the annotation used on
// the service to specify a SSL negotiation settings for the HTTPS/SSL listeners
// of your load balancer. Defaults to AWS's default
const ServiceAnnotationLoadBalancerSSLNegotiationPolicy = "service.beta.kubernetes.io/aws-load-balancer-ssl-negotiation-policy"
The link to that file is listed under official documentation on K8s.
Additionally, there is a predefined policy ELBSecurityPolicy-TLS-1-2-2017-01 that uses only TLS v1.2 ( with 1.0 and 1.1 disabled).
Hope that helps.
you can use for example annotations like:
alb.ingress.kubernetes.io/ssl-policy: ELBSecurityPolicy-TLS-1-1-2017-01
ALB Ingress Controller SSL Policy Annotations
Edit the Security policy on the HTTPS listener on the Load Balancer.

Load balancing gRPC requests using one of AWS Load Balancers

I'm trying to work out whether I could use one of the (A/E/N)LBs to load balance gRPC traffic. A simple round robin would suffice in our case.
I've read that ALB doesn't fully support HTTP2 and therefore can't be used with gRPC. Specifically lack of support of sending HTTP2 traffic downstream and lack of support for trailer headers was mentioned. Is it still true?
Couldn't find any definitive answers with regards to NLBs or "classic" ELBs. Any hints?
As of October 29, 2020, Application Load Balancers now support HTTP/2 and gRPC load balancing. From the announcement:
To use the feature on your ALB, choose HTTPS as your listener protocol, gRPC as the protocol version for your target group and register instance or IP as targets for the configured target group. ALB provides rich content based routing features that will let you inspect gRPC calls and route them to the appropriate target group based on the service and method requested. Within a target group, ALB will use gRPC specific health checks to determine availability of targets and provide gRPC specific access logs to monitor your traffic.
The support for gRPC and end-to-end HTTP/2 is available for existing and new Application Load Balancers at no extra charge in all AWS Regions. To learn more, please refer to the blog post, demo, and the ALB documentation.
Using gRPC on AWS had some major challenges. Without full HTTP/2 support on AWS Application Load Balancer, you have to spin up and manage your own load balancers. Neither NLB and ELB are viable alternatives on AWS due to issues with traffic to and from the same host, dynamic port mappings, SSL termination complications, and sub-optimal client and server-side round-robining of TCP connections.
gRPC demonstrated performance improvements, however, it would take considerable infrastructure efforts to adopt, whether it be using LBs such as Nginx or Envoy; or setting up a service mesh with something of the likes of Istio. Another possibility would be to make use of thick client load balancing, though this would also require additional service discovery infrastructures such as Consul or ZooKeeper.
AWS recently announced a new service called AWS App Mesh. AWS App Mesh supports HTTP2 and gRPC services
gRPC can now model and manage their inter-service communications using AWS App Mesh.
Reference:
https://aws.amazon.com/about-aws/whats-new/2019/11/aws-app-mesh-now-supports-http2-and-grpc-services/
https://aws.amazon.com/app-mesh/
https://docs.aws.amazon.com/app-mesh/latest/userguide/what-is-app-mesh.html

How to setup an external kubernetes service in AWS using https

I would like to setup a public kubernetes service in AWS that listens on https.
I know that kubernetes services currently only support TCP and UDP, but is there a way to make this work with the current version of kubernetes and AWS ELBs?
I found this. http://blog.kubernetes.io/2015/07/strong-simple-ssl-for-kubernetes.html
Is that the best way at the moment?
Https usually runs over TCP, so you can simply run your service with Type=Nodeport/LoadBalancer and manage the certs in the service. This example might help [1], nginx is listening on :443 through a NodePort for ingress traffic. See [2] for a better explanation of the example.
[1] https://github.com/kubernetes/kubernetes/blob/release-1.0/examples/https-nginx/nginx-app.yaml#L8
[2] http://kubernetes.io/v1.0/docs/user-guide/connecting-applications.html
Since 1.3, you can use annotations along with a type=LoadBalancer service:
https://github.com/kubernetes/kubernetes/issues/24978
service.beta.kubernetes.io/aws-load-balancer-ssl-cert=arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012
service.beta.kubernetes.io/aws-load-balancer-ssl-ports=* (or e.g. https)
The first annotation is the only one you need if all you want is to support HTTPS, on any number of ports. If you also want to support HTTP on one or more additional ports, you need to use the second annotation to specify explicitly which ports will use encryption (the others will use plain HTTP).
In my case I setup an elb in aws and setup the ssl cert on that, choosing https and http for the connection types in the elb and that worked great. I setup the elb wroth kubectl expose.