Playing with Locks in Consul
Posted on September 13, 2015
Consul is a great piece of software, and I love building HA services with it at the heart of the distributed system. One of Consul’s features is a distributed locking mechanism, and I wanted to learn a little more about it. I also wanted to experiment with simple methods for running a one-time action, or a single instance of a service in a distributed system - potential solutions to the famous challenge: “who guards the guards?”
import sys
from time import sleep
import consul
import consul_lock
from docker import Client
'''
This is a PoC which uses consul's locking mechanism to ensure only
one instance of the named docker container is running. Requires:
a) pip install python-consul consul-lock
b) docker create --name my_container my/app
try it: python only-one.py container_name token
'''
= 3
pause = sys.argv[1]
container_name = sys.argv[2]
token = Client(base_url='unix://var/run/docker.sock')
cli
= consul.Consul(token=token)
consul_client = consul_client
consul_lock.defaults.consul_client
print 'starting up!'
while True:
= consul_lock.EphemeralLock(('only-one/%s' % container_name),
ephemeral_lock =3600,
lock_timeout_seconds=500)
acquire_timeout_mstry:
print 'acquiring distributed lock in consul..'
= ephemeral_lock.acquire(fail_hard=False)
was_acquired if was_acquired:
# do dangerous stuff here
print 'lock acquired!'
print ('starting container %s' % container_name)
= cli.start(container=container_name)
response print(response)
print 'will now wait/block until the container exits..'
=container_name)
cli.wait(containerelse:
print 'someone else has the lock :\ try again later'
finally:
print 'be sure there is no lock in consul..'
ephemeral_lock.release()print ('sleeping for %d seconds' % pause)
sleep(pause)
The original post can be seen in this gist.