Up to Main Index                             Up to Journal for April, 2026

                      JOURNAL FOR SUNDAY 5TH APRIL, 2026
______________________________________________________________________________

SUBJECT: Kubernetes clusters, site sins and generators
   DATE: Sun  5 Apr 16:25:51 BST 2026

Let’s start by discussing Kubernetes clusters…

Over the past week I found myself in need of a small Kubernetes cluster for
some local development work. No problem, I had my `node-setup` script from
“How-To: Build Kubernetes Clusters”[1]. Yes problem, I needed it to work on my
MacBook Pro M4. The script was only written and tested on AMD64.

I could have just hacked something together quickly. Instead there is now an
updated How-To and `node-setup` script v0.0.5 that works for AMD64 or ARM64.
The ARM64 version is tested on a MacBook Pro M4 using UTM[2] virtual machines.

The `node-setup` script has also been fixed after the Kubernetes dashboard was
archived, due to it being deprecated and unmaintained. The dashboard has been
replaced by Headlamp[3], however I have not had time to look into that yet.

One final change to the `node-setup` script. You can now force the IP address
used for the control-plane and worker nodes. For some reason macos and UTM
create a huge number of interfaces and bridges. On my MacBook Pro macos has
two bridges and a dozen interfaces listed and the wrong one is always picked.

In other news, a mortal sin against this site?…

I’ve continued working on my new static site generator. The intent is to
rebuild the WolfMUD site. In doing so I have committed a mortal sin :( For
over 15 years this site has had no JavaScript, except in the Annex for the
Mere ICE section — where its use is clearly labelled. With the rebuild I will
be adding roughly 400 bytes of Javascript:


  (function() {
    document.querySelectorAll('pre > span + code[class^="language-"]')
    .forEach(c => {
      const b = document.createElement('button');
      b.className = 'copy-button';
      b.innerText = 'Copy';

      b.onclick = () => navigator.clipboard.writeText(c.innerText.trim())
      .then(() => {
        b.innerText = 'Done';
        setTimeout(() => b.innerText = 'Copy', 1000);
      });
      c.before(b);
    });
  })();


The JavaScript is intended as a quality of life improvement for readers. It
simply adds a `Copy` button to commands and code snippets allowing easy, error
free copying to the clipboard. If JavaScript is turned off, no button is added
and you can continue to manually copy and paste from the website.

Finally, the static site generator…

As for the generator itself, it is about 23Kb or 800 lines of finely tuned
Bash. How finely tuned? This is the report from a ‘cold’ build and a ‘hot’
build of a small selection of pages I’m testing with:


  >rm -rf ./public/*
  >./build.sh
  2026-04-05T13:50:00.235 Starting
  2026-04-05T13:50:00.238 Examining site structure
  2026-04-05T13:50:00.249 Generating meta-data
  2026-04-05T13:50:00.310 Checking for latest journal entry
  2026-04-05T13:50:00.313 Generating pages
  2026-04-05T13:50:00.353 Generating indexes
  2026-04-05T13:50:00.448 Generating assets
  2026-04-05T13:50:00.527 ---------- Build Summary ----------
                          Meta-Data:    21 Built     0 Skipped    21 Total
                              Pages:    12 Built     0 Skipped    12 Total
                            Indexes:     9 Built     0 Skipped     9 Total
                             Assets:    19 Built     0 Skipped    19 Total
  2026-04-05T13:50:00.529 Finished in 00h00m00.310s
  2026-04-05T13:50:00.532 Exiting.
  >./build.sh
  2026-04-05T13:50:18.153 Starting
  2026-04-05T13:50:18.155 Examining site structure
  2026-04-05T13:50:18.166 Generating meta-data
  2026-04-05T13:50:18.170 Checking for latest journal entry
  2026-04-05T13:50:18.173 Generating pages
  2026-04-05T13:50:18.196 Generating indexes
  2026-04-05T13:50:18.200 Generating assets
  2026-04-05T13:50:18.203 ---------- Build Summary ----------
                          Meta-Data:     0 Built    21 Skipped    21 Total
                              Pages:     0 Built    12 Skipped    12 Total
                            Indexes:     0 Built     9 Skipped     9 Total
                             Assets:     0 Built    19 Skipped    19 Total
  2026-04-05T13:50:18.210 Finished in 00h00m00.071s
  2026-04-05T13:50:18.219 Exiting.


That’s 310ms to build 12 static pages, 9 index pages, copy 19 assets and
pre-compresses everything. The ‘hot’ build goes through the motions of
checking everything is up to date and has nothing to build taking only 71ms.

The build is dependency driven. For example if I touch a single page’s
Markdown source and rebuild:

  >touch src/annex/building-kubernetes-clusters.md
  >./build.sh
  2026-04-05T13:52:24.877+01:00 Starting
  2026-04-05T13:52:24.879+01:00 Examining site structure
  2026-04-05T13:52:24.889+01:00 Generating meta-data
  2026-04-05T13:52:24.958+01:00 Checking for latest journal entry
  2026-04-05T13:52:24.961+01:00 Generating pages
  2026-04-05T13:52:25.024+01:00 Generating indexes
  2026-04-05T13:52:25.139+01:00 Generating assets
  2026-04-05T13:52:25.141+01:00 ---------- Build Summary ----------
                                Meta-Data:     1 Built    20 Skipped    21 Total
                                    Pages:     1 Built    11 Skipped    12 Total
                                  Indexes:     2 Built     7 Skipped     9 Total
                                   Assets:     0 Built    19 Skipped    19 Total
  2026-04-05T13:52:25.147+01:00 Finished in 00h00m00.285s
  2026-04-05T13:52:25.156+01:00 Exiting.

Hrm, 285ms. In that time the generator:

  • built the meta-data for …/annex/building-kubernetes-clusters.meta
  • built+compressed the HTML page for …/annex/building-kubernetes-clusters.html
  • built+compressed the HTML index for …/annex/index.html
  • built+compressed the HTML index for …/index.html

If any of that seems too slow, we just turn off the reporting:


  >rm -rf ./public/*
  >time ./build.sh -q
  real    0m0.253s
  user    0m0.671s
  sys     0m0.191s
  >time ./build.sh -q
  real    0m0.059s
  user    0m0.051s
  sys     0m0.016s
  >touch src/annex/building-kubernetes-clusters.md
  >time ./build.sh -q
  real    0m0.236s
  user    0m0.176s
  sys     0m0.095s


Hrm… 253ms for a full ‘cold’ build, 59ms for a ‘hot’ build and 236ms for an
incremental build. Not to shabby even if I do say so myself. I thought Bash
was supposed to be slow? No, no, unoptimized shell scripts are slow ;)

I also tried the same performance tests on a Raspberry Pi 4 (4Gb) the same as
the website is hosted on. 1,322ms (1.3s) for a full ‘cold’ build, 93ms for a
‘hot’ build and 371ms for an incremental build. I think I can live with sub
400ms builds whenever I push up a new journal entry :)

--
Diddymus

  [1] How-To: Build Kubernetes Clusters:
      /annex/building-kubernetes-clusters.html

  [2] UTM - Virtual machines on Apple silicon: https://github.com/utmapp/UTM

  [3] Kubernetes Headlamp: https://headlamp.dev/


  Up to Main Index                             Up to Journal for April, 2026