Skip to content

Latest commit

 

History

12 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TL;DR;

This code sets up a web app with at least 2 replicas and serve its content behind a load balancer via HTTPS.

  • ensure you are on a linux-based system with docker available; preferably ubuntu 24.04;
  • ensure you can use sudo and you have make installed as well;
  • run make start and wait until the details of the load balancer show up.

One-liner? curl -fsSL https://get.docker.com | sudo bash -; sudo apt install -y make; make start

Specifications and Requirements

This setup and all its deployments were tested on the following environment:

$ cat /etc/os-release
PRETTY_NAME="Ubuntu 24.04.4 LTS"
NAME="Ubuntu"
VERSION_ID="24.04"
VERSION="24.04.4 LTS (Noble Numbat)"
VERSION_CODENAME=noble
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=noble
LOGO=ubuntu-logo
$ uname -a
Linux my-instance 6.8.0-57-generic #59-Ubuntu SMP PREEMPT_DYNAMIC Sat Mar 15 17:40:59 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
$ docker version
Client: Docker Engine - Community
 Version:           29.2.1
 API version:       1.53
 Go version:        go1.25.6
 Git commit:        a5c7197
 Built:             Mon Feb  2 17:17:26 2026
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          29.2.1
  API version:      1.53 (minimum version 1.44)
  Go version:       go1.25.6
  Git commit:       6bc6209
  Built:            Mon Feb  2 17:17:26 2026
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          v2.2.1
  GitCommit:        dea7da592f5d1d2b7755e3a161be07f43fad8f75
 runc:
  Version:          1.3.4
  GitCommit:        v1.3.4-0-gd6d73eb8
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
$ minikube version
minikube version: v1.38.1
commit: c93a4cb9311efc66b90d33ea03f75f2c4120e9b0

It's not the scope of this repository to setup your NTP, but please consider doing it (though, it's not the scope here; explore yourself). Curious to hear how to setup it securely? Try this article and adapt it to your necessities.

The hardware, virtual or not, should be similar to the following:

  • CPU: 2
  • DISK: 16 GB
  • NETWORK: 1 NIC
  • RAM: 8 GB

The resources used by minikube will be restricted to not use 100% of server's hardware.

Which software projects are this setup using?

  • docker
  • haproxy
  • jq
  • kubectl
  • minikube
  • mkcert
  • nginx
  • openssh

Security aspects and considerations

To begin with, this code was signed using GPG and its authenticity can be prooved.

  • Why creating a SSH tunnel to the minikube? - That could be running in a remote machine; the channel is definitely safer over SSH.
  • TLS is not necessay on both ends, right? - That's correct, though we would advocate for a clear and safer traffic between the proxy and the "origin servers" (similar to what cloudflare and other CDN providers offer).
  • I can not access the resources with TLSv1.1 or even 1.2! - It was a requirement here to server the state of the art for the security of this deployment and its channels, and TLSv1.3 is obligatory to use it.
  • To build and setup the containers we picked LTS (long-term support) releases, correct? - Yes, one would like to follow stable and maintained versions of upstream softwares to keep thigns sharp (they receive CVE patches too).
  • Can the NTP mentioned before be set and configured in a secure way? - Yes, the openntpd project allows it easily; it relies on HTTPS from any desired reference and you can set the clock via TLS.
  • We are setting a CPU and memory limit to minikube; cpu=2, mem=4gb;
  • The pod is also limited to use resources in a similar way, inferiror to what we gave to minikube, of course;
  • Containers are not running with root privileges;
  • Pod Security Standards are in place with baseline policy, providing user friendly audit annotation logging of what the namespace of the web app is running;
  • System and filesystem capabilities are restricted - same for privilege escalation;
  • AppArmor is running and filtering out (denying) restricted accesses based on profiles;
  • Kubernetes sets by default a NoSwap usage for its pods - we are leaving this as is;, though disabling the system's swap usage in parallel while we set the environment up;
  • Unnecessary kernel modules (e.g.: dccp, and sctp) are disabled from loading and blocked permanently via modprobe's config file;
  • It's not extrictly necessary to expose the server to the public Internet, as you may use an argo tunnel or onion service to serve the contents of the web application.

