Compare commits

...
Sign in to create a new pull request.

4 commits

Author SHA1 Message Date
jon brookes
8ff2f6dc12 Refactor MVK documentation
templates; streamline navigation, add new guides, and enhance clarity in prerequisites, configuration, and run instructions for Gcloud setups.
2025-10-21 15:53:12 +01:00
jon brookes
cce1c1aa7a Add initial documentation for Gcloud single node setup; include pre-requisites, configuration, and run guides. 2025-10-21 11:37:53 +01:00
jon brookes
cad1e562ac Update MVK documentation and configuration; correct LOG_FORMAT variable and enhance index description. 2025-10-21 11:21:12 +01:00
jon brookes
2804824444 Add comprehensive guides for gcloud setups;
include instructions for cluster creation, smoke testing, and infrastructure management.
2025-10-03 18:09:26 +01:00
24 changed files with 611 additions and 35 deletions

View file

@ -23,37 +23,15 @@ export default defineConfig({
sidebar: [
{
label: 'MVK',
items: [
// Each item here is one entry in the navigation menu.
{ label: 'Minimal Viable Kubernetes', slug: 'mvk/intro' },
],
},
{
label: 'infctl',
items: [
// Each item here is one entry in the navigation menu.
{ label: 'Introduction', slug: 'infctl/intro' },
{ label: 'Quick Start Guide', slug: 'infctl/quick-start' },
{ label: 'Configuration', slug: 'infctl/configuration' },
],
autogenerate: { directory: 'mvk' },
},
{
label: 'Microlearning',
autogenerate: { directory: 'guides' },
// items: [
// { label: 'Local Dev Environment', slug: 'guides/dev-env' },
// { label: 'Create a Local K3d Instance', slug: 'guides/local-k3d' },
// { label: 'Initial Pipeline Run', slug: 'guides/infctl-first-run' },
// { label: 'Create a vagrant 3 node cluster', slug: 'guides/local-vagrant-cluster' },
// { label: 'Add Longhorn Storage', slug: 'guides/local-vagrant-cluster-storage' },
// { label: 'Add Ingress', slug: 'guides/local-vagrant-cluster-ingress' },
// ],
},
{
label: 'MVK Templates',
autogenerate: { directory: 'templates' },
},
{
label: 'Reference',

View file

@ -0,0 +1,90 @@
---
title: Google Cloud MVK
description: A guide to creating a virtualized Google Cloud k3s instance.
---
###### Use case :badge[development]{variant=success} :badge[pre-production]{variant=caution}
# Introduction
Google Cloud can be used to host a lab that can be cheaper to run if the hardware you use for your day to day is not sufficiently capable and can also offer an alternative that is close or identical to production.
The approach adopted by MVK strongly supports the use of *infrastructure as code*. A key benefit of this being its ability to build and more imortantly *rebuild* infrastructure from scratch.
This means that you can **destroy** infrastructure when it is not needed.
Fort test, development and validation work, this has many benefits.
* Reduced costs - your not paying for hosting when you don't need it
* Increased confidence - in your infrastructure being recoverable in the event of a disaster
* Better testing - of both your infrastructure and your applications as each test cycle is guaranteed to have a 'clean', consistent and predictable environment.
# Prerequisites
If you have not [already installed `infctl`](/infctl/quick-start/) please do so.
If your a Windows user, be sure to check [Notes for Windows Users](https://mvk.headshed.dev/guides/001-dev-env/#note-for-windows-users) to ensure you have [Git and Bash](https://git-scm.com/downloads) installed.
Suffice to say, you will need to run the following in a bash capable console:
```bash
curl -L https://codeberg.org/headshed/infctl-cli/raw/branch/main/install.sh | bash
```
## Install OpenTofu
We will build Google Cloud infrastructure with Terrarorm and using OpenTofu which you can find download and installation instructions for all major platforms here:
https://opentofu.org/docs/intro/install
## Sign Up for Google Cloud Console
To create and manage Google Cloud resources, you need a Google Cloud account.
1. Visit the [Google Cloud Console](https://console.cloud.google.com/).
2. Sign in with your Google account or create one if you don't have one yet.
3. Follow the prompts to set up billing (a free trial may be available).
4. Once signed in, you can create a new project by clicking on the project dropdown at the top and selecting "New Project".
5. Name your project and click "Create".
You will use this project to build and manage your cloud resources.
## Install the Google Cloud CLI
To interact with Google Cloud resources, you need to install the `gcloud` command line interface.
`gcloud` is available for all major platforms, be they Windows, Linux or Mac.
You can find an installation and download for each at :
https://cloud.google.com/sdk/docs/install
After installation, open a new Command Prompt and initialize the CLI:
```cmd
gcloud init
```
Refer to the [official documentation](https://cloud.google.com/sdk/docs/install#windows) for troubleshooting and advanced options.
## Sign up for Hosted DNS
To access your lab in Gcloud, you need to buy or already have a domain name and the ability to manage where its 'A records' point to.
You can use any DNS provider of your choosing that can do this for you but here is a quick guide to sign up for a free Cloudflare account where you can both buy and manage existing or new domain names.
Cloudflare offers free DNS management and security features for your domains.
1. Go to [Cloudflare Sign Up](https://dash.cloudflare.com/sign-up).
2. Enter your email address and create a password.
3. Click "Create Account".
4. After logging in if you already have a domain name, click "Add a Site" and enter your existing domain name.
5. Select the free plan and continue.
6. Cloudflare will scan your DNS records; review and confirm them and give instructions to complete the process.
Once sign up is complete, you can buy or import other Domain names and manage their records and settings from the Cloudflare dashboard.
Next we will run a pipeline to create a single node development cluster running k3s in gcloud.

View file

@ -0,0 +1,95 @@
---
title: Create gcloud infrastructure
description: A guide to creating gcloud infrastructure.
---
Clone the `infctl` repo if you have not yet done so. We will work on the assumption that we are working in a home directory called `projects`.
```bash
cd ~/projects
if [ ! -d "infctl-cli" ]; then
git clone https://codeberg.org/headshed/infctl-cli
cd infctl-cli
else
cd infctl-cli
fi
```
we need to configure some environment variables to let our build know some things about our project.
```bash
cp .env.gcloud-example .env
```
edit our newly created `.env` file and give it values that are appropriate to our gcloud account, for example:
```
PROJECT_NAME="my-very-own-dev-lab"
EMAIL="your.email@mailsomewhere.com"
APP_DOMAIN_NAME="atestdr.yourdomain.com"
```
where each of these variables represent:
* your project name, often called the project id in gcloud
* your email that you wish to be identified with for DNS and TLS encryption
* the domain name you want to use for this project when it is on line
Activate these in the current shell with:
```bash
source .env
```
Before we go any further, we need to confirm we have our gcloud environment ready and configured:
```bash
gcloud compute instances list --project="$PROJECT_NAME" \
&& gcloud compute disks list --project="$PROJECT_NAME" \
&& gcloud compute firewall-rules list --project="$PROJECT_NAME" \
&& gcloud storage buckets list --project="$PROJECT_NAME"
```
We should see pretty much an empty list but for default rules assigned for us by Google to our project to accept SSH, RDP and ICMP traffic - 4 lines in all.
To build the infrastructure :
```bash
LOG_FORMAT=none infctl -f gcloud/tf/scripts/build-gcloud-k3s-pipeline.json
```
You should see a successful build ending with something like:
```bash
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
k3s_vm_public_ip = "xxx.xxx.xxx.xxx"
project_number = "..233434.."
✅ Step completed: run tofu
✅ 🚀 Pipeline completed successfully
```
Take a note of public IP address assigned to your VM as in `xxx.xxx.xxx.xxx` in the above example.
You need to create an `A record` in your DNS console to point to this address, using the environment name you set for your app earlier
```bash
echo $APP_DOMAIN_NAME
<whatever you set your application full domain name to>
```
### Setting an A Record in your chosen or Cloudflare DNS
If you are using Cloudflare DNS, you can follow the below or use as a guide for your chosen DNS console...
1. Log in to your Cloudflare dashboard.
2. Select your domain.
3. Go to the **DNS** tab.
4. Click **Add record**.
5. Choose **A** as the record type.
6. Enter your subdomain (e.g., `atestdr`) in the **Name** field.
7. Enter your VM's public IP address in the **IPv4 address** field.
8. Set the record to be DNS only and a low TTL, for example 5 min.
9. Click **Save**.
Your domain should now point to your VM's public IP.

View file

@ -0,0 +1,57 @@
---
title: Smoke test the cluster
description: A guide to smoke testing our gcloud infrastructure.
---
# Smoke test the cluster
from our git repo directory that we checked out in [create gcloud earlier](/guides/3-gcloud/020-create-gcloud-infra/)
```bash
source .env
gcloud compute ssh k3s-vm-1 --zone=us-central1-a --project=$PROJECT_NAME
```
We should be shelled into our vm.
```bash
user@k3s-vm-1:~$ k version
Client Version: v1.32.8+k3s1
Kustomize Version: v5.5.0
Server Version: v1.32.8+k3s1
```
Kubectl is giving us a version
```bash
user@k3s-vm-1:~$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
k3s-vm-1 Ready control-plane,etcd,master 7m41s v1.32.8+k3s1
```
`kubectl` which is also aliased to `k` ( we can use either ) is telling us we have a single node k3s node.
```bash
k get events -A
....
kube-system 8m53s Normal ApplyingManifest addon/runtimes Applying manifest at "/var/lib/rancher/k3s/server/manifests/runtimes.yaml"
kube-system 8m53s Normal AppliedManifest addon/runtimes Applied manifest at "/var/lib/rancher/k3s/server/manifests/runtimes.yaml"
kube-system 8m52s Normal DeletingManifest addon/traefik Deleting manifest at "/var/lib/rancher/k3s/server/manifests/traefik.yaml"
```
There should be a bunch of events - the cluster just started up, and no alarming warnings or errors are present.
We should have pods running:
```bash
user@k3s-vm-1:~$ k get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-64fd4b4794-gt5mp 1/1 Running 0 11m
kube-system local-path-provisioner-774c6665dc-h5xws 1/1 Running 0 11m
kube-system metrics-server-7bfffcd44-tfwnw 1/1 Running 0 11m
```
Not many, this is true but k3s is lightweight. This is good.
Ok, so we have a functioning single node k3s, next we can install an application that can use our Domain name we configured earlier, using [forgejo](https://forgejo.org/), a code forge application, much like github, gitlab but self-hosted and efficient.

View file

@ -0,0 +1,118 @@
---
title: Install Forgejo
description: A guide to installing forgejo to our cluster.
---
From our host system, in another shell and from the location of the `infctl-cli` git repo, we need to copy our `.env` file to the gcloud vm:
```bash
gcloud compute scp .env k3s-vm-1:/opt/src/infctl-cli/.env --zone=us-central1-a --project=$PROJECT_NAME
```
From a shell into our cluster from [earlier](/guides/3-gcloud/030-smoke-test-cluster/) or by reconnecting with
```bash
gcloud compute ssh k3s-vm-1 --zone=us-central1-a --project=$PROJECT_NAME
```
Change directory to `/opt/src/infctl-cli/` and `source` the '.env' file that was just copied
```bash
cd /opt/src/infctl-cli/
source .env
```
From here we can run a pipeline to install foregejo:
```bash
LOG_FORMAT=none infctl -f gcloud/tf/scripts/install-forgejo-pipeline.json
```
if the pipeline completes successfully we can test to see if the site is responding with
```bash
curl -k $APP_DOMAIN_NAME
```
we should see an HTML page returned to us from foregejo.
This should work also from our host or anywhere that is internet connected.
NB: the use of `-k` in the curl request: this is to tell `curl` to ignore TLS certificates that are not fully signed.
In the manifests used to install forgejo, this was intentionally set to use a staging service with LetsEncrypt:
```bash
user@k3s-vm-1:/opt/src/infctl-cli$ cat gcloud/tf/k3s/forgejo/issuer.yaml
```
...
```yaml
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: le-cluster-issuer-http
namespace: forgejo
spec:
acme:
email: marshyon@gmail.com
# We use the staging server here for testing to avoid throttling.
server: https://acme-staging-v02.api.letsencrypt.org/directory
# server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: http-issuer-account-key
solvers:
- http01:
ingress:
class: traefik
```
you can see that this has worked also by running
```bash
printf "Q" | openssl s_client -connect "$APP_DOMAIN_NAME":443 -servername "$APP_DOMAIN_NAME" -showcerts
```
Look for the section that looks like this:
```
depth=1 C = US, O = (STAGING) Let's Encrypt, CN = (STAGING) Tenuous Tomato R13
```
This certificate will not be trusted by Chrome or other modern browsers, so, to bypass this and to complete our tests, we can download a certificate root file from LetsEncrypt and install this into our browser.
Step 1: Download the Staging Root Certificate
The specific certificate you need is the "Let's Encrypt Staging Root X1". Here is the direct link to download the file from the official Let's Encrypt website:
Direct Download Link: https://letsencrypt.org/certs/staging/letsencrypt-stg-root-x1.pem
download this letsencrypt-stg-root-x1.pem file and save it to your computer.
Step 2: Import the Certificate into Your Browser
For security reasons, it is highly recommended to do this in a new, separate browser profile that you only use for testing.
For Google Chrome:
1. Create a New Test Profile:
1. Click your profile picture in the top-right of Chrome.
1. Click Add > Continue without an account.
1. Give the profile a name like "Staging Test" and click Done. A new Chrome window will open using this profile.
1. Open Certificate Settings:
1. In this new profile window, go to Settings > Privacy and security > Security.
1. Scroll down and click on Manage device certificates.
1. Import the Certificate:
1. Click the Authorities tab.
1. Click the Import... button.
1. Select the letsencrypt-stg-root-x1.pem file you downloaded earlier.
1. In the pop-up window, check the box for "Trust this certificate for identifying websites."
1. Click OK.
Test:
Close and reopen the "Staging Test" profile Chrome window.
Navigate to your site. It should load correctly with a padlock icon, without any security warnings.

View file

@ -0,0 +1,43 @@
---
title: Shut down and clean up
description: A guide to destroying unwanted infrastructure
---
## Clean up (destroy) the infrastructure
Now we no longer have use for the test infrastructure it is time to clear it down to save hosting costs.
From our host machine and within the `infctl-cli` repository we have checked out:
```bash
cd gcloud/tf
tofu destroy
```
this will ask us if we want to proceed:
```bash
Plan: 0 to add, 0 to change, 5 to destroy.
...
Do you really want to destroy all resources?
OpenTofu will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value:
```
Enter `yes` and press return.
this should compete with
```bash
......
Google_compute_disk.app_data_disk: Destruction complete after 2s
Destroy complete! Resources: 5 destroyed.
```
No further costs will be incurred on your Google Cloud account for this test infrastructure and you can rebuild whenever you need to run further tests or carry out disaster recovery rehearsals.

View file

@ -1,6 +1,6 @@
---
title: Welcome to Minimal Viable Kubernetes
description: Get started building your docs site with Starlight.
description: MVK is a fast path method to stand up and stage K8s infrastructures.
template: splash
hero:
tagline: Tools and patterns to deliver self hosted, minimal, viable k8s!
@ -8,7 +8,7 @@ hero:
file: ../../assets/mvk.png
actions:
- text: MVK Guide
link: /mvk/intro/
link: /mvk/1-introduction/goals-limitation-design-use-cases/
icon: right-arrow
- text: infctl and mvk source
link: https://codeberg.org/headshed/infctl-cli

View file

@ -1,17 +1,29 @@
---
title: MVK Introduction
title: Goals, Limitations, Design, Use Cases
description: introducing minimal viable Kubernetes and its guiding principles
---
Kubernetes is complicated
## Goals
Additionally, K8s is designed with cloud in mind.
Minimal Viable Kubernetes has the following goals:
Thus, self hosting options can be limiting.
* CLI friendly and first
* Promotes Infrastructure as Code
* Portablity across cloud and on-prem
* Openness and keeping it simple
* Avoid proprietary lock in
Kubernetes is complicated.
K8s is designed with cloud in mind.
Self hosted options can be limiting.
## Limitations
Out of the box, Kubernetes expects key components of infrastructure to be present. For example, ingress, storage and load balancers.
MVK addresses the limitations of Kubernetes 'out of the box' for self-hosted implementation.
On its own, Kubernetes expects key components of infrastructure to be present. For example, ingress, storage and load balancers.
If any of these are not present, they will need to be supplied in a form that Kubernetes can consume them.
@ -39,7 +51,7 @@ It can also reduce costs, provided that its users are already, or become, famili
A greater understanding of k8s results in us all becoming less reliant on others providing this as a service for us. It protects our industry from losing these skills entirely.
**Above all it can gain control over our own digital sovereignty.**
**MVK can help give us control of our digital sovereignty.**

View file

@ -0,0 +1,21 @@
---
title: Quick Start
description: A guide to setting up MVK quickly.
---
`infctl` is a command line tool used by MVK to orchestrate code.
It makes scripted infrastructure as code simpler and easier to run, manage and support.
You can think of it as a 'simpler pipeline'.
Install `infctl` command line tool with
```bash
curl -L https://codeberg.org/headshed/infctl-cli/raw/branch/main/install.sh | bash
```
Alternatively, go to [Releases](https://codeberg.org/headshed/infctl-cli/releases) to find a current version for your Operating System, download it and place a copy in your `PATH`.

View file

@ -0,0 +1,54 @@
---
title: Configuration
description: infctl configuration
---
`infctl` uses `json` files for configuration.
It is designed around the idea of pipelines where each pipeline performs a series of steps.
A short, 2 step pipeline configuration can look like :
```json
[
{
"name": "ensure inf namespace exists",
"function": "k8sNamespaceExists",
"params": ["infctl"],
"retryCount": 0,
"shouldAbort": true
},
{
"name": "create php configmap",
"function": "RunCommand",
"params": ["./scripts/create_php_configmap_ctl.sh"],
"retryCount": 0,
"shouldAbort": true
}
]
```
Each Object is a task.
Object task records are executed in a `[]` list and in sequence.
Each task has a `name` to be displayed in logs.
Each task calls a `Function` that is registered within `infctl` and that accepts `params` string, which are any parameters to be passed to that function, script or executable. The simplest example being `RunCommand` which accepts the path to a script or executable as its `params`. This can be anything but can be as simple as :
```bash
echo "hello world"
exit 0
```
So `infctl` is unlimited as to what it can use in its pipeline files to achieve any kind of automation.
If a task fails ( the script or program that is run returns a non zero value ) it may be re-tried up to `retryCount` times.
If a task fails the pipeline will stop running unless `shouldAbort` is set to false, in which case, the pipeline will continue to run with the next step item in the list.

View file

@ -0,0 +1,29 @@
---
title: Pre-Requisites
description: A guide to creating a single Gcloud MVK node.
---
we need to run this at least once to ensure we have tooling available ...
```bash
cd ${PATH_TO_infctl-cli}/infctl-cli # where we checked out infct-cli to
./gcloud/tf/scripts/pre-flight-checks.sh
```
```
✅ tofu is installed,...
✅ gcloud is installed,...
✅ kubectl is installed,...
✅ envsubst is installed,...
# .....
✅ Pre-flight checks passed. You are ready to proceed 🙂
```
hopefully, we have no errors.
Follow instructions to install any missing dependencies.

View file

@ -0,0 +1,13 @@
---
title: Configure
description: A guide to creating a single Gcloud MVK node.
---
```bash
[ -f .env ] || cp -v .env.gcloud-example .env
# edit to include
export PROJECT_NAME="the name of your gcp project, often referred to as the project"
export EMAIL="your email address to identify yourself with letsencrypt"
export APP_DOMAIN_NAME="your domain name for the app, e.g., frgdr.some-domain.com"
export INSTALL_FORGEJO="true"
```

View file

@ -0,0 +1,14 @@
---
title: Run
description: A guide to creating a single Gcloud MVK node.
---
```bash
# RUN
LOG_FORMAT=none infctl -f ./gcloud/tf/scripts/build-gcloud-k3s-pipeline-wait-dns.json
```
At the end of the pipeline we will see an ip address displayed of the VM instance the terraform has created.
You will need to edit an A-record in your DNS to point your $APP_DOMAIN_NAME

View file

@ -0,0 +1,31 @@
---
title: Pre-Requisites
description: A guide to creating a single Gcloud MVK node.
---
### 👷 coming soon ...
we need to run this at least once to ensure we have tooling available ...
```bash
cd ${PATH_TO_infctl-cli}/infctl-cli # where we checked out infct-cli to
./gcloud/tf/scripts/pre-flight-checks.sh
```
```
✅ tofu is installed,...
✅ gcloud is installed,...
✅ kubectl is installed,...
✅ envsubst is installed,...
# .....
✅ Pre-flight checks passed. You are ready to proceed 🙂
```
hopefully, we have no errors.
Follow instructions to install any missing dependencies.

View file

@ -0,0 +1,15 @@
---
title: Configure
description: A guide to creating a single Gcloud MVK node.
---
### 👷 coming soon ...
```bash
[ -f .env ] || cp -v .env.gcloud-example .env
# edit to include
export PROJECT_NAME="the name of your gcp project, often referred to as the project"
export EMAIL="your email address to identify yourself with letsencrypt"
export APP_DOMAIN_NAME="your domain name for the app, e.g., frgdr.some-domain.com"
export INSTALL_FORGEJO="true"
```

View file

@ -0,0 +1,6 @@
---
title: Run
description: A guide to creating a single Gcloud MVK node.
---
### 👷 coming soon ...