Deploy a dynamic Service Gateway for Lagom in production - lagom

I have developed a set of Lagom microservices. The development environment provides with default Service Gateway and Service Locator.
In a production environment I would like my services to:
register to a service registry
be available to a web app through a service locator that uses this registry
What should I use as Service Registry / Service Locator / Service Gateway ?
A simple NGINX would be a reasonable service gateway but it implies a very static configuration based on redirect rules (no actual registration).
I cannot find any code sample on this subject and the documentation is very poor (it describes well development tools but doesn't help when it comes to actual production).

The documentation on that area is vague on purpose because the ecosystem is very vast and changes fast.
You could, for example, use Consul or ZooKeeper to keep track of the instances that are runnning for each service and where they are running (where means IP:PORT). Then you would need to use a Consul-based or a ZooKeeper-based Service Locator instance. The preferred target deployment environment these days is Kubernetes (in any of its flavors) so the service location is based on DNS-SRV lookups on the DNS server provided by k8s. The registration step happens automatically in a k8s setup for each pod so you won't need to care for that.
Then, the reverse proxy on the edge capable of directing each request to the appropriate process is a plain-old HTTP proxy that can check your service location (or cache the service location information). These days the recommendation is configuring an Ingress/Route (for k8s or OpenShift) edge proxy for each of your lagom services.
See the guide on Deploying a Lagom application to Openshift for a thorough explanation.

Related

Kubernetes application authentication

Maybe this is a dumb question, but I really don't know if I have to secure applications with tokens etc. within a kubernetes cluster.
So for example I make a grpc-call from a client within the cluster to a server within the cluster.
I thought this should be secure without authenticating the client with a token or something like that, because (if I understood it right) kubernetes pods and services work within a VPN which won't be exposed as long as it's not told to.
But is this really secure, should I somehow build an authorization system within my cluster?
Also how can I use a service to load balance the grpc-calls over the server pods without exposing the server outside the cluster?
If you have a service, it already has built-in load balancer when you have more than one replica out of the box.
Also Kubernetes traffic is internal within the cluster out of the box, unless you explicitly expose traffic using LoadBalancer, Ingress or NodePort.
Does it mean traffic is safe? No.
By default, everything is allowed within Kubernetes cluster so every service can reach every service or pod in StatefulSet apps.
You can use NetworkPolicy to allow traffic from one service to another service and nothing else. That would increase security.
Does it mean traffic is safe now? It depends.
Authentication would add an additional security layer in case container is hacked. There could be more scenarios, but I can't think of for now.
So internal authentication is usually used to improve security in production systems.
I hope it answers the question.

Apache web server and microservices with Docker

I have a few spring boot microservices running on Docker, and Apache web server (also running on Docker) for all the static stuff. The microservices are consumed by the web browser. Problem is, I don't know how I should reference the microservices from html or javascript:
the microservice runs on a different port
also might run on a different host
the browser complains about links
Googling the problem points me toward Netflix eureka or Apache Camel, but I'm not sure these are the right solutions.
Let's first think about deployment. You mention that the Docker containers might run on different machines. I recommend using container orchestrators like Docker Swarm or Kubernetes to manage a cluster and communication between microservices (typically via DNS).
Generally, you want to hide all your microservices behind one API path. The outside world does not need to know that your server application consists of multiple microservices. You can use a simple reverse proxy for this. I personally like Traefik because you can configure the routing paths in the Docker ecosystem via labels.
You say you consume the microservice APIs with a browser, so is it a web client application? If so, I recommend serving it as Docker container as well and embed it into the routing by using relative paths. E.g. UI is served as / and microservices as /api/{service}/{path}. Then the UI application can use relative paths because they are served by the same reverse proxy and such under the same URL (=> no CORS issues). Additionally, you can deploy to any IP, the routing stays the same and does not have to be adjusted

Will there be support to establish a private connection to Azure AKS

My client is currently evulating AKS which seems to be really promising. Our current platform is based on Azure VM's we provision ourselves. We would like to create private communication between both our existing platform and the managed AKS cluster but so far that does not seem to be supported yet.
Some example use cases for us are:
- Proxying incoming HTTP traffic via our main entrypoint, a Varnish server, to the new AKS environment so we don't have to change url's
- Accessing non publically exposed API's from the AKS environment
Right now the AKS cluster is it's a different subscription and resource group than other parts of our platform. The main reason we we can't connect though seems to be that it's not possible to specify which private IP range should be used when creating an AKS cluster.
Is there support planned for this or is there a reliable workaround?
Thanks for the inquiry, there's a workaround for the stated case, it's through the use of ACS Engine, "ACS Engine, for Azure Container Service Engine, is a CLI tool that helps to generate Azure Resource Manager templates to deploy Docker enabled clusters on Microsoft Azure. It works with all the orchestrators supported by ACS: Docker Swarm, Mesosphere DC/OS and Kubernetes"
So using this solution will allow you to integrate Azure Container Service Cluster into an existing Virtual Network.More details and step by step guide can be found here: https://blogs.msdn.microsoft.com/jcorioland/2017/01/10/how-to-integrate-a-new-azure-container-service-cluster-into-an-existing-virtual-network-using-acs-engine/

How do you create a net.tcp endpoint to an Azure Cloud Service?

This has to be a pretty simple task. I have an Azure Cloud Service that works just fine with HTTP and HTTPS. Now I want to create a net.tcp connection to the cloud service. The first thing I discover is that net.tcp is not supported by IIS Express. That's fine. So I try switching to regular IIS and all I get when I try to run the application is a 404 error. If I was building an WCF Web Application, I would get a form that allows me to select (and build) the virtual directory for the application, but there's no analog for this in the Cloud Service.
I can take a fresh 'Cloud Service' project build using visual studio, make no changes to it except change IIS Express to IIS. When I launch it, I get a 404 error in the web browser.
Does anyone have a working example of tcp.net (with IIS Express or standard IIS) in a Cloud Service?
This video by the Azure team is a great overview and cleared up a lot of conceptual issues I had. An Azure Cloud Service is a container around one or more virtual machines. The virtual machines basically come in two flavors: Web Role and Worker Role. What threw me is the description that the Worker Role was intended for background processes: not true. A Web Role is basically a VM with IIS, a Worker Role is basically a VM without IIS. Since the off-the-shelf IIS doesn't have net.tcp installed, you have to jump through hoops in order to get the protocol installed. Instead, the Worker Role can be used as a self-hosted web service. If you want the performance and throughput of TCP, this appears to be the direction to go.

Kubernetes API for provisioning pods-as-a-service?

Currently I have an app (myapp) that deploys as a Java web app running on top of a "raw" (Ubuntu) VM. In production there are essentially 5 - 10 VMs running at any given time, all load balanced behind an nginx load balancer. Each VM is managed by Chef, which injects the correct env vars and provides the app with runtime arguments that make sense for production. So again: load balancing via nginx and configuration via Chef.
I am now interested in containerizing my future workloads, and porting this app over to Docker/Kubernetes. I'm trying to see what features Kubernetes offers that could replace my app's dependency on nginx and Chef.
So my concerns:
Does Kube-Proxy (or any other Kubernetes tools) provide subdomains or otherwise-loadbalanced URLs that could load balance to any number of pod replicas. In other words, if I "push" my newly-containerized app/image to Kubernetes API, is there a way for Kubernetes to make image available as, say, 10 pod replicas all load balanced behind myapp.example.com? If not what integration between Kubernetes and networking software (DNS/DHCP) is available?
Does Kubernetes (say, perhas via etc?) offer any sort of key-value basec configuration? It would be nice to send a command to Kubernetes API and give it labels like myapp:nonprod or myapp:prod and have Kubernetes "inject" the correct KV pairs into the running containers. For instance perhaps in the "nonprod" environment, the app connects to a MySQL database named mydb-nonprod.example.com, but in prod it connects to an RDS cluster. Or something.
Does Kubernetes offer service registry like features that could replace Consul/ZooKeeper?
Answers:
1) DNS subdomains in Kubernetes:
https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/dns
Additionally, each Service loadbalancer gets a static IP address, so you can also program other DNS names if you want to target that IP address.
2) Key/Value pairs
At creation time you can inject arbitrary key/value environment variables and then use those in your scripts/config. e.g. you could connect to ${DB_HOST}
Though for your concrete example, we suggest using Namespaces (http://kubernetes.io/v1.0/docs/admin/namespaces/README.html) you can have a "prod" namespace and a "dev" namespace, and the DNS names of services resolve within those namespaces (e.g. mysql.prod.cluster.internal and mysql.dev.cluster.internal)
3) Yes, this is what the DNS and Service object provide (http://kubernetes.io/v1.0/docs/user-guide/walkthrough/k8s201.html#services)