There was no direct contact of use of GAI to produce this work; it is mainly formed by pieces of different experiences and archived projects put all together.

How to deploy?

Before proceeding any further check if you have docker and make available, plus you must be able to run commands with sudo.

The installation of Docker is covered by the project's official documentation here. Should you opt to install it by convenience, try the following:

$ curl -fsSL https://get.docker.com | sudo bash -

There are other options to install it and you should be encouraged to explore, by reading their official notes and documentation.

Aren't you sure that you can use sudo? Try the following command:

$ sudo -l
Matching Defaults entries for ubuntu on my-instance:
  env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty

User ubuntu may run the following commands on my-instance:
  (ALL : ALL) ALL
  (ALL) NOPASSWD: ALL

You should see something similar to the output above.

If that works for you, try installing make like this:

$ sudo apt-get install -qq -y make

Once all requirements mentioned above are met, run the following command - and go play some Mario Kart ;)

$ make start

Should be willing to get into a step-by-step run, this would be the order to follow:

$ make deps
$ make kube
$ make myapp
$ make proxy
$ make start

How to customize my setup?

The following variables can be set to modify the setup and its deployment:

Additional variable:

  • MYAPP_CLEAN_KUBE

The default value for MYAPP_CLEAN_KUBE is not set; it's empty.

  • MYAPP_KUBE (Default: armor)

Define this to anything else other than 'armor' and you will deploy the standard minikube image, without any changes from the KubeArmor project.

Testing and Troubleshooting

Considering the defaults, here's a list of commands to check and test the setup. They may differ if you changed some configuration or environment variables.

  • Send a GET request to the proxy that acts as load balancer:

    $ curl -k -I https://172.17.0.2
    HTTP/2 200
    server: nginx
    date: Sat, 21 Feb 2026 11:43:57 GMT
    content-type: text/html
    content-length: 3983
    last-modified: Sat, 21 Feb 2026 11:43:37 GMT
    etag: "69999a69-f8f"
    accept-ranges: bytes
    x-permitted-cross-domain-policies: none
    strict-transport-security: max-age=63072000
    x-content-type-options: nosniff
    x-frame-options: SAMEORIGIN
    x-xss-protection: 1;mode=block
  • Check the /myapp route and see which container is serving the health check

    $ curl -k -w '%header{x-my-app}\n' https://172.17.0.2/myapp
    app=myapp myapp-6f8cc7c464-fvjvm
    $ curl -k -w '%header{x-my-app}\n' https://172.17.0.2/myapp
    app=myapp myapp-6f8cc7c464-smlv8
    $ curl -k -w '%header{x-my-app}\n' https://172.17.0.2/myapp
    app=myapp myapp-6f8cc7c464-2tr56
  • Show the TLS certificates

    $ echo -n | openssl s_client -connect 172.17.0.2:443 -showcerts
  • Try connecting with TLSv1.2 (must not work, as we only allow v1.3)

    $ curl -k -I --tls-max 1.2 https://172.17.0.2
    curl: (35) OpenSSL/3.0.13: error:0A00042E:SSL routines::tlsv1 alert protocol version
  • Browser the website via terminal - perhaps that helps you to access the easter egg left on this setup ;)

    $ sudo apt-get install -qq -y lynx
    $ lynx https://172.17.0.2

Contributions to Upstream Projects

During the development of this code (or environments using it), the following issues and merge requests were produced:

Willing to setup a Kubernetes as a Service using OpenStack? Try checking this project out: https://github.com/OSBA-eco-digit/scs-clusterstacks-iac

References

There's no A.I. prompt to be shared; this work was not relying on it.