A 32MB docker image sync service built for persist data on clusters
+------+ +----------+
| NFS |----| Your App |
+------+ +----------+
Imagine a NFS server, but made for cluster and containers.
Ready for production! Until now, its the only BTSync docker imaged that is harassed with a test suite!
At findhit.com, we have to share data between our cluster nodes. After testing out some solutions such as: cloud provider's storage ones, some well known cluster-targeted file systems and among other less valuable solutions to our architecture (such as NAS sharing), we've got always the same opinion. None of them could be fast, scalable and easy as plug-n-play.
As so, we looked for p2p syncing solutions. BTSync was our first choice, but it
lacks some important features such as cluster-based configuration storages
(etcd
for example).
I took a time to plan how I would structure configurations on a cluster, but it always ends on configurations per node, the only difference with current BTSync approach would be configuration sharing, and thats not useful.
So, instead of creating an image that relied on confd
(which is great btw),
I've decided to work on btsync cli before going to sleep.
A cli will allow us to place a btsync service per cluster node (making use out of
the ephemeral disk they mostly have) and control that service via docker exec
.
NOTE: Examples presented above will rely on a CoreOS environment.
- Submitting a btsync global service (with fleet) will allow us to share one
path (my choice was
/mnt/resource
, which is an ephemeral storage on CoreOS on MS Azure) - Services could easily ensure or remove a folder by running:
docker exec btsync ctl add gitlab
onExecStartPre
docker exec btsync ctl del gitlab
onExecStopPost
- Storage could be mounted by sharing
/data
volume ofbtsync
container, but I really advise you to don't do so./data
could have other containers data and that fact creates a big SECURITY WARNING ON MY HEAD!!! Instead we could use a path getter such as:docker run -v $(docker exec btsync ctl path gitlab):/home/gitlab/data gitlab:latest
There are several ways to configure this service. They were created to fit on your services structure.
Note: Although they don't mention how to bind data folder into a disk, you could
achieve by mounting it as a volume: -v /path/to/some/host/disk:/data
docker run \
--name btsync-nfs \
bootstrap SECRET_HERE some-third-party-image
# Now you just have to make sure your image is able to mount it
# In case the image you pretend doesn't do that, you could work around it by
# replacing entrypoint and command. (Advanced users)
docker run \
--name some-third-party-image \
-e CONTAINER_DATA_PATH=/container/data/path \
--entrypoint /bin/sh \
some-third-party-image: latest \
-s -c "mount -t nfs4 btsync-nfs:/some-third-party-image /container/data/path && /path/to/original/entrypoint and/or command;"
Shares are exposed on NFS root system, meaning that if you create a namespace
called yolo
(with ctl add yolo
), you nfs mount command should look like:
mount -t nfs4 btsync.link.or.ip:/yolo /path/to/mount/on
docker run \
--name btsync \
cusspvz/btsync:latest
Now each service should add his folder data before mounting it:
docker exec btsync ctl add --secret="SECRET_HERE" my-app-name
docker run --name="my-app-name" -v /path/to/some/host/disk/my-app-name:/container/data/path my-app-name
# Removing it from global service
docker exec btsync ctl del my-app-name
docker run \
--name my-app-name-data \
cusspvz/btsync:latest \
bootstrap SECRET_HERE my-app-name
docker run \
--volumes-from my-app-name-data \
-e DATA_DIR=/data/my-app-name \
my-app-name
BTSync WebGUI is available by default at port 8888.
You could set up an internal load-balancer just to see whats happening under the hood. But please, avoid to give public access to it, otherwise MR Robot will nuke all your data, including you chinese servers backup with a Raspberry Pi...
Default credentials: User: admin Pass: admin
docker exec btsync ctl [commands]
Adds a folder for a determined namespace
docker exec btsync ctl add --secret="e3hryu35qegqery4w5y164u5u" "gitlab"
NOTE: Secret provided on example isn't a valid one, it was generated by a random pseudo-geek key typing. I'm on a coffee, now people here think I write fast.
Deletes folder related with that namespace
docker exec btsync ctl del "gitlab"
Returns host's or container's path to created namespace. By default, scope is host.
docker exec btsync ctl path "gitlab" # /mnt/resources/sync/gitlab
Exits with 0 (has) or 1 (hasn't) indicating if namespace exists [or not]
if docker exec btsync ctl has "gitlab"; then
echo "yeah, we already have that namespace"
fi
Prints a spaced-separated list of namespaces
docker exec btsync ctl add gitlab
docker exec btsync ctl add star-trek
docker exec btsync ctl list # gitlab star-trek
Defaults to: /mnt/resources
Defaults to: /data
Defaults to: /data/btsync.conf
Defaults to: 10
Defaults to: /var/run/btsync.pid
Defaults to: "btsync:ctl"
Defaults to: btysnc
Defaults to: 1000
Defaults to: 1000
make run
make run-bash
make build
make test