How Bindle Makes It Easy to Store and Distribute Cloud Native Apps
Cloud native architectures rely on microservices that break complex applications up into smaller composable pieces but there’s still the problem of storing and installing those individual pieces, which often requires developers to deal with multiple runtimes, cloud services and related artifacts.
How do you easily represent complex interdependencies like an application that can be configured to use MySQL, PostgreSQL or SQLite as a database that will need a helper library if you pick MySQL and a shim library if you’re deploying on a system that doesn’t have a GPU, without the package being so large that it’s impractical to deploy when bandwidth is tight?
That’s the kind of common scenario that the Bindle package repository system (soon to reach its 0.9 release) was designed to address, grouping related objects for distribution using aggregate storage where clients can retrieve just the parts of the package they need.
“We knew that as WebAssembly matured, applications in WebAssembly were going to be built of composite binaries, where you have a whole bunch of different binaries stored together that could link with each other in different configurations and we built Bindle to do that,” Bindle maintainer and Fermyon Technologies CEO Matt Butcher told the New Stack.
“The system was set up to conceptualize applications the way we want to in the cloud native ecosystem. An application shouldn’t be considered a binary: that was the way we were thinking about applications years and years ago. Now we have to think of applications in terms of a conglomerate of different microservices and maybe even some files and objects and things like that. They all have to fit together in a very particular way in order to accomplish their job but they are actually several different binaries.”
The Silverware Drawer
Butcher and Bindle maintainer Taylor Thomas uses the metaphor of the silverware drawer in the kitchen, where you might keep chopsticks and straws and tea strainers as well as knives forks and spoons, with rules like “you need two chopsticks and probably a spoon” or “this spoon is only used for soup and this spoon is only used for tea”.
“The silverware drawer is the idea of saying regardless of the shape and size you should be able to store all this stuff in that same thing and explain to the system this is how I need to retrieve it and these are the things I get back.”
Bindle (named after the handkerchief-wrapped bundle tied to the end of a long stick that you can imagine holding everything you need) handles groups of related objects, with each “bindle” package having an invoice: a manifest explaining what the bindle does and listing all the parcels that make up the package.
Invoices have to have version numbers (Bindle uses semantic versioning so if you search for v1.2 and v1.2.4 is the latest version, you’ll be offered that but if you know you need v1.2.3 instead you can search for that explicitly).
Conditional groups can list requirements (the application needs a Borne-style shell so at least one of Bash, Korn, Zsh or Busybox needs to be installed), optional add-ones or chains of dependencies (the application needs at least one web server and if NGNX is installed, a particular NGNX module must also be installed).
“That’s how we group things,” Thomas explains, “there are things we use together that that are entirely different from each other.”
You’d use a group to list the SQLite, PostgreSQL and MySQL plus helper library database options and a feature for the shim library required when there’s no GPU. Instead of downloading six components, people get the two or three they need, saving network bandwidth and storage. And if one of the parcels is already installed because another package uses the same version of Postgres, the Bindle client will use that rather than downloading it again.
“You save a lot of bandwidth with Bindle,” he points out. “Instead of having to download whole tarballs where half of it you don’t need, you can now just download exactly what you need, given your circumstances.”
These invoices can be as simple or complex as the application requires.
“You don’t have to fit your application into an existing mold,” Butcher explained: “you can store the application the way you want it stored and then reassemble it the way you need to reassemble it later.”
Store and Deploy
He gives the example of a game he coded for a colleague with a very picky cat. The Finicky Whiskers app has seven microservices packaged into a single bindle: one for the scoreboard, another than handles the button you click to offer the cat different types of food. “When we refresh the Finicky Whiskers site, it pulls the bindle out and reconstitutes the application from that.”
“That’s the flexibility of being able to store things in Bindle. You can package up seven different microservices all in one big application and deploy it wherever [you need]. You can store a single binary, you can store an application that has dozens of different binaries: you can probably store a file system in there if you want. It’s proven to be a very nimble format for us.”
“It’s surprising to me that no one has even thought about doing it this way,” Thomas told us. “Everyone wants to think of it as a tarball or some sort of very flat structure and Bindle is taking the approach that you might want to assemble things from different parts. Internally in Cosmonic we’ve already seen multiple instances where we need to be able to version something that has a couple of different disparate components and put it together.”
The idea behind Bindle might actually sound familiar if you’ve come across Porter, a packaging tool created by colleagues of the Bindle creators that recently reached 1.0, or the Cloud Native Application Bundle (CNAB) specification it implements. “CNAB is for installing applications, for taking an application and installing it everywhere and Bindle is for storing those things,” Thomas explained. “Those two projects came from the same team because we were thinking about that from two different angles: one is the actual deployment of the application, and one is how you store it.”
Bindle was originally planned as a way to store and share WebAssembly applications and binaries although it’s proving useful more broadly. Butcher characterized CNAB as a similar approach for the container ecosystem, calling Bindle “what we learned working with registries and CNAB — that there should be a better way to store microservice-based applications and then deliver that microservice-based application”.
CNAB and Bindle could work together, Thomas suggested. “You could have CNAB pull the artifacts that it needs from the Bindle server.”
WebAssembly isn’t the only place Bindle could be useful; “there’s many other things that we have found that don’t have anything to do with WebAssembly where it comes in handy.” The principle of having implementation details that vary between systems and allowing the runtime to make the decision about what to pull down works for a lot of scenarios.
Bindle could handle file system snapshots for building infrastructure where you need specific numbered releases, or where you want to deploy at the edge where you can’t control what hardware will be available (and don’t want to have to create multiple container images for different hardware). “I’m assuming that if Bindle continues to grow, we’ll start to see like things that are Bindle aware for specific runtimes and how to leverage those,” Thomas said.
“We’ve needed this for a long time.”
Secure Package Registry
The first special interest working group at the Bytecode Alliance (the industry group building shared implementations of WebAssembly standards) is SIG-Registries, which is working on the specification for a package registry for WASM components. “A central hub for us to share the different WebAssembly applications and binaries that we’re building and then allow people to pull from that and assemble their own applications and upload those,” Butcher explained, comparing it to npm or Docker Hub for WASM.
Bindle has been proposed as the storage layer for that, with a package API layered on top and may become the reference implementation.
With the WebAssembly component model, applications are built out of small units like Lego blocks. “A component alone depends on many other components: if you get one component, that’s not enough to run anything,” Bailey Hayes from the SIG-Registries working group explained. Bindle makes it easy to pull all the components and nested dependencies you need. “With SIG-Registries, I think we’re going to build on a lot of what Bindle has come up with and the way that all those pieces work.”
The appeal of WebAssembly isn’t just that code can run in many different places but the combination of performance and security. WebAssembly code should be designed to have only the capabilities and permissions it really needs and it’s that as much as the sandbox that offers a better security model, because components can do things like opening sockets that essentially punch a hole in the sandbox. Importing components means you’re relying on them behaving well and being well written, so the component registry needs to implement a chain of trust, Hayes said.
“It’s a complete rethinking of how we’ve been doing registries in the past, how we want to do them in the future and just like many of the other WebAssembly standards that have come before us, it’s all about having security as a first principle.”
Bindle is a good fit for that because it was designed to have security on by default. Bindles are immutable: they’re cryptographically hashed and signed and neither the name nor the contents can be changed.
“There should be no question that when I pull something back out of the registry, it is the same exact thing that somebody put into the registry before,” Taylor explained. “There is no sense in which it can be tampered with, or that a bad actor could come in and redirect one thing to another thing.”
The upcoming 0.9 release will require all bindles to be signed; “that’s always been stated since the beginning that it would be the plan,” Thomas noted, but there will be an RC release to make sure it doesn’t break anything for organizations like Fermion, Cosmonic (where Thomas and Hayes work) and Suborbital that are already using Bindle.
Because Bindle was designed for signed bindles, while they will need to do a little more work, this won’t significantly change the developer experience. “The Bindle key spec [means] the base default is for me to get at least the most simple level of security, which is saying I trust this host, I must know every single thing I’ve pulled down from that host is actually coming down from that host.”
On top of that organizations will be able to build more restrictive policies in WebAssembly and Bindle but still give developers flexibility, Cosmonic CEO Liam Randall pointed out. “You can say ‘only allow the import of modules that have a scan or that meet certain requirements.’ You can have organization-specific policies that would show me choices that meet my policies. Within a regular development pipeline, perhaps you have major and minor numbers of a component, and only the majors get a security assessment, and maybe in prod you would just want those but in dev, you would want other options.”
“I can look at these things at a glance and say what level of risk I want to take on,” Hayes noted.
Getting to Bindle 1.0
The 1.0 release of Bindle may not follow the 0.9 release until there’s enough usage to make it clear the spec hasn’t missed any edge cases that would need breaking changes, Thomas explained.
“We haven’t designed a registry, which is basically a storage system from the ground up. We have a background from people who’ve done little bits and pieces of it and worked with OCI and different parts of the ecosystem but because this is an entirely new way of doing things, we knew we probably got some stuff wrong and so we didn’t want to have to break the spec too soon.”
Having worked on projects like Helm, the Bindle maintainers have strict requirements around semantic versioning and bandwidth compatibility and the only breaking changes to 1.0 would be security related. “That’s a rule we follow because all of us have been bit by trying to upgrade from one supposedly minor version of Kubernetes to the next minor version of Kubernetes and having three APIs break on you and we don’t want to do that to people.”
That doesn’t mean Bindle isn’t ready to use in production now: platforms like Fermion and Cosmonic are built on Bindle (and Cosmonic uses it for both WebAssembly and part of the platform that are not built with WebAssembly). “It’s solid enough to use, it’s just not 1.0 because we wanted to reserve the right to make a breaking API change or a breaking spec change.”
That’s particularly important for a specification that Thomas says aims to be “simple, straightforward and open” and will be implemented in multiple ways for the different ways platforms might need to set up and run Bindle. There’s already an F# implementation and a proposal for implementing Bindle as a set of wasmCloud actors.
The flexibility of the silverware drawer metaphor is part of what makes Bindle so powerful because it allows for experimentation when exploring projects like SIG-Registries (which may ultimately have a more rigid package API than Bindle requires), Taylor suggested. “People can try different things and see when we make it rigid, which set of assumptions are going to hold.”
“It’s malleable enough to move with the standard but at the same time the internals are pretty solid.”
That comes from the frustration of having to constantly rebuild otherwise working systems Butcher said. “As developers, we tend to build solutions for a specific problem but technology evolves so rapidly, that very often, it’s only a few years before we’d say, oops, we made an assumption and the assumption no longer fits the design.”
“I’ve been a software developer for 25 years now and I think no lesson is learned so clearly by experience in this industry as the lesson that technology as a whole moves forward, but individual technologies have a very short shelf life. Consequently, we constantly have to revisit assumptions: yesterday’s assumptions that seemed safe yesterday, may not be safe today and will certainly be out of date tomorrow. As an industry moving toward more flexible solutions is going to be an important thing: if we want to somehow break out of the trap of having to continually re-architect particularly the low-level stable things then we need to get better at designing with flexibility in mind.”