Why VRRP would be an awesome addition to Docker?

Docker 1.7 is going to ship with libnetwork

This opens to door to a wide variety of network configurations involving Docker.

I asked on Twitter if there are going to be any plans to add VRRP and got the reply:

The reply clearly does not fit in a tweet, so I wanted to demonstrate how Docker could work with built-in VRRP.

Use case: Redis master - slave with automatic failover.

Consider we have 2 machine running Docker on a shared network.

machine1# docker run redis/master -p 6379: --vrrp-ip --vrrp-publish 6379 --vrrp-router-id 1 --vrrp-weight 2
machine2# docker run redis/master -p 6379: --vrrp-ip --vrrp-publish 6379 --vrrp-router-id 1 -vrrp-weight 1

Explaining the param:

vrrp-ip : the ip address to publish
vrrp-publish: same as --publish but for the vrrp interface
vrrp-router-id : required by vrrp protocol for election process
vrrp-weight : weight of the “request” for ip, highest weight wins.

Then … immediately on the network port 6379 would point to a highly available redis.

If machine1 dies (or container is stopped), machine2 takes over.

This kind of setup is doable today using keepalived, or vrrpd. But having Docker aware of this protocol would significantly simplify deployment.

It could be used for highly available haproxy instances, pg instances and more.

Would it perhaps also be possible to assign a virtual IP to a container inside the container network?

I’m currently struggling with Redis, I can set up replication but then I’m facing the issue that if I reference the redis cluster via Docker service name, I’ll get connected to a random one (either master or replica) and the replica isn’t replicating information to the master, which means that if one of my containers connects to the replica and the rest would connect to the master, I’d be left with a unidirectional communication for the one container.

Not sure if this was at all the goal of this post but for me it sounds like it and I’d love to see this feature added.
Alternatively you may present me another solution to this problem but I’ve been searching for over 24 hours now and wasn’t able to find anything that would suit my needs.

samsaffron was writing about redis instances running on different machines. Do you run your containers in swarm mode?

Since Redis 2.6, replicas support a read-only mode that is enabled by default.

You may wonder why it is possible to revert the read-only setting and have replica instances that can be targeted by write operations. The answer is that writable replicas exist only for historical reasons. Using writable replicas can result in inconsistency between the master and the replica

So indeed, you should not write to a replica and it should not even be allow to write to it. I haven’t used Redis reently, but if I remember correctly I had to configure multiple redis instance on the client side and not using only one hostname to point to multiple IP addresses. Then the client could decide which one was the master. Probably using the INFO command but I am not sure.

There is an other interesting statement in the documentation:

To make Docker compatible with Redis Cluster, you need to use Docker’s host networking mode. Please see the --net=host option in the Docker documentation for more information.

So according to this statement you should use the host network and not the Docker network.

In a Kubernetes cluster there are “services” to have a static IP which you can refer to. However, you can assign an IP address to a Docker container this way:

docker run -d --name redis-1 --network redisnet --ip <ip_address_on_redisnet>

This way you could set the IP addresses. Since you mentioned

Then I suppose you just scaled a docker compose service up and used the service name insted of the container name like projectname-redis-1 and projectname-redis-2. Am I right?

Do you run your containers in swarm mode?

I could be running the Redis instances in swarm mode but the clients are standalone containers. I don’t think it makes a difference though for what I’ll explain further down.

Then I suppose you just scaled a docker compose service up and used the service name insted of the container name like projectname-redis-1 and projectname-redis-2. Am I right?

I’m afraid not. I’ll try and explain again my setup, what I’d like to achieve and where the issues are.

  1. Let’s say I have 3 standalone client containers that all want to sync some data through Redis.
  2. I now set up 2 masters with 1 replica each, and let’s also say I set up the replicas in read-only mode as you mentioned. The masters get the IP and and the replicas get and They are all set up under the service name “redis1”
  3. Now I tell my client container to connect to redis1 which has two issues already.
    Issue #1: It could still pick a replica cause DNS would still resolve redis1 to all 4 IP addresses and pick one at random. It might then try and reconnect but this behavior shouldn’t even occur in my opinion.
    Issue #2: If client container 1 and 2 picked and container 3 picked, they still wouldn’t be able to sync up the data cause they are connected to different servers that do not replicate data to each other!

Issue #1 could be resolved by giving the masters the service name redis1master and the replicas would be redis1replica and I set up my client containers to connect to redis1master but Issue #2 is still unresolved in this scenario.

Docker network VRRP would solve this issue by having a virtual IP (= VIP).
Let’s say we pick as a VIP and assign it to both master containers. Now I’d be able to tell all 3 client containers to connect to and they would always connect to the same master with replica (though for my use case I don’t even need replicas and only masters as it’s literal messages that are being redistributed but that might be besides the point here).

Hope that helped clear things up, otherwise you may ask me some more questions :smiley:

Thank you for your description. I try to write a short reply, because this topic was about a feature request and I would not turn it into a Redis configuration discussion more than I have already done. I would also not vote against a feature like this, but it doesn’t exist. You can try to open a new feature request in the roadmap. I haven’t used Redis for years know, so I would probably have to try it again to fully understand you.

I am starting to feel that you actually run containers on multiple nodes. Otherwise I don’t know how you could use the same service name without Docker Compose. Unless you have multiple Docker Compose project on the same machine.

If you would like to find a solution to issue 2 even without VRRP, I recommend you to create a new topic with “Redis” in the title so people who are more familiar with Redis would immediately see and I could ask more questions too :slight_smile:

1 Like