UpCloud+Kontena - all Suomi (Finnish) love <3

Read this blog post about using UpCloud and Kontena, by guest Kontena Community blogger, Juhani Atula.

This article was originally published on 21 FEBRUARY 2017 on Juhani's blog.

Key words: containers, cloud, upcloud, kontena, orchestration

A venture in to the unknown.

Earlier last year, I was tasked to migrate my company's wiki portal (Atlassian Confluence) to what ever platform or setup I pleased, as long as the cost would be manageable and the upkeep wouldn't be too complicated. As I am a cloud orientated dude, I naturally gravitated towards a cloud hosted solution - preferably something with containers (as containers are the hothothot thing right now).

I'm pretty fluent in using Docker, Docker Swarm and Kubernetes. The latter being arguably the best container orchestration platform right now with a really vibrant Github scene. Google is your go to place for a turn-key deployment of Kubernetes as Google Container Engine, or GKE, is actually a Kubernetes cluster under the hood. Running workloads and maintaining the Kubernetes cluster on GKE is as simple as posting YAML files or typing one-liners to the Google Cloud Shell. So, for my assignment, Kubernetes (K8S) and GKE did look like obvious choices...or did they?

Back in the fall, I was contacted by a Helsinki based cloud hosting company called UpCloud just when I was handed my task to look into hosting providers and platform alternatives for our company, so the timing was impeccable. I met up with their sales person and at the end, I had a trial account - I was intrigued.

If you don't know about UpCloud, they have a similar portfolio as DigitalOcean or Vultr, so mostly IaaS with some sides.

I demoed a K8S cluster on UpCloud and it was fine. Not as dynamic and smooth of an experience you can get on a bigger and better documented platform. UpCloud does have a good tutorial on installing K8S to get you going, but still, I do prefer the kubeadm, Stackpoint or GKE turn-key installation of K8S as the manual installation with CoreOS just hurts. Compared to Dockers Swarm Mode, manually installing K8S on top of CoreOS is like swimming through nails. When you get it going though, running workloads on K8S is a breeze.

So, UpCloud, a platform with a lot of manual work to get my container orchestration going, maybe even too much - or so I thought. That was before reading about another Helsinki-based company called Kontena and their container orchestration platform by the same name. Kontena is somewhat newish. The Github release is currently at v1.2.2.

Using Kontena feels like a mix of Docker Swarm and Kubernetes, taking good ideas from both and giving you both flavors. I do feel like Kontena tips towards K8S, which I personally prefer, but the most important thing is that, Kontena container orchestration CLI has a plugin for provisioning and maintaining your cluster on UpCloud!!! What joy of joys! No more swimming through nails for me.

Besides having easy provisioning on UpCloud (and DigitalOcean, Packet and many others), the best points about Kontena compared to Kubernetes or Docker Swarm, for example are:

  • Native support for stateful workloads, which is a must for wider adoption of containers and container orchestration among the industry. Every container that's labeled stateful gets a volume container that lives with the app . There is a drawback though, the volume container does not move with the app between nodes so you need a solution to sync data between nodes (using Resilio Sync is one option, and using my custom Resilio Sync container image is even better ;) ).
  • Easy load balancing out-of-the-box using HAProxy.
  • Support for VPN connections to the cluster with OpenVPN.
  • Access control and roles for users.
  • A private docker registry.
  • Native control plane on https://kontena.io

Many of the said features are available out-of-the-box or as 3rd party plugins on other orchestration tools. So many of the said features are not unique, but they are made very easy to use.

Let's give it a go!

We'll be spinning up a Confluence instance stack, but with a twist. I'll be going for a Postgres master + replica cluster with a pgpool in front and a Resilio Sync + Confluence front-end. The Resilio Sync lives like a hunch on Confluence's back and syncs the application data across the nodes in the cluster.

The Postgres cluster YAML file:

