+++ dep = 2 title = "Draft Design" authors = [ "Matt Fisher email@example.com" ] created = 2017-10-18 +++
This document outlines the general design principles of Draft; what it does, how it works, what it can (and cannot) do, as well as define its intended audience and place in the market.
What Draft Does
Draft makes it easy to build applications that run on Kubernetes. Draft targets the "inner loop" of a developer's workflow: as they hack on code, but before code is committed to version control.
Once the developer is happy with changes made via Draft, they commit and push to version control, after which a continuous integration (CI) system takes over. Draft builds upon Helm and the Kubernetes Chart format, making it easy to construct CI pipelines from Draft-enabled applications.
What Draft Does Not Do
Draft is not any of the following, nor should it be used as the following:
- a tool to be used in production deployments
- a tool to be used in replacement for a CI/CD pipeline
- a PaaS like Deis Workflow
The motivation behind why Draft should not be designed around these workflows is because it is purely intended to be used for a very quick development workflow when writing applications for Kubernetes. Production use cases such as secure signing, packaging and verification of chart deployments are all things handled through Helm. Since Draft creates helm-compatible artifacts, the artifacts created using Draft can then be passed along the toolchain to Helm.
Draft has only one major component: the Draft client.
The Draft client is a command-line client, as the name suggests. The client is responsible for the following domains:
- Building and pushing a Docker image to the Docker registry
- Combining a chart and image to build a release through Tiller
- Installing and upgrading charts by interacting with Tiller
- Interacting with plugins
The Draft client interfaces with the Kubernetes API server, a Docker registry and a Tiller (Helm server) instance.
Under the covers, Draft works with several components to achieve this architecture:
- A Kubernetes cluster - hosts the applications deployed by Draft
- A Docker Engine - builds application source code using a Dockerfile
- A Docker Registry - stores the artifacts built from
- The Helm Tiller server - deploys the image artifacts to the Kubernetes cluster
Early versions of Draft was originally designed around a client/server architecture: Draft and Draftd. Draft would package and ship uploads to Draftd, while Draftd would build the docker image, push to a registry and deploy to Kubernetes using Helm. This came with a number of limitations, most notably:
draft initcontrols were often clunky and cumbersome
- Running a docker daemon in-cluster was incredibly insecure
- the Docker daemon only worked on clusters with overlayfs as the backing filesystem
- RBAC controls between draft, draftd and tiller was complex
- TLS configuration between draft, draftd, docker, the docker registry and tiller was also complex
- alternative builder runtimes could not be implemented, at least not without bloating the system setup
- docker registry authentication would only work on a small subset of systems
- client and server-side extensions were limited in scope
Draft starts with
draft create. In this case, you must use a Draft pack (a preconfigured template for your chart) to tell Draft how to use your source code.
draft create is executed on an application, Draft performs a deep search on the current directory to determine the language, then starts iterating through the packs available in
$(draft home)/packs. If it finds a pack that matches the language description, it will then use that pack to bootstrap the application.
Draft's smart pack detection can be overridden with the
--pack flag. The detection logic will not be run and Draft will bootstrap the app with the specified pack, no questions asked.
Start from scratch
If you want to start with an application, you can simply run
draft create and it will scaffold a chart and a Dockerfile for you.
Start from a Dockerfile
Say you have an application that is already Dockerized, but not Helm-ified. Draft can start from your existing Dockerfile and create a new app:
$ ls Dockerfile src/ $ draft create --> Draft detected the primary language as Python with 85.990338% certainty. --> Ready to sail $ ls chart/ Dockerfile draft.toml src/
In the example above,
draft create constructed a new Helm Chart for you, and stored it alongside your source code so that you can add it to version control, and even manually edit it.
Start from an existing Chart
If you've already created Kubernetes applications, you can start with an existing chart and begin using Draft. There are a few patterns you may need to follow to meet the expectations for Draft, but this is a matter of a few minutes of work; not a complete refactoring.
In this case, you don't even need
draft create. You can just create the directory structure, add a draft.toml and sail onward.
Deploying your code
When you run
draft up, Draft deploys your code to your Kubernetes cluster for you. It does the following:
- Packages your code using a
- Sends your code to a Docker Registry.
- Installs (or upgrades) your chart using Helm
Take to Production
When you're done with development, Draft's "first class" objects are all supported by the Kubernetes toolchain. Deploy the chart to your production cluster in whatever way suits you, be it through a CI/CD pipeline or a
For docs on taking your chart to production, see Helm's Best Practices on Charts.
Imagine an app named
my-app, which contains a Dockerfile and some source:
myapp/ Dockerfile src/ app.py
draft create, this directory would have a chart built for it:
myapp/ chart/ python/ Chart.yaml templates/ deployment.yaml service.yaml values.yaml Dockerfile src/ app.py
chart/ directory is a complete Helm chart, tailored to your needs.
Inside of the
values.yaml file, Draft configures images for your chart:
image: repository: gcr.io/bacongobbler/myapp tag: 0.1.0
This information is then available to all of your Helm charts. (e.g. via
The contents of the
templates/ directory are determined by the particular Pack you've used.
Example applications that can be deployed using Draft can be found in the
examples/ directory in the Draft project.
Can I have multiple Draft charts in the same repo?
At this time, no. You can however use a
requirements.yaml in your chart to note what your chart depends on.
Can I modify the chart, or do I have to accept whatever the pack gives me?
You can modify the contents of the
chart/ directory as you wish. Consider them part of your source code.
Keep in mind that there are certain values injected from Draft into the chart which you'll likely want to use:
image: repository: quay.io/bacongobbler/myapp # the full name of the image tag: 08db751 # the release of the image in the registry basedomain: example.com # the base domain configured with the ingress controller ondraft: true # metadata to demonstrate this was deployed using Draft
How do I add an existing chart to Draft?
Just copy (
helm fetch) it into the
chart/ directory. You need to tweak the values file to read from
image.tag if you want draft to regenerate Docker images for you. See above.
How do I deploy applications to production?
Draft is a developer tool. While you could simply use
draft up to do this, we'd recommend using
helm package in conjuction with a CI/CD pipeline.
Remember: You can always package a Draft-generated chart with
helm package and load the results up to a chart repository, taking advantage of the existing Helm ecosystem.
User Personas and Stories
Persona: Inexperienced Kube Dev
This user wants to just work in their normal environment, but be able to deploy to Kubernetes without any extra work.
Persona: Kubernetes App Developer
This user knows all about Kubernetes, but doesn't enjoy the hassle of scaffolding out the same old stuff when testing changes. This user wants a starting point to deploy in-progress changes to a cluster.
- As a user, I want to create a new Kubernetes app...
- from scratch
- from existing code
- from a Dockerfile
- from a chart
- from some Kubernetes manifest files
- As a user, I want my app deployed quickly to a dev cluster
- As a user, I want to code, and have the deployed version auto-update
- As a user, I want to be as ignorant of the internals as possible, but still be able to GSD.
- As a user, I want to be able to hand off code artifacts without having to prepare them.