"One way to deploy your microservices is to use the Multiple Service Instances per Host
pattern. When using this pattern, you provision one or more physical or virtual hosts and
run multiple service instances on each one. Multiple Service Instances per Host pattern has some significant
drawbacks. One major drawback is that there is little or no isolation of the service
instances, unless each service instance is a separate process. While you can accurately
monitor each service instance’s resource utilization, you cannot limit the resources each
instance uses. It’s possible for a misbehaving service instance to consume all of the
memory or CPU of the host.
There is no isolation at all if multiple service instances run in the same process.
All instances might, for example, share the same JVM heap. A misbehaving service
instance could easily break the other services running in the same process. Moreover,
you have no way to monitor the resources used by each service instance.
Another significant problem with this approach is that the operations team that deploys a
service has to know the specific details of how to do it. Services can be written in a variety
of languages and frameworks, so there are lots of details that the development team must
share with operations. This complexity increases the risk of errors during deployment.----------Another way to deploy your microservices is the Service Instance per Host pattern.
When you use this pattern, you run each service instance in isolation on its own host.
There are two different specializations of this pattern: Service Instance per
Virtual Machine and Service Instance per Container.------When you use Service Instance per Virtual Machine pattern, you package each service
as a virtual machine (VM) image such as an Amazon EC2 AMI. Each service instance is
a VM (for example, an EC2 instance) that is launched using that VM image. This is the primary approach used by Netflix to deploy its video streaming service.
Netflix packages each of its services as an EC2 AMI using Aminator. Each running service
instance is an EC2 instance.
There are a variety tools that you can use to build your own VMs. You can configure your
continuous integration (CI) server (for example, Jenkins) to invoke Aminator to package
your services as an EC2 AMI.Packer is another option for automated VM image creation.
Unlike Aminator, it supports a variety of virtualization technologies including EC2,
DigitalOcean, VirtualBox, and VMware.
The company Boxfuse has a compelling way to build VM images, which overcomes the
drawbacks of VMs that I describe below. Boxfuse packages your Java application as a
minimal VM image. These images are fast to build, boot quickly, and are more secure
since they expose a limited attack surface.
The company CloudNative has the Bakery, a SaaS offering for creating EC2 AMIs. You can
configure your CI server to invoke the Bakery after the tests for your microservice pass.
The Bakery then packages your service as an AMI. Using a SaaS offering such as the Bakery
means that you don’t have to waste valuable time setting up the AMI creation infrastructure.
The Service Instance per Virtual Machine pattern has a number of benefits. A major benefit
of VMs is that each service instance runs in complete isolation. It has a fixed amount of
CPU and memory and can’t steal resources from other services.
Another benefit of deploying your microservices as VMs is that you can leverage mature
cloud infrastructure. Clouds such as AWS provide useful features such as load balancing
and autoscaling.
Another great benefit of deploying your service as a VM is that it encapsulates your
service’s implementation technology. Once a service has been packaged as a VM it
becomes a black box. The VM’s management API becomes the API for deploying the
service. Deployment becomes much simpler and more reliable.
The Service Instance per Virtual Machine pattern has some drawbacks, however.
One drawback is less efficient resource utilization. Each service instance has the overhead
of an entire VM, including the operating system. Moreover, in a typical public IaaS, VMs
come in fixed sizes and it is possible that the VM will be underutilized.
Moreover, a public IaaS typically charges for VMs regardless of whether they are busy
or idle. An IaaS such as AWS provides autoscaling, but it is difficult to react quickly to
changes in demand. Consequently, you often have to overprovision VMs, which increases
the cost of deployment.
Another downside of this approach is that deploying a new version of a service is usually
slow. VM images are typically slow to build due to their size. Also, VMs are typically slow
to instantiate, again because of their size. Also, an operating system typically takes some
time to start up. Note, however, that this is not universally true, since lightweight VMs such
as those built by Boxfuse exist.
-----------------When you use the Service Instance per Container pattern, each service instance runs in
its own container. Containers are a virtualization mechanism at the operating system level.
A container consists of one or more processes running in a sandbox. From the perspective
of the processes, they have their own port namespace and root filesystem. You can limit
a container’s memory and CPU resources. Some container implementations also have
I/O rate limiting. Examples of container technologies include Docker and Solaris Zones.There are some drawbacks to using containers. While container infrastructure is rapidly
maturing, it is not as mature as the infrastructure for VMs. Also, containers are not as
secure as VMs, since the containers share the kernel of the host OS with one another.
Another drawback of containers is that you are responsible for the undifferentiated
heavy lifting of administering the container images. Also, unless you are using a hosted
container solution such as Google Container Engine or Amazon EC2 Container Service
(ECS), then you must administer the container infrastructure and possibly the VM
infrastructure that it runs on.
Also, containers are often deployed on an infrastructure that has per-VM pricing.
Consequently, as described earlier, you will likely incur the extra cost of overprovisioning
VMs in order to handle spikes in load.
Interestingly, the distinction between containers and VMs is likely to blur. As mentioned
earlier, Boxfuse VMs are fast to build and start. The Clear Containers project aims to create
lightweight VMs. There is also growing interest in unikernels. Docker, Inc acquired Unikernel
Systems in early 2016"