stack: kontenaadmin/postgres  
version: 0.2.1  
services:  
  master:
    image: crunchydata/crunchy-postgres:centos7-9.5-1.2.5
    stateful: true
    volumes:
      - /pgdata
    environment:
      - PGHOST=/tmp
      - PG_USER=pguser
      - PG_MODE=master
      - PG_MASTER_USER=masteruser
      - PG_DATABASE=confluence
      - PG_MASTER_PORT=5432
    secrets:
      - secret: PG_PASSWORD
        name: PG_ROOT_PASSWORD
        type: env
      - secret: POSTGRESQL_DB_PASS
        name: PG_PASSWORD
        type: env
      - secret: POSTGRESQL_REPLICATION_PASS
        name: PG_MASTER_PASSWORD
        type: env
    health_check:
      protocol: tcp
      port: 5432
      interval: 30
      initial_delay: 15
      timeout: 15
  replica:
    image: crunchydata/crunchy-postgres:centos7-9.5-1.2.5
    stateful: true
    volumes:
      - /pgdata
    environment:
      - PGHOST=/tmp
      - PG_USER=pguser
      - PG_MODE=slave
      - PG_MASTER_USER=masteruser
      - PG_DATABASE=confluence
      - PG_MASTER_PORT=5432
      - PG_MASTER_HOST=master
    secrets:
      - secret: PG_PASSWORD
        name: PG_ROOT_PASSWORD
        type: env
      - secret: POSTGRESQL_DB_PASS
        name: PG_PASSWORD
        type: env
      - secret: POSTGRESQL_REPLICATION_PASS
        name: PG_MASTER_PASSWORD
        type: env
    health_check:
      protocol: tcp
      port: 5432
      interval: 30
      initial_delay: 60
      timeout: 15
  pgpool:
    image: crunchydata/crunchy-pgpool:centos7-9.5-1.2.5
    volumes:
      - /pgconf
    environment:
      - PG_MASTER_SERVICE_NAME=master
      - PG_SLAVE_SERVICE_NAME=replica
      - PG_USERNAME=pguser
      - PG_DATABASE=confluence
    secrets:
      - secret: POSTGRESQL_DB_PASS
        name: PG_PASSWORD
        type: env
    health_check:
      protocol: tcp
      port: 5432
      interval: 30
      initial_delay: 15
      timeout: 15
    links:
      - master
      - replica

And the Confluence YAML file:

stack: kontenaadmin/confluence  
version: 1.2.2  
services:  
  app:
    image: registry.prod.kontena.local/jatula/confluence:6.0.4
    stateful: true
    links:
      - prod/internet/lb
    volumes:
      - confluence-data:/var/atlassian/application-data/confluence
    mem_limit: 2048m
    environment:
      - KONTENA_LB_MODE=http
      - KONTENA_LB_BALANCE=source
      - KONTENA_LB_INTERNAL_PORT=8090
      - KONTENA_LB_VIRTUAL_HOSTS=confluence.domain.com
      - KONTENA_LB_CUSTOM_SETTINGS=redirect scheme https if !{ ssl_fc }
    instances: 1
  sync:
    image: jatula/resilio-sync:2.4.4
    volumes_from:
      - app-%%s
    environment:
      - SYNC_DIR=/var/atlassian/application-data/confluence
      - SECRET=A3P5TQEQQF5EXLOKYAYX7AGKJQN6SUHTN
    instances: 1

There's a lot of steps I left out. Mainly the load balancer and secrets I used. Check out Kontena's docs for more info on those and much more.

Running the app is really straight forward. I made a short recording of setting the app stack with pretty much two one-liners.

asciicast

And that's it. I'm really liking how easy Kontena is to pick up and go. You should try it too!

About Kontena

Want to learn about real life use cases of Kontena, case studies, best practices, tips & tricks? Need some help with your project? Want to contribute to a project or help other people? Join Kontena Forum to discuss more about Kontena Platform, chat with other happy developers on our Slack discussion channel or meet people in person at one of our Meetup groups located all around the world. Check Kontena Community for more details.

Image Credits: Abstract art black and white by Ricardo Gomez Angel.

Juhani Atula

Read more posts by this author.

comments powered by Disqus