Hi, I am one of the contributors on this project, and happy to answer any questions... LCFS will also be supporting the snapshot driver discussed here - https://github.com/docker/containerd/pull/484.
Currently, the install experience is not the greatest... We rely on the Docker v2 plugin interface and that is still in beta. We are working with the Docker team to help us smooth out some of these rough edges.
LCFS will also support other container formats and any help from the community is much appreciated.
LCFS is not yet being used in production as far as I know
We started building this because there are a lot of issues running containers in production, specifically around image space and inode management and also with page cash usage.
This file system was specifically designed to address memory and storage management of container images
Really nice to see the new file systems addressing this issue, but, as many including me hurt by AUFS, I am being cautious. Do you think it is battle tested enough? As it is different than other merging ones, it is a little more dangerous than them as well since it works on block level? Not trying to be negative, I really liked it, and I am not even happy about even a docker load command performance over my overlay2, and will defintely be trying LCFS.
It is a mini-file system, working directly on top of a block device. Having something else in between is not a good idea. Much of the data handled by docker storage driver is temporary and does not even have to hit disk before thrown away.
This project is currently in experimental mode. We would appreciate any feedback you may have.
How many more file systems are we going to see before we realize that the file system is the wrong layer of abstraction to be solving the deduplication problem?
I think the filesystem is a fine place to do it, I just wish more filesystems would give us the option to do deduplication offline.
ZFS's dedup uses grotesque amounts of RAM since it insists on holding the dedup table in it and only doing dedup in realtime.
btrfs however allows you to scan the filesystem and do dedup of existing data later (even while it is mounted), using no RAM at all. This is one of a couple of places where I think btrfs is actually becoming a better-designed filesystem than ZFS.
BTRFS has so many drawbacks using it as storage driver for docker. See the bottom of the page https://docs.docker.com/engine/userguide/storagedriver/btrfs....
Primary drawback being each container creates unique copy of the data in kernel page cache and taking away system resources from applications.
Not using image layers to begin with. You can't reasonably do that with Docker or other software that isn't aware of the dependency graphs of the software that it runs. Docker just runs some arbitrary commands and maintains an opaque set of disk images. Seems to be the best you can do there. However, if one were to use software that actually understood the full dependency graph, you wouldn't need disk images at all and you'd be able to share storage without involving special file systems. In GNU Guix, a functional package manager, we can make containers for arbitary software without any duplication because we know the full dependency graph of the application. Applications may share sub-graphs so they are only on disk once. If two programs depend on libpng, libpng and its dependencies are only on disk in one place. With a functional package management system in place, containers become a relatively simple matter of creating namespaces and bind mounting the dependencies. No image layering, no special file systems, just simple bind mounts.
Easy on the surface, but very limiting and frustrating in practice.
I think all the energy spent around designing image layer file system after image layer file system is good evidence that the Docker approach isn't as easy as it may seem.
Interesting thought, however I think that the existing graph driver file systems are not actually an "image layer file system"... instead they are a general purpose file systems that are being used to store images.
For example, what one wants with launching multiple instances of an image is to be able to clone the image. Today, to accomplish that, file system snapshots are used to simulate this feature. And that is where a lot of the problems start happening. LCFS does things purpose built for these use cases.
I would say image layer file system is not that hard to solve if you approach the problem correctly. It looks like all prior attempts tried to use general purpose solutions and in some cases a combination of those (for example, overlay on top of ext4) for dealing with a much smaller problem and ran into unnecessary complications. A lot of the complexities in a general purpose solution is unwarranted for a image layering file system.
We looked at the requirements of a docker storage driver and built a solution from scratch, just to address those efficiently and nothing else.
There are many problems a storage driver for docker need to solve. We are not replacing docker here, just providing a better solution for the storage driver (API of which is defined by docker) part of it. Solutions in use today are half baked and have too many problems to deal with.
Docker is already doing a good job of de-duplication by identifying shared data between applications and keeping a unique copy of shared data on disk. But many of the existing storage drivers today, would create multiple copies of such shared data in memory when many applications (containers) consume such shared data. Applications are running on top of file systems and each need a separate instance of the file system and Linux kernel does not know if all those file systems are sharing same data underneath. Each application also require a unique view of the file system and they may choose to modify their file system (thus their shadow copy of shared data) and such changes should be hidden from other applications (containers). That is where cloning technologies come into play. And there are many other things a docker storage driver need to solve. Rather than focusing on one aspect of the whole problem, it would be better to look at the whole picture and see if there are any solutions out there solving all those problems correctly and efficiently for a docker storage driver.
I am the OP and I kept the original title, but it does not look like a "file system" to me, it looks more like a key/value store optimized for storing container image layers.
Also curious to know if anyone is using it in production and what their experiences are.
This is not a general purpose file system, but something purpose built for serving as a docker storage driver. LCFS outperforms existing solutions and does not have any correctness issues.
It is an experimental release at this point. We would like to receive feedback from the community and make it successful for everybody. Our tests so far look very promising.
Just to add to what jjobi says and agree with point here, we have to battle test this, and the best way to get there is to start in the open. So this is the start :).
The fundamental thing here is that (a) it's taking a specific approach [with layers], (b) we're in it for the long-haul, and (c) we want this to be in the open. We’ll update as the battle-testing, production progress continues. So 100% agree with the question/point.
I figure this will probably be shit on here, but have you ever played with Windows Server Deduplication? We use it all over our corporate Windows environment, with a distributed file system, and it averages 48% globally. It doesn't chew up RAM, integrates with shadow copy services, behaves itself while it runs in the background, and I honestly don't see much if any performance hit reading/writing. Now we're not talking petabytes of data, but each of probably a hundred file servers worldwide has 10-20 terabytes worth stored.
It's literally set it, and forget it. While you gain 50% of your storage back.
This is a custom built solution for docker storage driver. A de-duplication server cannot be docker storage driver, as there are more things involved in a docker storage driver like layer management, rapid cloning and deletion of those, efficient diffing between layers and stuff like that. The existing solutions are AUFS, Overlay, devicemapper, btrfs and zfs, and a comparison should be made against those.
We did not solve a typical de-duplication problem with LCFS. If you write two copies of the same data to LCFS, there will be two copies of data stored. We may provide such de-duplication feature at some point in future.
Docker is already doing de-duplication by keeping shared data in image layers and expect the storage driver (graphdriver) to manage shared data between many container application efficiently without instantiating multiple copies of shared data in memory and disk. That problem can be solved by well known file system snapshot and cloning technologies and that is what LCFS is doing, and a lot more efficiently than any existing storage drivers out there.
The focus here is not deduplication. However, if you want to think of it in those terms, it is sharing data at the 'layer' granularity (not block, not file, but a bunch of files) and that's co-ordinated by Docker. The main property of this filesystem is that it is layer aware; it clones layers efficiently and optimizes common workflows in the docker ecosystem.
Here's a quick one if your filesystem supports hard links:
#!/bin/ksh
typeset -A hashes
find . -type f -exec shasum -a 512 {} \; |
while read hash filename; do
if [[ -z ${hashes[$hash]} ]]; then
hashes[$hash]="$filename"
else
echo ln -f "'${hashes[$hash]}'" "'$filename'"
fi
done
Good answer, but unless you mark the files read-only/immutable, this ought to have big red flags all over it. Userland just can't do this safely in the general case.
This was done using fuse to make it portable across different distros. We have not seen any major issues testing it as a docker storage driver, compared to the graphdrivers in use today.
36 comments
[ 2.6 ms ] story [ 61.7 ms ] threadCurrently, the install experience is not the greatest... We rely on the Docker v2 plugin interface and that is still in beta. We are working with the Docker team to help us smooth out some of these rough edges.
LCFS will also support other container formats and any help from the community is much appreciated.
Is anyone using LCFS in production? Why did you get started building it?
We started building this because there are a lot of issues running containers in production, specifically around image space and inode management and also with page cash usage.
This file system was specifically designed to address memory and storage management of container images
This project is currently in experimental mode. We would appreciate any feedback you may have.
ZFS's dedup uses grotesque amounts of RAM since it insists on holding the dedup table in it and only doing dedup in realtime.
btrfs however allows you to scan the filesystem and do dedup of existing data later (even while it is mounted), using no RAM at all. This is one of a couple of places where I think btrfs is actually becoming a better-designed filesystem than ZFS.
I think all the energy spent around designing image layer file system after image layer file system is good evidence that the Docker approach isn't as easy as it may seem.
For example, what one wants with launching multiple instances of an image is to be able to clone the image. Today, to accomplish that, file system snapshots are used to simulate this feature. And that is where a lot of the problems start happening. LCFS does things purpose built for these use cases.
We looked at the requirements of a docker storage driver and built a solution from scratch, just to address those efficiently and nothing else.
Docker is already doing a good job of de-duplication by identifying shared data between applications and keeping a unique copy of shared data on disk. But many of the existing storage drivers today, would create multiple copies of such shared data in memory when many applications (containers) consume such shared data. Applications are running on top of file systems and each need a separate instance of the file system and Linux kernel does not know if all those file systems are sharing same data underneath. Each application also require a unique view of the file system and they may choose to modify their file system (thus their shadow copy of shared data) and such changes should be hidden from other applications (containers). That is where cloning technologies come into play. And there are many other things a docker storage driver need to solve. Rather than focusing on one aspect of the whole problem, it would be better to look at the whole picture and see if there are any solutions out there solving all those problems correctly and efficiently for a docker storage driver.
Also curious to know if anyone is using it in production and what their experiences are.
It is an experimental release at this point. We would like to receive feedback from the community and make it successful for everybody. Our tests so far look very promising.
The fundamental thing here is that (a) it's taking a specific approach [with layers], (b) we're in it for the long-haul, and (c) we want this to be in the open. We’ll update as the battle-testing, production progress continues. So 100% agree with the question/point.
It's literally set it, and forget it. While you gain 50% of your storage back.
Docker is already doing de-duplication by keeping shared data in image layers and expect the storage driver (graphdriver) to manage shared data between many container application efficiently without instantiating multiple copies of shared data in memory and disk. That problem can be solved by well known file system snapshot and cloning technologies and that is what LCFS is doing, and a lot more efficiently than any existing storage drivers out there.
see also jdupes fork of fdupes
https://github.com/jbruchon/jdupes
https://github.com/adrianlopezroche/fdupes