Some time ago I’ve written a small blog about how to get openSUSE Leap Micro 6 up and running. As one of the use cases for this distributions is to run container workloads, the next natural step is to deploy a containerized workload. As I am mostly interested in PostgreSQL and it becomes more and more popular to run PostgreSQL in Kubernetes, I’ll use minicube to easily get a local Kubernetes cluster and CloudNativePG to get an operator for managing PostgreSQL.
If you want to replay that, just follow the initial post linked above, which gives you this:
micro-minicube:~ $ cat /etc/os-release
NAME="openSUSE Leap Micro"
VERSION="6.0"
ID="opensuse-leap-micro"
ID_LIKE="suse opensuse opensuse-leap suse-microos"
VERSION_ID="6.0"
PRETTY_NAME="openSUSE Leap Micro 6.0"
ANSI_COLOR="0;32"
CPE_NAME="cpe:/o:opensuse:leap-micro:6.0"
BUG_REPORT_URL="https://bugs.opensuse.org"
HOME_URL="https://www.opensuse.org/"
DOCUMENTATION_URL="https://en.opensuse.org/Portal:LeapMicro"
LOGO="distributor-logo-LeapMicro"
From there you need to install minicube, which is really, really easy to do. As minicube should not run under “root”, create a dedicated user for it and configure sudo:
micro-minicube:~ $ groupadd minicube
micro-minicube:~ $ useradd -g minicube -m -s /bin/bash minicube
micro-minicube:~ $ echo "minicube ALL=(ALL:ALL) NOPASSWD: ALL" > /etc/sudoers.d/minicube
micro-minicube:~ $ su - minicube
minicube@micro-minicube:~> sudo ls
bin
minicube@micro-minicube:~>
Once you have that, it is time to install minicube:
minicube@micro-minicube:~> curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 91.1M 100 91.1M 0 0 14.2M 0 0:00:06 0:00:06 --:--:-- 17.1M
minicube@micro-minicube:~> sudo install minikube-linux-amd64 /usr/local/bin/minikube && rm minikube-linux-amd64
minicube@micro-minicube:~> ls -l /usr/local/bin/minikube
-rwxr-xr-x. 1 root root 95595640 Jun 6 09:07 /usr/local/bin/minikube
That’s it. Start it up:
minicube@micro-minicube:~> minikube start
😄 minikube v1.33.1 on Opensuse-Leap-Micro 6.0 (kvm/amd64)
✨ Automatically selected the podman driver
🧯 The requested memory allocation of 1972MiB does not leave room for system overhead (total system memory: 1972MiB). You may face stability issues.
💡 Suggestion: Start minikube with less memory allocated: 'minikube start --memory=1972mb'
📌 Using Podman driver with root privileges
👍 Starting "minikube" primary control-plane node in "minikube" cluster
🚜 Pulling base image v0.0.44 ...
💾 Downloading Kubernetes v1.30.0 preload ...
> preloaded-images-k8s-v18-v1...: 342.90 MiB / 342.90 MiB 100.00% 11.58 M
> gcr.io/k8s-minikube/kicbase...: 481.58 MiB / 481.58 MiB 100.00% 8.70 Mi
E0606 09:09:02.427139 3928 cache.go:189] Error downloading kic artifacts: not yet implemented, see issue #8426
🔥 Creating podman container (CPUs=2, Memory=1972MB) ...
🐳 Preparing Kubernetes v1.30.0 on Docker 26.1.1 ...
▪ Generating certificates and keys ...
▪ Booting up control plane ...
▪ Configuring RBAC rules ...
🔗 Configuring bridge CNI (Container Networking Interface) ...
🔎 Verifying Kubernetes components...
▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
🌟 Enabled addons: storage-provisioner, default-storageclass
💡 kubectl not found. If you need it, try: 'minikube kubectl -- get pods -A'
🏄 Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
… install kubctl or use the one from minicube (what I am doing here). I’ll also define an alias (this is from the offical minicube documentation linked above) to save some typing:
minicube@micro-minicube:~> minikube kubectl -- get po -A
> kubectl.sha256: 64 B / 64 B [-------------------------] 100.00% ? p/s 0s
> kubectl: 49.07 MiB / 49.07 MiB [-------------] 100.00% 7.37 MiB p/s 6.9s
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-7db6d8ff4d-bwr6n 1/1 Running 0 3m43s
kube-system etcd-minikube 1/1 Running 0 3m57s
kube-system kube-apiserver-minikube 1/1 Running 0 3m57s
kube-system kube-controller-manager-minikube 1/1 Running 0 3m57s
kube-system kube-proxy-wl74w 1/1 Running 0 3m44s
kube-system kube-scheduler-minikube 1/1 Running 0 3m57s
kube-system storage-provisioner 1/1 Running 0 3m56s
minicube@micro-minicube:~> echo "alias kubectl=\"minikube kubectl --\"" >> ~/.bashrc
minicube@micro-minicube:~> . .bashrc
minicube@micro-minicube:~> kubectl get po -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-7db6d8ff4d-bwr6n 1/1 Running 0 5m
kube-system etcd-minikube 1/1 Running 0 5m14s
kube-system kube-apiserver-minikube 1/1 Running 0 5m14s
kube-system kube-controller-manager-minikube 1/1 Running 0 5m14s
kube-system kube-proxy-wl74w 1/1 Running 0 5m1s
kube-system kube-scheduler-minikube 1/1 Running 0 5m14s
kube-system storage-provisioner 1/1 Running 0 5m13s
As the local Kubernetes is now up and running, CloudNativePG can be deployed on it (check for the most recent version, before you do this):
minicube@micro-minicube:~> kubectl apply --server-side -f https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-1.23/releases/cnpg-1.23.1.yaml
namespace/cnpg-system serverside-applied
customresourcedefinition.apiextensions.k8s.io/backups.postgresql.cnpg.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/clusterimagecatalogs.postgresql.cnpg.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/clusters.postgresql.cnpg.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/imagecatalogs.postgresql.cnpg.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/poolers.postgresql.cnpg.io serverside-applied
customresourcedefinition.apiextensions.k8s.io/scheduledbackups.postgresql.cnpg.io serverside-applied
serviceaccount/cnpg-manager serverside-applied
clusterrole.rbac.authorization.k8s.io/cnpg-manager serverside-applied
clusterrolebinding.rbac.authorization.k8s.io/cnpg-manager-rolebinding serverside-applied
configmap/cnpg-default-monitoring serverside-applied
service/cnpg-webhook-service serverside-applied
deployment.apps/cnpg-controller-manager serverside-applied
mutatingwebhookconfiguration.admissionregistration.k8s.io/cnpg-mutating-webhook-configuration serverside-applied
validatingwebhookconfiguration.admissionregistration.k8s.io/cnpg-validating-webhook-configuration serverside-applied
minicube@micro-minicube:~> kubectl get deployment -n cnpg-system cnpg-controller-manager
NAME READY UP-TO-DATE AVAILABLE AGE
cnpg-controller-manager 1/1 1 1 30s
Before you can deploy PostgreSQL, you’ll need to describe your desired cluster. A very minimal definition is this (this comes from the official documentation as well):
minicube@micro-minicube:~> cat pg.yaml
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: cluster-example
spec:
instances: 3
storage:
size: 1Gi
Deploy (or apply) it:
minicube@micro-minicube:~> kubectl apply -f pg.yaml
cluster.postgresql.cnpg.io/cluster-example created
… and monitor the creation of the pods until the cluster is finally ready:
minicube@micro-minicube:~> kubectl get pods
NAME READY STATUS RESTARTS AGE
cluster-example-1-initdb-wtl27 0/1 PodInitializing 0 20s
minicube@micro-minicube:~> kubectl get pods
NAME READY STATUS RESTARTS AGE
cluster-example-1 0/1 Running 0 5s
cluster-example-1-initdb-wtl27 0/1 Completed 0 30s
minicube@micro-minicube:~> kubectl get pods
NAME READY STATUS RESTARTS AGE
cluster-example-1 1/1 Running 0 12s
cluster-example-1-initdb-wtl27 0/1 Completed 0 37s
cluster-example-2-join-92rqp 0/1 Pending 0 1s
minicube@micro-minicube:~> kubectl get pods
NAME READY STATUS RESTARTS AGE
cluster-example-1 1/1 Running 0 22s
cluster-example-1-initdb-wtl27 0/1 Completed 0 47s
cluster-example-2 0/1 Running 0 3s
cluster-example-2-join-92rqp 0/1 Completed 0 11s
minicube@micro-minicube:~> kubectl get pods
NAME READY STATUS RESTARTS AGE
cluster-example-1 1/1 Running 0 33s
cluster-example-1-initdb-wtl27 0/1 Completed 0 58s
cluster-example-2 1/1 Running 0 14s
cluster-example-2-join-92rqp 0/1 Completed 0 22s
cluster-example-3-join-rx8g6 0/1 Init:0/1 0 3s
minicube@micro-minicube:~> kubectl get pods
NAME READY STATUS RESTARTS AGE
cluster-example-1 1/1 Running 0 46s
cluster-example-1-initdb-wtl27 0/1 Completed 0 71s
cluster-example-2 1/1 Running 0 27s
cluster-example-2-join-92rqp 0/1 Completed 0 35s
cluster-example-3 0/1 Running 0 9s
cluster-example-3-join-rx8g6 0/1 Completed 0 16s
minicube@micro-minicube:~> kubectl get pods
NAME READY STATUS RESTARTS AGE
cluster-example-1 1/1 Running 0 62s
cluster-example-2 1/1 Running 0 43s
cluster-example-3 1/1 Running 0 25s
All the nodes (as described in the yaml definition above) are up and running, which you also may verify by looking at the services:
minicube@micro-minicube:~> kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
cluster-example-r ClusterIP 10.96.171.131 <none> 5432/TCP 3m41s
cluster-example-ro ClusterIP 10.106.134.232 <none> 5432/TCP 3m41s
cluster-example-rw ClusterIP 10.108.169.108 <none> 5432/TCP 3m41s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 21m
Happy testing.