gokrazy: a minimal OS for Go programs (and containers)
In addition to an adorable mascot, gokrazy has some cool features:
- An entire operating system that can run on AMD64/ARM64 bare metal with only five system executables (dhcp, heartbeat, init [which starts a lightweight web interface], ntp, randomd) and then your choice of userland programs -- common options include:
- hello: simple example hello world program
- mkfs: to automatically expand the optional permanent partition
- serial-busybox: a statically compiled standalone busybox binary, for debugging on the serial port
- fbstatus: graphically shows the gokrazy system status on the Linux frame buffer, which is typically available via HDMI
- breakglass: a debugging executable that allows for SCP and SSH access
- podman: container engine
- tailscale: VPN
- caddy: HTTP server
- minio: object storage
- prometheus: monitoring system and time series database
- Immutable (read-only) root filesystem and no C runtime dramatically reduce your security vulnerability footprint
- Current Linux kernel (new versions are typically available < 24h after upstream release)
- Native update capability with A/B partitioning scheme
- Minimal state and configuration
Here's a basic example on an x86 AMD64 NUC device (which I'll call the "production machine"):
- On another Linux machine (which I'll call the "build machine"), make sure you have Go version 1.24 or higher installed: go version
- If they don't exist already, create an SSH keypair on the build machine: ssh-keygen
- Fork https://github.com/gokrazy/hello and then modify the go.mod file to indicate the new repo name, then create a new release of the hello example app as v1.0.0
- Install gok, the gokrazy CLI tool: go install github.com/gokrazy/tools/cmd/gok@main
- Create a configuration directory for your new instance, which I'll call "example": gok -i example new
- Since we're targeting an AMD device and by default gokrazy expects an ARM device, you need to edit the newly created ~/gokrazy/example/config.json file and do the following:
- Add this line above the line that says "Hostname": "KernelPackage": "github.com/gokrazy/kernel.amd64",
- In the "Environment" section, change the "GOARCH=arm64" line to say "GOARCH=amd64"
- In the "Packages" section, replace the "github.com/gokrazy/hello" line with your forked version
- Save and close the file
- To deploy to the production machine we can either create an image file and then use a tool like dd to overwrite the eMMC drive or we can use a USB thumb drive to boot and load gokrazy into memory:
- Image file: gok -i example overwrite --full example.img --target_storage_bytes 1258299392
- USB thumb drive (assuming /dev/sda is your thumb drive device -- verify your setup with lsblk): gok -i example overwrite --full /dev/sda
- In this example, we'll use the USB thumb drive approach. After running that command, the output shows a unique URL, like: "http://gokrazy:nY54bft6kxwwdLPMRL3u@example/" Make a note of that for later.
- Unplug the USB thumb drive from the build machine, plug it into the production machine and boot into it on the production machine. (Notice how fast it boots!)
- Once booted, either note the IP from the screen (if shown) or use a port scanning tool on the build machine to identify it. In my example, it was 192.168.31.192 Add this to your hosts file as an alias to the app name: echo "192.168.31.192 example" | sudo tee -a /etc/hosts
- Open link from Step 8. In the "Services" section, you'll see a "/user/hello" link. Click on it and you'll see the stdout says "Hello, 世界". Click the "run once" button and another hello will occur. Cool, huh! In theory, this could be any Go program you create statically with CGO_ENABLED=0
- Now click the "gokrazy" link in the top-left corner to view the list of services again and this time click on the "/user/breakglass" link and then click the "supervise" button. You can now SSH into the production device from the build device: ssh 192.168.31.192
- If you're curious, you can use this command to find all the executables on the OS: find / -type f -executable
- Now, make a change to your hello example app on GitHub and then perform another release as version v1.0.1
- On the build machine, all you need to do to update the production machine remotely is to run: gok -i example get github.com/YOUR_ACCOUNT/hello && gok -i example update
- This will pull the latest version of your hello example app to the build machine, then update your example instance and push the newly updated instance to the production machine which will install it and reboot automatically. All this happens super fast!
P.S. gokrazy can even help you with your non-Go needs.
Conclusion: while other similar solutions exist, such as Talos Linux and Fedora Internet of Things, I enjoy the simplicity and elegance of gokrazy ...not to mention their adorable mascot :)
Comments
Post a Comment
Keep it clean and professional...