kran
Deploy to Kubernetes with krane, the simple way. One command builds the image, pushes it, renders the krane templates and deploys them.
Kran is the German word for crane, the same word behind Shopify’s krane.
kran and krane are two different tools. krane is Shopify’s deployment tool and does the actual work. kran is this gem, which drives it. One letter apart, so read command names carefully.
Deploying with krane by hand
$ export DOCKER_HOST=ssh://builder@build.internal
$ export KUBECONFIG=$HOME/.kube/prod-east.yml
$ echo "$GITHUB_TOKEN" | docker login ghcr.io -u acme-deploy \
> --password-stdin
Login Succeeded
$ docker build --platform linux/amd64 --push \
> -t ghcr.io/acme/storefront:$(git rev-parse HEAD) .
pushed ghcr.io/acme/storefront:9c1f4d0b7a2e58c3d6f1b8a4e70925d3c8b1a6f2
$ krane render -f config/deploy --current-sha $(git rev-parse HEAD) \
> | krane deploy storefront prod-east \
> -f config/deploy/secrets.ejson -
Deploying resources
Successfully deployed 4 resources
Every value in that session is a fact about the project, not about deploying: the registry, the build host, the platform, the kubeconfig, the namespace, the context, the template directory.
With kran
Those facts move into config/kran.yml, and one command reads them:
# kran prints every step before it runs
$ kran deploy
printf '%s' '[REDACTED]' | docker login ghcr.io -u acme-deploy --password-stdin
docker build --platform linux/amd64 --push -t ghcr.io/acme/storefront:9c1f4d0b7a2e58c3d6f1b8a4e70925d3c8b1a6f2 .
krane render -f config/deploy --current-sha 9c1f4d0b7a2e58c3d6f1b8a4e70925d3c8b1a6f2 --bindings image=ghcr.io/acme/storefront:9c1f4d0b7a2e58c3d6f1b8a4e70925d3c8b1a6f2 | krane deploy storefront prod-east -f config/deploy/secrets.ejson -
Same docker, same krane, same templates. The tag is the git sha, and the full image reference is
bound into the krane templates as image.
The daily work:
kran logs -f
kran exec bin/rails db:migrate
# every resource in the namespace, then the rollout history
kran details
kran audit
# aliases, defined in config/kran.yml
kran shell
kran console
shell and console expand to exec --interactive bash and
exec --interactive bin/rails console.
If you have used kamal, this will feel just as simple: familiar command names, one config file, one command to deploy. Only the target changes, from a host to a cluster.
Not an abstraction
Kran writes no manifests, invents no resource types and holds no state. It builds command lines for
docker, krane and kubectl and runs them.
Every command takes
--dry-run, which prints the exact sequence and runs none of it.