or: How I got my blog onto it with autodeployment via GitHub Actions.
The world was once a simple place. Things used to make sense, or at least there
weren’t so many layers that it became difficult to tell what the hell is going
on.
Then complexity happened. This is a tale of how I literally recreated this meme:
Deployed my blog on Kubernetes pic.twitter.com/XHXWLrmYO4
— DevOps Thought Liker (@dexhorthy) April 24, 2017
This is how I deployed my blog (the one you are reading right now) to Kubernetes.
The Old State of the World
Before I deployed my blog to Kubernetes, I used Dokku, as I had been
for years. Dokku is great. It emulates most of the Heroku “git push; don’t care”
workflow, but on your own server that you can self-manage.
This is a blessing and a curse.
The real advantage of managed services like Heroku is that you literally just
HAND OFF operations to Heroku’s team. This is not the case with Dokku. Unless
you pay someone a lot of money, you are going to have to manage the server
yourself. My dokku server was unmanaged, and I run many apps on it (this
listing was taken after I started to move apps over):
=====> My Apps
bsnk
cinemaquestria
fordaplot-backup
graphviz.christine.website
identicond
ilo-kesi
johaus
maison
olin
printerfacts
since
tulpaforce.tk
tulpanomicon
This is enough apps (plus 5 more that I’ve already migrated) that it really
doesn’t make sense paying for something like Heroku; nor does it really make
sense to use the free tier either.
So, I decided that it was time for me to properly learn how to Kubernetes, and I
set off to create a cluster via DigitalOcean managed Kubernetes.
The Cluster
I decided it would be a good idea to create my cluster using
Terraform, mostly because I wanted to learn how to use it better.
I use Terraform at work, so I figured this would also be a way to level up my
skills in a mostly sane environment.
Terraform is suffering as a service
— Cadey Ratio 🌐 (@theprincessxena) August 24, 2019
I have been creating and playing with a small Terraform wrapper tool called
dyson. This tool is probably overly simplistic and is written in Nim.
With the config in ~/.config/dyson/dyson.ini
, I can simplify my Terraform
usage by moving my secrets out of the Terraform code directly. I also avoid
having my API tokens exposed in my shell to avoid accidental exposure of the
secrets.
Dyson is very simple to use:
$ dyson
Usage:
dyson {SUBCMD} [sub-command options & parameters]
where {SUBCMD} is one of:
help print comprehensive or per-cmd help
apply apply Terraform code to production
destroy destroy resources managed by Terraform
env dump envvars
init init Terraform
manifest generate a somewhat sane manifest for a kubernetes app based on the arguments.
plan plan a future Terraform run
slug2docker converts a heroku/dokku slug to a docker image
dyson {-h|--help} or with no args at all prints this message.
dyson --help-syntax gives general cligen syntax help.
Run "dyson {help SUBCMD|SUBCMD --help}" to see help for just SUBCMD.
Run "dyson help" to get *comprehensive* help.
So I wrote up my config:
# main.tf
provider "digitalocean" {}
resource "digitalocean_kubernetes_cluster" "main" {
name = "kubermemes"
region = "${var.region}"
version = "${var.kubernetes_version}"
node_pool {
name = "worker-pool"
size = "${var.node_size}"
node_count = 2
}
}
# variables.tf
variable "region" {
type = "string"
default = "nyc3"
}
variable "kubernetes_version" {
type = "string"
default = "1.15.3-do.1"
}
variable "node_size" {
type = "string"
default = "s-1vcpu-2gb"
}
and ran it:
$ dyson plan
<... many lines of plan output ...>
$ dyson apply
<... many lines of apply output ...>
Then I had a working but mostly unconfigured Kubernetes cluster.
Configuration
This is where things started to go downhill. I wanted to do a few things with
this cluster so I could consider it “ready” for me to use for deploying applications
to.
I wanted to do the following:
- setup helm to install packages for things like DNS management and HTTP/HTTPS ingress
- setup automatic certificate management with Let’s Encrypt
- setup HTTP/HTTPS request ingress with nginx-ingress (which uses nginx)
- setup automatic DNS management because the external IP addresses of Kubernetes nodes can and will change
After a lot of trial, error, pain, suffering and the like, I created
this script which I am not pasting here. Look at it if you want to
get a streamlined overview of how to set these things up.
Now that all of this is set up, I can deploy an example app with a
manifest that loo