I work for a company here in Gothemburg (Sweden) hired as a consultant.
This has given me a lot of opportunities to use Docker and learn its pits and falls.
Multihost:
One of the bigger problems have been multihost applications. To have containers on different hosts that talk to eachother.One company that set out to solve this problem is WeaveWorks (http://weave.works/).
But the new experimental branch of Docker 1.7 has the new libnetwork so you can do multihost.
But as I said, it is in the experimental branch and some of it's functions isn't mature enough.
This is one of the reasons that I've been looking at Weave. Another is that the experimental branch of Docker also have plugin support. And Weave is one of the first to actually create a network plugin (many big companies are working on this).
So I can use Weave as I do now or I can use it later as a plugin.
Components:
Weave Binary that pulls Weave, WeaveExec, WeaveDNS containers (they run in containers).
So what are some pros with Weave:
- Mulicast (or Unicast) support
- The containers have there own IP so they are more like traditional containers
- Containers can have Hostnames that just works with WeaveDNS
- Password for your Weave network
- NaCl crypt
- Uses "Vanilla" Docker, so no real changes to your containers
- The network hasn't one point failure, start a network on one host, connect another to that host, connect a third to the second and they all find eachother and registers eachothers as peers.
Some cons:
- Bad documentation (when is crypt used and more advanced examples). The only documentation on how to use it is the simple guides, but no real guides for configuration.
- Not apparent what the Weave Binary does
I'm probably gonna have a session on the next Docker Meetup Gothemburg (Aug 2015) and maybe in
JavaForum Gothemburg.
So for these sessions I have prepared 2 demos. One with minimum code and one with more complete code (still very little code).
Demo
So the demo is 2 services:
Weave Producer:
The Producer is a Spring Boot Rest service that retrieves a Environment Variable and sends it. It listens on the url: host:8080/rest/hostname
This is packed as a standalone jar. I put it in a Docker container (extended Image from OpenJRE).
Weave Consumer:
The Consumer is a Spring Boot Rest service that retrieves a value from the producer and then adds some text. The result is meant to be which Consumer and which Producer is involved.
This is packed as a standalone jar. I put it in a Docker container (extended Image from OpenJRE).
Here comes the fun!
Since the Consumer doesn't know the exakt host it will talk to, it talks to a DNS-name.
weave-service.weave.local
weave-service is my name for the service and weave.local is the mandatory part. This part it takes from a properties file if I want to change it.
So a hostname might not seem like a magical thing, but the fun part is that you can start several containers of the same Image with the same hostname!
WeaveDNS understands that it is the same service. I think (not sure) that it will loadbalance between them.
But what I do now is that if you have 1 Consumer and 2 Producers and the Producer that the Consumer is using for its service goes down (docker stop or unavailable) then (since I coded a retry function) it will automagically start using the other one (The DNS understands that it has gone down and will remove it from the DNS-list).
Weave'ing It
So the Demo is actually a Vagrantfile that starts 3 VM's running Ubuntu with Docker.
This takes up around 50-60 GB (sorry!).
The Github-page gives instructions on how to run them and build the Docker Images on the VM's.
All the code is included and I use Gradle Wrapper so you don't need to download Gradle or Maven for building the services. (You only need Java 8, the services are built on you host, not the VM's).
One VM will have a consumer and the other two will have producers. The Environment Variable that the Producer uses is set when you create the container (the name Producer 1 or Producer 2).
Conclusion:
A small and fun way to try out microservices with high availability using Docker and Weave.
Nothing in the Java-code does anything to do with the high availability part (just the retry but you want that even if you only use one host to talk to).
So for Weave to work you only need to use hostname, you don't need any other change.
Sorry for any misspelled things or typos.
Here is the Links:
Minimal Code: https://github.com/Khazrak/WeaveDemo
Better Code with fast Retry: https://github.com/Khazrak/WeaveDemoEX
Feedback:
I would love some feedback on these or some idés for improvments.
Happy Testing!