Kube Deployer adds templating and multi-branch environments to your K8S deployments, reduces your project overhead and takes care of cleaning up merged branches.
If you want templating in your Kubernetes files and/or multi branch support please continue reading.
How to use
Go see all available commands please run:
$: kube-deploy -h
A Docker image with kubectl 1.7.7 is available here: https://hub.docker.com/r/flixtech/kube-deployer/
Internally kube-deployer uses the handlebars v3 templating engine.
Inside the template you have access to a "context" variable of type RenderContext.
type RenderContext struct {
Containers map[string]RenderContextContainer
Objects map[string]map[string]RenderContextEnvAwareObject
Env string // url slugged
Namespace string
DeployerSpec DeployerSpec
}
type RenderContextContainer struct {
Name string
}
type RenderContextEnvAwareObject struct {
Name string
}
type DeployerSpec struct {
ProjectDir string
TagVersion string
Env string
Namespace string
Containers []DeployerSpecContainer
Templates []string
Cluster DeployerSpecCluster
}
type DeployerSpecCluster struct {
Host string
Token string
}
type DeployerSpecContainer struct {
Id string
Image string
}
If you name a container "php" as id, then you reference it in your template like this:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: foo-web
labels:
app: foo-web
spec:
replicas: 1
template:
metadata:
labels:
app: foo-web
spec:
containers:
- name: php
image: "{{ context.containers.php.name }}"
...
kube-deployer is changing the metadata.name of all objects to include the env you passed.
To get the final object name you can access the context.objects map. (Templating is case sensitive)
{{ context.objects.{kind}.{original-metadata-name}.name }}
// kind must be a valid k8s object (Service|Deployment|...)
Example:
volumes:
- name: db-volume
persistentVolumeClaim:
claimName: '{{ context.objects.PersistentVolumeClaim.foo-pvc.name }}'
Either set the KUBE_TOKEN env variable or pass the token via the -token=xxx flag.
To debug locally you can pass the --dry-run and --verbose flag.
$: kube-deploy deploy ... --dry-run --verbose
In the "no-config-file" mode you need to pass all information like api host, templates, containers as cli arguments.
Following arguments are requiered:
- template (string list)
- containers (string list in format :<registry/image> the id is a key chosen by you)
- server (api host of the cluster)
$: kube-deploy deploy \
-env=production \
-branch=master \
-tag=1.4.5 \
-namespace=staging-foo \
-template=./kubernetes/staging/web.yml \
-template=./kubernetes/staging/db.yml \
-server=https://foo.k8s.io \
-container=php:foo/bar
You can place a .kube-deploy.yml file in your project and store multiple cluster data and targets and choose based on the -cluster and -namespace cli flag.
Example:
version: 1
containers:
- id: "php"
image: "foo/bar"
clusters:
de_cluster:
host: https://foo.k8s.bar.io
targets:
- namespace: staging-foo
templates:
- "./kubernetes/staging/web.yml"
- "./kubernetes/staging/db.yml"
- "./kubernetes/staging/pvc.yml"
- "./kubernetes/staging/consumer.yml"
- namespace: prod-foo
templates:
- "./kubernetes/prod/web.yml"
- "./kubernetes/prod/qa.yml"
- "./kubernetes/prod/consumer.yml"
- "./kubernetes/prod/crons.yml"
The -cluster flag is required when running with config file
$: kube-deploy deploy \
-env=prod \
-branch=master \
-tag=1.4.5 \
-namespace=staging-foo \
-cluster=de_cluster
When running kube-deploy outside of your project directory you will need to provide the absolute path via the -project-dir flag
$: kube-deploy deploy ... -project-dir=/user/app
If don't want to use the internal "kubectl apply" command from kube-deployer you can run the "render" command.
For help run: kube-deploy render -h
It takes the same arguments (without token, verbose, dry-run because they are not needed for rendering) which will work the same as the "deploy" command but it will output the rendered template on STDOUT.
This way you can do further manipulation or customize the kubectl apply call with your needs.
Here is an example of how to multi-branch-deploy from gitlab-ci.
# deploy on branch pushes
deploy-staging-branch:
image: flixtech/kube-deployer:latest
script: >
kube-deploy
deploy
-branch=$CI_BUILD_REF_NAME
-env=$CI_BUILD_REF_NAME
-tag=$CI_PIPELINE_ID
-namespace=staging-foo
-cluster=de_cluster
stage: deploy
only:
- branches
except:
- master
# deploy latest master to static-1 and static-2 staging env
deploy-sandbox-branch:
image: flixtech/kube-deployer:latest
script:
- kube-deploy deploy \
-branch=master \
-env=static-1 \
-tag=$CI_PIPELINE_ID \
-namespace=staging-foo \
-cluster=de_cluster
- kube-deploy deploy \
-branch=master \
-env=static-2 \
-tag=$CI_PIPELINE_ID \
-namespace=staging-foo \
-cluster=de_cluster
stage: deploy
only:
- master