Containers are moving targets in multiple ways. With multiple tools, frameworks, implementations, and use cases to accomplish any task, it can be a fast-moving chaotic container world, which is a natural consequence of being young and popular.
The good news is that all of this creative incubation is hugely productive, and because it’s all open source everyone gets to share the benefits of all of this fabulous creativity. The bad news is that it’s a giant energized cat herd. How do we know what direction to take? Must we plan for the work we do today to be obsolete in a few months? And, what about portability?
I’d like to provide a few insights into the future of containers, and the direction we can expect the state of the art technology to take.
The evolution of standards for containers
Container standards has become more of a formal conversation, and a political one. But the progress on it presently is a lot more standardized, and governed, and has some formal rules around interactions between all the different people involved. Whereas over the last few years, or at least three years’ prior, the only standards were any given tools on configuration files, or a way of doing it.
Systemd had its own way of doing it for nspawn, and Linux Containers (LXC) had its own way of doing it for LXC. They had their own interactions with the tool, but when it got down to the question a lot of people were asking (“How do I get started with a container?”), you just had to make it yourself. There wasn’t this notion of distributing images at all. You had to just bolt that on and figure out the work for yourself.
Then Docker came along and got people’s attention. One of the things Docker brought to the table was, effectively, a new meta-package. A lot of people had gotten familiar with RPM and Debian packages, and then JAR files for Java applications, and Ruby gems, and NPM node packages and so forth. But, they wanted to put all that together, which is a container image, like a big, rolled-up meta-package. Then, developers wanted to distribute this meta-package.
For the last year or two, there had been kind of an informal standard based on people kicking the tires of Docker, and they’re now building these Docker packages that they want to deploy in different ways, so they need to figure out their use cases. Because this method has gotten attention, it’s become an informal standard.
The importance of container standards
It’s interesting to see where people are standardizing, and it’s cool to see some competing standards emerging. For example, in the networking space, there is Docker’s container networking model (CNM), and then there’s another one called CNI, the Container Networking Interface. They have different ways of solving some similar problems, but people are electing to use one versus the other to solve their particular use cases. Although Kubernetes orchestration is being built very heavily around Docker, it ended up working around Docker’s CNM model and adopting the CNI networking spec.
The other emerging standard is Open Container’s runtime-spec and the Open Container’s image-spec. The main use case for runtime spec is have to a defined invocation model for launching a container. Some use-cases just require running a command and leaving all the bells and whistles to be handled by a higher level. The reference implementation for the runtime-spec is runC. Even at Red Hat, runC is being used for early boot containers; some stuff that might even need to get done before the Docker daemon gets started.
These containers still need to be distributed to the host, this is where the OCI image-spec comes in. A defined layout for distributing container images, where you can have choice for signing and federating, and portation of container images between varying tools. There are tools like skopeo to facilitate push, pull, and signing, and have interoperability across OCI and docker. Recent release of rkt now have support for OCI images as well.
As the standards are evolving, we already have competing ones. Before OCI there was the appc spec that covers distribution, assigning of images, and runtime, as well as the image itself. While the Open Containers Initiative only touches on a couple pieces of what appc does. But we do have a lot of cross-pollination between the two as well. Maintainers from each are contributing to the other specification, and there are maintainers from appc that are on OCI, and vice versa.
Basically, one tool does not fit all. People will have different use cases. That’s why you’re seeing some people even have a runC-type tool to run a mini-hypervisor (runv). Now the container is not just a container, it’s actually a virtual machine (VM). But all you gave it was a root file system, and then it can run a small VM with the same layout. And the image spec is just to have that interoperability that you might have built-in.
Your choice of Docker, Rocket, LXC, runC, or even sytemd-nspawn…or some of the other container tools, like bubblewrap, for non-root containers. As you’re working on your use case, you can still have portability of the same file system. You can have portability of that file system and assign that file system. Then choose the tool that makes the most sense for your use case.
Standards are very important in this way.
Key elements for success with containers
We’ve seen developers make a lot of strides and advances in the last year or two. Though the next paradigm shift is going to happen soon.
Currently, developers are taking applications that they know and are familiar with, and shoving them into a container. Then they ask a lot of VM-related questions. I feel like the next iteration of developers that aren’t just shoving the existing software into a box, that are writing or rewriting existing software or new software with container concepts and foundations in mind, will start to become a lot more aware of the confines of what their application has given. This will be an interesting space because for some people it might be very exciting, they’ve never gotten down into the kernel level. And they don’t really care about capabilities, and seccomp, syscalls, SELinux, AppArmor, and all these things. They just want to shove it in the box and run. They might still be thinking of virtual machines.
But the next iteration of developers are going to need to become a lot more aware of the fact that when their application is going to production, they won’t have root on the host; they don’t have wide-open access on the machine that’s running it; capabilites are restricted. They should assume the most confined world possible for their software.
Enabling developers to see that, access that, and profile their application is important, because even if you’re writing some high-level Ruby or Python web app, you need to know what capabilities or syscalls that application’s actually asking for. Where is your block I/O or network I/O behavior? These kind of things are good questions to ask. It’s going to make a big difference in the container world because your application might be thrown onto infrastructure that is running under confines immediately, and then you’re stuck with undefined behavior that might be a hard to debug.
I feel like there’s going to be a shift in the way developers think about writing software. For example, when they think about whether or not they need MySQL. Maybe they just need certain aspects of it. The databases might start to change. The way people write and think about applications is starting to change. More tools will become available to make it easier to see that kind of stuff.
What’s more, it’s not just the standards, it’s going to be the tools. Once there are standards, various tooling infrastructures, like debugging and tooling, will have very consistent expectations. Like on the portability of the image, or the runtime of the image, that they can build off of it. As long as it’s a moving target, most people are going to just sit back and wait until things are a little bit more stable. And that’s very important for developers. They like it hot and they like it fast, but they also don’t want weeks of debugging undefined behavior.
The future for container standards
The big thing that everybody is keeping their eyes on is how to best hedge for fragmentation. Unfortunately, with something as popular and as fast-moving and growing as containers, there is an equal chance that it could sprawl, and clash, and fragment, and nobody needs that. There’s a lot of really great stuff to be had with containers as long as people are solving for particular use cases, and being amicable to all the different use cases at play.
The flipside of that is to not have competing standards. It’s an age-old thing where you have two implementations of something and neither one of them solve it completely, so you make a third implementation. And now you have three problems. It makes sense, because if the first two weren’t solving all the use cases needed, then, obviously, something else was needed as well. So doing that fairly and amicably is going to be the biggest constant challenge, because we’re all people.
Vincent Batts is speaking at LinuxCon + ContainerCon North America 2016 in Toronto, Ontario. Several of his previous conference talks are available on YouTube: