Introduction to Kontena Stacks

Traditionally in application development, developers can use third-party components and libraries that implement some specific features instead of implementing those features by themselves. With containers it's not so straightforward. Of course you can use ready made images, but you may still need to extend and combine those images together, add some configuration files and remember to execute those files in the correct order to achieve a working application or system. And eventually someone has to maintain those configurations.

To help ease this problem Kontena 1.0 introduced Stacks to make developers' lives easier. The ultimate goal of Kontena Stacks is that developers can just define service dependencies of their applications and don't need to worry about their internals. Also installing some ready-made third-party applications is made extremely easy.

A software stack is a group of programs that work in tandem to produce a result or achieve a common goal.

Kontena Stacks are pre-packaged and reusable collections of Kontena services with associated configuration in the form of a YAML file.

Kontena Stacks can be categorized roughly into three categories:

  • Service stacks
  • In-house stacks
  • Application stacks

Service stacks are ready-made stacks that you can use with your applications. Those stacks can be installed directly from Kontena Stack Registry and utilized with your in-house applications. Typically those stacks are for example clustered databases (MongoDB Replica Set, MariaDB Galera Cluster etc) or some API gateways (Kong etc).

In-house stacks are your custom made stacks that contain your application services. Typically configuration for these stacks are stored in the version control system among the application's source code.

Application stacks are ready-made applications.

These stacks are for example Jenkins and GitLab. These stacks are available and ready to use from Kontena Stack Registry.

Stack files

Kontena Stacks are defined in an YAML file (kontena.yml). The main goal of stack files is to make stacks easy to configure, install and share.

The YAML file contains the stack definition, variables that are used to customize services and service definitions. Service definitions can be extended from Docker Compose YAML files (version 2).

Stack

In stack definition you can define stack, version, description and expose options.

It's recommended to define stack in the format of username/stack. That way it's easy to share the stack in the Kontena Stack Registry and see the author of the stack.

The version must follow Semantic Versioning format.

The description contains some summary of your stack to help people understand it better if you share it in the Kontena Stack registry.

With the expose option you can define which service you want to publish from your stack to other stacks. That service will get the <stack>.<grid>.kontena.local DNS address.

For example, the internal Kontena Registry is deployed as a registry stack that exposes the internal api service. The registry.test.kontena.local DNS name is an alias for the api-1.registry.test.kontena.local service container. Other service containers and the host nodes can use the bare registry DNS name to connect to the Kontena Registry.

Variables

Variables can be used to fill in values and to create conditional logic in kontena.yml files.

When defining variables you basically give it some name, where the value is obtained from and where to store the value of the variable.

By default a variable gets set to a local env with the same name, making it possible to use the value later in the YAML.

variables:  
  this_is_the_name:
services:  
  ...
  environment:
    - ENV_VAR=${this_is_the_name}

You can define multiple sources where the value of a variable is got from:

from:  
    env: MYSQL_PASSWORD # First try local environment variable
    vault: mysql-password # Then try to read from Kontena Vault
    prompt: Enter MySQL password # Then ask for a value if still not found
    random_string: 32 # Finally generate random string if user does not provide anything

Then you can define what to do with the value. The default behavior is to set it to the local environment using the variable name.

You can also use another environment variable name or write the value to the Kontena Vault.

to:  
  env: MYSQL_ROOT_PASSWORD # set to local env
  vault: mysql-password # also send to vault

It's also possible to add conditionals and use different resolvers and data types.
You can read more about these from the complete reference of variables: https://kontena.io/docs/references/kontena-yml-variables

Services

Service definitions configure running application services. If you are familiar with Docker Compose V2 files you are ready to go.

Kontena supports the majority of docker-compose YAML definitions and adds a bunch more options to leverage for example secret management, deployment and orchestration possibilities.

You can read the complete Kontena.yml reference: https here://kontena.io/docs/references/kontena-yml

Example of the Complete Stack

stack: examples/wordpress  
version: 0.1.0  
variables:  
  wordpress-mysql-root:    
    from:
      vault: wordpress-mysql-root
      random_string: 32
    to:
      vault: wordpress-mysql-root
  wordpress-mysql-password:    
    from:
      vault: wordpress-mysql-password
      random_string: 32
    to:
      vault: wordpress-mysql-password
services:  
  wordpress:
    image: wordpress:4.6
    stateful: true
    ports:
      - 80:80
    environment:
      WORDPRESS_DB_HOST: mysql
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_NAME: wordpress
    secrets:
      - secret: wordpress-mysql-password
        name: WORDPRESS_DB_PASSWORD
        type: env
  mysql:
    image: mariadb:5.5
    stateful: true
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
    secrets:
      - secret: wordpress-mysql-root
        name: MYSQL_ROOT_PASSWORD
        type: env
      - secret: wordpress-mysql-password
        name: MYSQL_PASSWORD
        type: env

How to install stacks

There are two ways to install stacks. You can install them directly from the Kontena Stack registry or install from your YAML file.

Installing from an YAML file

Stacks are installed with the kontena stack installcommand:

$ kontena stack install kontena.yml

This command will initialize a stack in the Kontena Master, but it won't be deployed. If you want to deploy it right away, you can give the --deploy option to the install command:

$ kontena stack install --deploy kontena.yml

Installing from Kontena Stack registry:

To install the latest version:

$ kontena stack install --deploy kontena/mongodb

To install some specific version:

$ kontena stack install --deploy kontena/mariadb:5.5

Future Road Map

Kontena Stacks already include handy features but we are working hard to make them even better. Here are some short-term improvements that we are introducing in the near future.

  • require and include other stacks in your stack
  • network isolation for the stacks
  • vault isolation for the stacks
  • better life-cycle management
  • organizations to stack registry

About Kontena

Kontena, Inc. is the creator of Kontena, an open source, developer-friendly container and microservices platform. Kontena is built to maximize developer happiness by simplifying running containerized applications on any infrastructure: on-premises, cloud or hybrid. It provides a complete solution for organizations of any size. Founded in March 2015, Kontena was recognized as one of the best new open source projects in the 8th annual Black Duck Open Source Rookies of the Year Awards. For more information, visit: www.kontena.io.

Image credits: Mountain Peak View by Wolfgang Lutz.