When I was deploying this cluster the goal was to have a managed Kubernetes cluster and container registry, but at the same time minimize costs. I also did not consider DigitalOcean and Linode, because as soon as we look at the better instances (more RAM and CPU), they get very close in pricing.
Azure Kubernetes Service is free when there is no SLA attached, so it is used to manage single worker cluster and takes care of the control plane.
For container registry I decided to use Amazon ECR because of its pricing model.
Example how to put value. The service is currently deployed and can be used
% curl -X POST https://kv-store.defmacro.eu/test -d 'abcd' -H 'Content-Type: application/text'
{"status": "ok"}
Example how to get value
% curl https://kv-store.defmacro.eu/test
{"status": "ok", "data": {"key": "test", "value": "abcd"}}%
Setup assumes a Kubernetes clusetr with existing Flux configured for it. For installation copy the flux-cluster/traefik, flux-cluster/kv-store and flux-cluster/postrgesql directories to the flux repository along with flulx-system and it will configure the deployments.
Wait for postgresql to become available and then use setup-pg.sh
to initialize schema and create user.
Run aws configure
and provide credentials from mail and then create ecr-credentials
imagePullSecret.
kubectl create secret docker-registry ecr-credentials \
--docker-server=722387802726.dkr.ecr.eu-central-1.amazonaws.com \
--docker-username=AWS \
--docker-password=$(aws ecr get-login-password --region eu-central-1)
Traefik requires TLS certificates to be present in the cluster so that it can serve HTTPS traffic.
Certificate can be nicely generated with Ansible:
#!/usr/bin/env ansible-playbook
- name: Generate TLS certifiacte
hosts: localhost
connection: local
tasks:
- openssl_privatekey:
path: cert.key
register: key
- openssl_csr:
path: cert.csr
privatekey_path: "{{ key.filename }}"
common_name: kv-store.example.com
subject_alt_name:
- DNS:kv-store.example.com
register: csr
- openssl_certificate:
path: cert.crt
privatekey_path: "{{ key.filename }}"
csr_path: "{{ csr.filename }}"
provider: selfsigned
kubectl create secret generic traefik-tls --from-file fullchain.pem=cert.crt --from-file privkey.pem=cert.key