# deployer A tool simplifying image building and deploying utilising docker, kubectl and helm. The tool tailors the commands according to the [Workflow of University Library of Leipzig] for creating official docker images and deploying to alpha- staging- and production environments. # Usage The tool is bundled with docker, kubectl and helm into a docker image itself. You can use it like this: ``` docker run --rm --volume $PWD:/app ubleipzig/deployer:latest deployer build --build-arg http_proxy=http://proxy.example.com:3128 --output image.tar.gz ``` _the working directory inside the container is `/app`, so make sure to bind local files there._ ## deployer build This command builds an image from local context. You can set multiple `--build-arg` options mainly used for providing proxy-environment variables such as `HTTP_PROXY`, `http_proxy`, ... The See [Advanced Configuration] for more information. ``` $ deployer build --build-arg http_proxy=http://proxy.example.com:3128 --output image.tar.gz ``` _builds image and saves it to file `image.tar.gz`_ ## deployer publish This command publishes an image provided as `tar.gz`-file to [Docker-Hub]. The credentials are provided as file content of dockers config-file located by default under `~/.docker/config.json` ``` $ deployer publish --docker-config "$(cat ~/.docker/config.json)" --input image.tar.gz --name example/image --tag latest --tag 1.0 --tag 1 ``` _publishes the image from `image.tar.gz` to [Docker-Hub] as *example/image:latest*, *example/image:1.0* and *example/image:1*_ ## deployer deploy This command deploys a helm-chart to a kubernetes cluster. The credentials are provided by the cluster-admin as well as the namespace and the service-account. ``` $ deployer deploy \ --namespace example_namespace \ --cluster-url https://k8s-cluster.example.com:6443 \ --certificate-authority "$base64_encoded_cacert" \ --token "$base64_encoded_bearer_token" \ --service-account tiller-service-account \ --name example-staging \ --charts ./helmcharts ``` *deploys helm-charts found at `./helmcharts` to namespace *example_namespace** Depending on existing deployment with the same name either an installation or an upgrade is performed. Upgrades always recreate the pods. If the image is pulled depends on `imagePullPolicy` of the container specs. ## deployer undeploy This command undeploys a deployment from a kubernetes cluster. The credentials are provided by the cluster-admin as well as the namespace and the service-account. ``` $ deployer undeploy \ --namespace example_namespace \ --cluster-url https://k8s-cluster.example.com:6443 \ --certificate-authority "$base64_encoded_cacert" \ --token "$base64_encoded_bearer_token" \ --service-account tiller-service-account \ --name example-staging ``` *undeploys deployment named *example-staging* from namespace *example_namespace** ## deployer add-repo This command adds a public repository of helm-charts to choose from. The credentials are provided by the cluster-admin as well as the namespace and the service-account. ``` $ deployer deploy \ --namespace example_namespace \ --cluster-url https://k8s-cluster.example.com:6443 \ --certificate-authority "$base64_encoded_cacert" \ --token "$base64_encoded_bearer_token" \ --service-account tiller-service-account \ --name incubator \ --repo-url https://kubernetes-charts-incubator.storage.googleapis.com/ ``` *adds the* incubator *repository with the url https://kubernetes-charts-incubator.storage.googleapis.com/* From now on charts located in this repository can be deployed by using the `--charts` option and providing the chart prefixed by `incubator/`. # Advanced Configuration ## docker init * `--docker-config`: sets the content of the file `~/.docker/config.json` which is used by docker to authenticate to the registry. This can contain multiple registry-servers and there credentials. Which registry is used depends on the image name. * `--cluster-url`: sets the url to the kube-apiserver. This URL is provided by the k8s-admin. * `--certificate-authority`: sets the certificate-authority certificate as base64-encoded string. This string is provided by the k8s-admin * `--token`: sets the bearer token of the service-account as bas64-encoded string. This string is provided by the k8s-admin. * `--namespace`: sets the k8s-namespace where the deployment is located. This string is provided by the k8s-admin. * `--service-account`: this is the name of the service-account, that is used to perform the deployment. * `--reset`: this ignores eventually existing config-folders of docker, helm and kubectl and removes them. * `--debug`: outputs executed commands ## docker build * `--docker-config`: sets the content of the file `~/.docker/config.json` which is used by docker to authenticate to the registry. This can contain multiple registry-servers and there credentials. Which registry is used depends on the image name. * `--build-arg`: used to provide build-arguments do `docker build`-command. This is mainly used for `HTTP_PROXY`/`http_proxy`: When you specify `--build-arg HTTP_PROXY=...` the tool adds the build argument `--build-arg http_proxy=...` as well, so lower-case proxy-variables are provided automatically. Nevertheless can you use this option to provide your own build-arguments within the `Dockerfile` * `--output`: sets the filepath to the file where the built image is saved. If omitted the image is not saved to a file. Also the script trys to import an eventually existing file prior to building in order to make usage of its layers as build-cache. * `--build-context`: sets the build-context for `docker build` to a custom path. If omitted the path where the command is invoked is used. * `--reset`: this ignores eventually existing config-folders of docker, helm and kubectl and removes them. * `--image-name`: sets the image name in the local docker-registry. Can be useful for following builds to build upon existing builds * `--docker-file`: sets the path to the Dockerfile * `--pull`: tells docker to always pull newer images before building * `--debug`: outputs executed commands ## docker publish * `--input`: sets the filepath to the file from where the image is loaded * `--docker-config`: sets the content of the file `~/.docker/config.json` which is used by docker to authenticate to the registry. This can contain multiple registry-servers and there credentials. Which registry is used depends on the image name. * `--name`: sets the name of the image. If you do not wish to publish to [Docker-Hub], you have to specify a server, e.g. `registry.example.com/my-image`. **Be aware that you need to provide credentials in your docker-config if the registry requires authentication. * `--tag`: sets the tags of the image. Provide multiple `--tag`-options if you wish to tag an image with multiple tags. * `--reset`: this ignores eventually existing config-folders of docker, helm and kubectl and removes them. * `--image-name`: specifys the image name in the local docker-registry to publish * `--debug`: outputs executed commands ## docker deploy * `--cluster-url`: sets the url to the kube-apiserver. This URL is provided by the k8s-admin. * `--certificate-authority`: sets the certificate-authority certificate as base64-encoded string. This string is provided by the k8s-admin * `--token`: sets the bearer token of the service-account as bas64-encoded string. This string is provided by the k8s-admin. * `--namespace`: sets the k8s-namespace where the deployment is located. This string is provided by the k8s-admin. * `--service-account`: this is the name of the service-account, that is used to perform the deployment. This string is provided by the k8s-admin * `--name`: sets the name of the deployment. * `--charts`: sets the path where the helm-charts reside or the public chart e.g. `stable/maridb`. * `--values`: overrides the values from `Values.yaml` in the helm-charts with values in the specified YAML file. May be provided multiple times. * `--set`: overrides the values from `Values.yaml` in the helm-charts. Provide multiple `--set`-options if you want to provide multiple overrides. * `--set-string`: overrides the values from `Values.yaml` in the helm-charts as string. Provide multiple `--set-string`-options if you want to provide multiple overrides. * `--timeout`: sets the timeout for helm. defaults to `60` seconds. * `--reset`: this ignores eventually existing config-folders of docker, helm and kubectl and removes them. * `--debug`: outputs executed commands ## docker undeploy * `--cluster-url`: sets the url to the kube-apiserver. This URL is provided by the k8s-admin. * `--certificate-authority`: sets the certificate-authority certificate as base64-encoded string. This string is provided by the k8s-admin * `--token`: sets the bearer token of the service-account as bas64-encoded string. This string is provided by the k8s-admin. * `--namespace`: sets the k8s-namespace where the deployment is located. This string is provided by the k8s-admin. * `--service-account`: this is the name of the service-account, that is used to perform the deployment. This string is provided by the k8s-admin * `--name`: sets the name of the deployment. * `--reset`: this ignores eventually existing config-folders of docker, helm and kubectl and removes them. * `--debug`: outputs executed commands ## docker add-repo * `--cluster-url`: sets the url to the kube-apiserver. This URL is provided by the k8s-admin. * `--certificate-authority`: sets the certificate-authority certificate as base64-encoded string. This string is provided by the k8s-admin * `--token`: sets the bearer token of the service-account as bas64-encoded string. This string is provided by the k8s-admin. * `--namespace`: sets the k8s-namespace where the deployment is located. This string is provided by the k8s-admin. * `--service-account`: this is the name of the service-account, that is used to perform the deployment. This string is provided by the k8s-admin * `--name`: sets the name of the repo to add. * `--repo-url`: sets the repository-url of the repo to add. * `--reset`: this ignores eventually existing config-folders of docker, helm and kubectl and removes them. * `--debug`: outputs executed commands # Assumptions This tool makes a few assumptions in order to simplify usage respecting the workflow and cluster-configuration principals if University Library Leipzig ## One service account per namespace Namespaces are used to separate a project deployment from another. Each namespace is unique per project per deployment i.e. *website-alpha*, *website-staging* and *website-production*. The rights of a service account are bound to a namespace, therefore each namespace has its own service account which is allowed to apply deployments in it. By this we are able to publish the credentials of uncritical deployments such as *alpha* and *staging* to developers, so they can independently deploy their features. The credentials of critical deployments such as *production* are restricted to maintainers which are held responsible for their deployments. ## One Tiller per namespace *Tiller* - the service component of *Helm* - is deployed in each namespace so they are independent from each other. Also *Tiller* is using the service account of the namespace to create deployments, so that a user can modify or interact with the deployments by using the service accounts credentials. ## Helmchart location Each project consists of one or more applications which are deployed together in the projects deployment-environment. Each application is responsible for its own components and defines it via helm charts located in the application repository. For consistency this folders should be named `helmchart`. [Workflow of University Library of Leipzig]: https://git.sc.uni-leipzig.de/ubl/git-test/wikis/home [Advanced Configuration]: #Advanced-Configuration [Docker-Hub]: https://hub.docker.com/u/ubleipzig/dashboard/