Service discovery and daemons with docker - ruby-on-rails

Here are some questions I have about Docker:
Given the way Docker handles Daemons and Links betweens services (not using daemons)
1- How process monitoring, daemons and application chains will work (ie: upstart/bluepill/unicorn) if you can run daemons and bluepill restarts process by itself ?
2- How will it work with load balancing with a high level proxy when it comes to find ip address of the containers to balance to if you want to stick to upstart/bluepill/unicorn model ?
3- Which is the recommended software for service discovery on the top of docker for example to perform a rails deploy?

1- AFAIK, there is no problem running bluepill (or some other process monitor like supervisor or monit) in a docker container. I often used this kind of tool to run more than one service in a container.
2- For load balancing containers, you can either use a load balancer that you can configure dynamically (for http balancing, hipache is a good candidate) or have some scripts that dynamically update configuration of a standard load balancer and reloads it (I did it many times with nginx, it should work with other solutions)
3- There are some tools in the docker ecosystem for service discovery. You can have a look at Serf (http://www.serfdom.io/) and etcd (https://github.com/coreos/etcd). For the deploy part, I would recommend you to use the ONBUILD instruction in Dockerfile to inject application code and create immutable containers.

Related

Does a simple monolith application need kubernetes to manage

I'm very new to the infrastructure so I built a simple monolith application and I use docker for building a container and deploy it on my linux server. My question is, do I need to install kubernetes for a single container and if no how can I scale or do the load balancing.
"... do I need to install kubernetes for a single container" - No, it is not mandatory. One can use docker to manage applications. Kubernetes is a platform that can be used to orchestrate containerized applications. It offers tools and concepts like autoscaling based on load, isolation through namespaces, network access management through services and ingresses, and much more. But Kubernetes is not the only platform for orchestration. There are others, for example OpenShift, docker swarm, rancher. All those are optional platforms with additional tooling and concepts that can be used if necessary.
"how can I scale or do the load balancing." - We can, for example, define the replicas through the replicas variable in a docker-compose file. All containers defined under a service are accessed through this service's name. How exactly the balancing is done can also be configured through the endpoint_mode configuration. If we need even more control, we can deploy a separate load balancer, e.g. nginx. A possible configuration is described in this medium article.
For future posts, please limit yourself to one question per post.

Best approach to create containers

I am developing an application with nodejs, mysql that has the following dependencies
Nginx (for reverse proxying the db and the nodejs server)
ghostscripts (dependent os is ubuntu)
pdftk (dependent os is ubuntu)
I would like to know what would be the best approach if I want to use docker containers to pack my application.
Should I create one Nginx container, one nodejs container and one MySQL and make them talk to each other? I know this is a better approach since its scalable, but in this case how and where should I install ghostscript and pdftk? (the nodejs application makes use of Ghostscript and pdftk for pdf files)
or
should I create one ubuntu docker container and install everything (viz. Nginx, pdftk, Ghostscript, mysql) in it?
Splitting an application up into separate containers requires a well defined API that support calls over the network (usually HTTP or some other application protocol on the TCP stack).
As both ghostscripts and pdftk are commandline tools invoked using a CLI you cannot call them from another container out of the box, you would need to develop some external facing API for that.
When setting the boundaries of your containers, think in terms of domains. The container becomes a the smallest unit that you will deploy and scale. That unit should be self contained and have a well defined, single purpose.
It is not clear from your description exactly what role nginx plays, but assuming that is some kind of client facing webserver or proxy, 3 containers makes sense in your case
NodeJs + PDFTK + Ghostscripts (The application)
Nginx (The webserver/proxy)
MySQL (The database)
The NodeJS application has all its application dependencies inside, but are more loosely coupled to Nginx and MySQL to whom it can communicate over the network.
You should create separate containers for each application, because this allows you to achieve:
Independent deploy.
Independent scaling.
Independent development.
Isolation and security.
For convenience, you can use docker-compose, which allows you to launch configure and launch multiple docker containers with a single command.
I would recommend that you deploy the database not in a Docker container in production because the database stores the state, it is also unreliable, and this increases the complexity of support.

Does it make sense to run Kubernetes on a single server?

I'm using Docker I have implemented a system to deploy environments (on a single server) based on Git branches using Traefik (*.dev.domain.com) and Docker Compose templates.
I like Kubernetes and I've never switched to it since I'm limited to one single server for my infrastructure. I've only used it using local installations (Docker for Windows).
So, my question is: does it make sense to run a Kubernetes "cluster" (master and nodes) on a single server to orchestrate and route containers (in place of Traefik/Rancher/Docker Compose)?
This use is for development and staging only for the moment, so high availability is not a prerequisite.
Thanks.
If it is not a production environment, it doesn't matter how many nodes you are using. So yes, it should be just fine in this case. But make sure all the k8s features you will need in production are available in test/dev, to keep things similar and portable.
AFAIU,
I do not see a requirement for kubernetes unless we are doing below at least for single host using native docker run or docker-compose or docker engine swarm mode -
Make sure there are enough(>=2) replicas of your app in a single server and you are balancing the load across those apps docker containers.
If you want to go bit advanced, we should be able to scale up & down dynamically (docker swarm mode supports this out of the box else use jwilder nginx proxy).
Your deployment should not cause a downtime. Make sure a single container is always healthy at any instant of time while deploying.
Container should auto heal(restart automatically) in case your HTTP or TCP health check fails.
Doing all of the above will certainly put you in a better place but single host is still a single source of failure which you got to deal with at regular intervals.
Preferred : if possible try to start with docker engine swarm mode or kubernetes single master or minikube. This will automatically take care of all the above scenarios out of the box and will also allow you to further scale up anytime by adding more nodes without changing much in your YML files for docker swarm or kubernetes.
Ref -
https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/
https://docs.docker.com/engine/swarm/
I would use single host k8s only if I managed clusters with the same project that I would like to deploy to the said host. This enables you to reuse manifests and all the automation you've created for your clusters.
Have I had single host environments only, I would probably stick to docker-compose.
If you're looking to try it out your easiest options are probably minikube (easy to run single-node cluster locally but without some features) or using one of the free trial accounts for a managed Kubernetes service from one of the big cloud providers (fully-featured and multi-node but limited use before you have to pay).

Container delivery on amazon ecs

I’m using Amazon ECS to auto deploy my containers on uat/production.
What is the best way to do that?
I have a REST api with a several front-end clients
Should I package my api container with nginx in the same container?
And do the same thing with the others front end clients.
Or I have to write a big task definition to bring together all my containers(db, nginx, php, api, clients) :(, but that's mean that I should redeploy all my infrastructure at each push uat/prod
I'm very confusing.
I would avoid including too much in a single container. Try and distill your containers down to one process doing one thing. If all you're doing is serving up a REST API for consumption by your front end, just put the essential pieces in for that and no more.
In my experience you also want your ECS tasks to be able to handle failure gracefully and restart, and the more complicated your containers are the harder this is to get right.
Depending on your requirements I would look into using ELB instead of nginx, you can have your ECS cluster point at an ELB and not have to deal with that piece at all.
Do not use ECS - it's too crude. I was using it as a platform for our staging/production environments and had odd problems during deployments - sometimes it worked well, sometimes - not (with the same Docker images). ECS provides not clear model of container deployment and maintenance.
There is another good, stable and predictive option - Docker Cloud service. It's new tool (a.k.a. Tutum) that was acquired by Docker. I switched the CI/CD to use it and we're happy with it.
Bind Amazon user credentials to Docker Cloud account. Docker Cloud uses AWS (or other provider) API for creating appropriate computer instances.
Create Node. Select Amazon EC2 instance type and parameters of storage, security group and so on. New instance will contain installed docker software and managing container that handles messages from Docker Cloud (deploy, destroy and others).
Create Stackfile, see https://docs.docker.com/docker-cloud/apps/stack-yaml-reference/. Stackfile is a definition of container group you required. You can define different scaling/distribution models for your containers using specific Stackfile options like deployment strategy, see https://docs.docker.com/docker-cloud/apps/stack-yaml-reference/#deployment-strategy-1.
Define ELB configurations in AWS for your new instances.
P.S. I'm not a member of Docker team and I like other AWS services :).
Here is my two cents on the topic, the question is not really related to ecs, it applies to any body deploying their apps on docker.
I would suggest separating the containers, one for nginx and one for API.
if they need to be co-located on the same instance, on ECS you can define them as part of the same task and on kubernetes you can make them part of same pod.
Define a docker link between the nginx and the api container. This will allow the nginx process to talk to api container without the api container exposing its ports to the host.
One advantage of using the container running platforms such as kubernetes and ecs is that they ensure each of the container run all the time and dynamically restart if one of the processes/containers go down.
Separating the containers will allow these platforms to monitor both the processes separately. When you combine the two into one container the docker container can only run with one of the processes in foreground, so you will loose the advantage of auto-healing for one of the processes.
Also moving from nginx to ELB is not a straightforward solution, you may have redirections and other things configured on the nginx, which are not available on ELB(As of date).
If you also need the ELB, there is no harm in forwarding the requests from the ELB to the nginx port.

HaProxy for service discovery on a marathon mesos docker linked containers

Please this is not asked anywhere I have checked. Here is what I have done. I am able to deploy single instance of mesos, marathon and docker. Moving next step ahead I want to have 2 mesos slave(docker containers) linked to each other. Just using docker the same can be achieved by using the docker link feature. But while using the orchestration(mesos) and scheduler(marathon)it seems u need to use service discovery.
My setup up is simple and runnning on a single host. So I will have 2 docker containers one running a simple pub/sub and one running rabbitmq. How can I use HA PRoxy in this setup. I have seen some documents provided by mesosphere
http://mesosphere.com/docs/getting-started/service-discovery/ but it is not clear how to go about it.
The canonical approach for service discovery with Mesos + Marathon + Docker is currently what is described in the document you linked.
I'm assuming you're able to get the two applications running in Marathon already.
Typically what happens is:
1) Configure your application definition to include the ports that your application requires.
2) You set up the provided haproxy-marathon-bridge script to run periodically using a utility like cron. This script scrapes Marathon's API to figure out what host and port the application instances are running on and what the known "friendly" port is.
In the example in the service discovery article, the first application has friendly ports of 80 and 443, whilst the second has a friendly port of 8081.
The script then generates a haproxy.cfg configuration that has rules mapping localhost:friendly_port to actual_host:actual_port.
3) Configure your applications to look for each other on localhost:friendly_port. HAProxy will route connections appropriately.
Hope this helps your understanding!
I created a haproxy service discovery docker container that you can run in mesos. It's not production ready but I am using it in my development environment doing exactly what you're trying to do. The reason I prefer this over what comes with marathon is I haven't found a good way to do complicated haproxy configurations with haproxy-marathon-bridge. With spiderweb you can create a template for the haproxy configuration which enables you to do things such as acl routing etc. It doesn't support health checks yet which is something that will need to be done before its production ready. You can see the project here https://github.com/SBRDevelopment/spiderweb.
We have combined Mesos and Marathon with consul and registartor,
so in the end you have haproxy configuration auto-generated with consul-template.
try https://github.com/eBayClassifiedsGroup/PanteraS
All in one container.
With Mesos-DNS you can also do the following:
Setup mesos-dns as in this guide: http://programmableinfrastructure.com/guides/service-discovery/mesos-dns-haproxy-marathon/ (you can skip HAProxy steps they are not required)
When you start your docker containers make sure that they have "namespace %slave_ip_with_mesos_dns%" (replace string with IP address) in their /etc/resolv.conf files.
if lets say name of an app is "peek" it should be reachable from other applications at peek.marathon.mesos

Resources