CNAB: Packaging for Distributed
Applications with Multiple Toolchains
January 2019
Gareth Rushgrove
Slide 2
Slide 2 text
@garethr
Docker
Slide 3
Slide 3 text
This talk
- A little background
What is the user need behind CNAB?
- Diving into the CNAB specification
Core concepts and state of play
- Emerging CNAB tools
What tools have been built so far?
An introduction to Cloud Native Application Bundles
Slide 4
Slide 4 text
No content
Slide 5
Slide 5 text
A bit of background
Slide 6
Slide 6 text
How many tools do you use?
In particular when describing/deploying your apps
Multi-service apps often use
multiple toolchains
Which means distributing lots of versions of lots of tools,
often separately from the application
Slide 11
Slide 11 text
Large organisations often have a
diversity of toolchains
Which means distributing lots more versions of lots
more tools
Slide 12
Slide 12 text
CNAB allows for packaging the
tools along with the app they manage
Just install
Slide 13
Slide 13 text
AWS RDS and Helm example
Slide 14
Slide 14 text
But how many times have we
re-invented package formats?
Hint, it’s more than once
Slide 15
Slide 15 text
With reference to XKCD 927
Slide 16
Slide 16 text
CNAB isn’t trying to solve
the whole problem
Just the bits we can build agreement around
Slide 17
Slide 17 text
Metadata
Fundamental parts
What do we mean when we say package
On-disk representation
Execution
Distribution
Slide 18
Slide 18 text
Terraform
Cloud
Formation
Azure
Resource
Manager
Compose Helm Pulumi etc.
Terraform
Module
None None None
Helm
Chart
None etc.
Terraform
Module
Registry
None None None
Helm
Chart
Repository
None etc.
Slide 19
Slide 19 text
Terraform
Cloud
Formation
Azure
Resource
Manager
Compose Helm Pulumi etc.
Terraform
Module
None None None
Helm
Chart
None etc.
CNAB compatible registries
Compatibility between repositories/registries should reduce the
upfront cost for adopting new technologies that utilise CNAB. You’ll
already have a compatible package registry in place.
Slide 20
Slide 20 text
Terraform
Cloud
Formation
Azure
Resource
Manager
Compose Helm Pulumi etc.
Standard tools for creating packages for different toolchains
Today not all tools have a package concept, CNAB makes that
easier to implement in a standard way, either in technology-specific
tooling (better UX) or generic tooling (no need to wait for integration)
CNAB compatible registry
Slide 21
Slide 21 text
CNAB is more like MSI than Helm
Charts or Terraform Modules
It’s not tool specific, it’s about compatibility between tools
Slide 22
Slide 22 text
Demo
Slide 23
Slide 23 text
Diving into the spec
Slide 24
Slide 24 text
deislabs/cnab-spec
Slide 25
Slide 25 text
Metadata
CNAB parts
What do we mean when we say package
On-disk representation
Execution
bundle.json
Specified file system layout
OCI runtime with specified entry point and arguments
Distribution OCI image and distribution specifications
Slide 26
Slide 26 text
Table of contents
Slide 27
Slide 27 text
bundle.json
A schema for package metadata
Slide 28
Slide 28 text
No content
Slide 29
Slide 29 text
Basic metadata like name,
version, description, etc.
Slide 30
Slide 30 text
Credentials required by the
tools to talk to relevant APIs
(eg. KubeConfig.)
Slide 31
Slide 31 text
The actions which the bundle
responds to. Must include
install, uninstall and upgrade.
Slide 32
Slide 32 text
The user interface exposed to
those installing the package.
These are provided at
runtime.
Slide 33
Slide 33 text
Extend the metadata with
format specific information.
Slide 34
Slide 34 text
Invocation Image
- A file system hierarchy following a defined pattern
- A executable entry point responsible for translating action requests
(install, upgrade,...) to a sequence of tasks
- Runtime metadata
- The material necessary for reproducing the invocation image
Referenced in the bundle.json
Slide 35
Slide 35 text
Claims
A record of a CNAB action
Slide 36
Slide 36 text
Signing, Attesting, Verifying
and Validating
Ensure package was vetted by a trusted entity and has not
been altered
Slide 37
Slide 37 text
Emerging CNAB tools
Slide 38
Slide 38 text
Duffle: Go reference implementation
Slide 39
Slide 39 text
Building a CNAB with duffle
$ duffle build ./examples/helloworld/
Step 1/5 : FROM alpine:latest
---> 196d12cf6ab1
Step 2/5 : RUN apk add -u bash
---> Using cache
---> 54b3a85c5c2e
Step 3/5 : COPY Dockerfile /cnab/Dockerfile
---> Using cache
---> cd6f4ff8d83d
Step 4/5 : COPY app /cnab/app
---> 38a482447ffd
Step 5/5 : CMD ["/cnab/app/run"]
---> Running in 8b22055f0a37
---> e5c795c2a1f4
Successfully built e5c795c2a1f4
Successfully tagged deislabs/helloworld-cnab:64dfc7c4d825fe87506dbaba6ab038eafe2a486d
==> Successfully built bundle helloworld:0.1.0
Slide 40
Slide 40 text
Installing a CNAB with duffle
$ duffle install helloworld-demo -c helloworld-creds helloworld:0.1.0
Executing install action...
hello world
Install action
Action install complete for helloworld-demo
Slide 41
Slide 41 text
Docker App: Package Compose apps
Slide 42
Slide 42 text
Start with a Compose file
$ cat docker-compose.yml
version: '3.6'
services:
hello:
image: hashicorp/http-echo:${version}
command: ["-text", "${text}"]
ports:
- ${port}:5678
Install and upgrade your application
$ docker-app install
Waiting for the stack to be stable and running...
hello: Ready
Stack hello is stable and running
$ docker-app status
ID NAME MODE REPLICAS IMAGE PORTS
38e1cec8-f88 hello_hello replicated 0/0 hashicorp/http-echo:latest *:8765->5678/tcp
$ docker-app upgrade hello --set port=9876 --set text="hello again"
Waiting for the stack to be stable and running...
hello: Ready
Stack hello is stable and running
Slide 46
Slide 46 text
Get information about your bundle
$ docker-app inspect
hello 0.1.0
Maintained by: garethr
sample app for DockerCon
Service (1) Replicas Ports Image
----------- -------- ----- -----
hello 1 8765 hashicorp/http-echo:latest
Parameters (3) Value
-------------- -----
port 8765
text hello DockerCon
version latest
Slide 47
Slide 47 text
Push bundles to Docker Hub
$ docker-app push --namespace garethr
The push refers to repository [docker.io/garethr/hello]
b86b3b8bd0d3: Pushed
6b91c6b22046: Mounted from garethr/myapp
ead7fcac6d91: Mounted from garethr/myapp
df64d3292fd6: Mounted from garethr/myapp
0.1.0-invoc: digest: sha256:9f5fa85893cc87024a74b2261d19a309e5de55dff5e43d19fcf1d2f2657dbe2a size:
1157
Successfully pushed
garethr/hello:0.1.0@sha256:1f7f2ac9ce061f7727addce5843d65fb052382f4e5f92dd38dd519b5e9b1e60a
$ docker-app install garethr/hello:0.1.0
Waiting for the stack to be stable and running...
hello: Ready
Stack hello is stable and running
Slide 48
Slide 48 text
CNAB is an implementation detail,
unless you want to drop down a level
Slide 49
Slide 49 text
bundle.json and Invocation Image
$ docker-app bundle
Invocation image "hello:0.1.0-invoc" successfully built
$ docker image ls hello
REPOSITORY TAG IMAGE ID CREATED SIZE
hello 0.1.0-invoc cfd34904554c 6 days ago 40.1MB
$ cat bundle.json
{
"name": "hello",
"version": "0.1.0",
"description": "sample app for DockerCon",
"maintainers": [
{
"name": "garethr",
"email": "[email protected]",
"url": ""
}
Slide 50
Slide 50 text
By creating CNAB bundles we get a
GUI installer for free, in the form of
duffle-bag
Why we adopted CNAB?
Slide 51
Slide 51 text
We can also more easily add
support for different toolchains,
all in the same signed package
Why we adopted CNAB?
Slide 52
Slide 52 text
Some examples to get you started
garethr/docker-app-cnab-examples
Running a CNAB from Python
from cnab import CNAB
app = CNAB("fixtures/hellohelm/bundle.json")
# list available actions
print(app.actions)
# list available parameters
print(app.parameter)
# list required credentials
print(app.credentials)
# Here we pass the value for the required credential
# in this case by reading the existing configuration from disk
with open("/home/garethr/.kube/config") as f:
print(app.run("status", credentials={"kubeconfig": f.read()}))
Slide 59
Slide 59 text
Conclusions
Slide 60
Slide 60 text
Conclusions
- CNAB is a specification first
Think MSI or OSI rather than Helm Charts
- Early days, but lots of hacking potential
Client libraries, contribute to existing tools, integrate your own software
- Get involved
#cnab on CNCF Slack, or open issues on the GitHub repository
If all you remember is...