Configuration Templates¶
Ready-to-use configuration examples.
Platform Values¶
These overlays follow the kmetal-chart values shape — see Helm Values Reference for the full key list.
Lab / development:
network:
kubeOvn:
tunnelInterface: "data.205"
metallb:
pools:
- name: default-pool
addresses:
- 192.168.100.10-192.168.100.20
l2Advertisements:
- name: default-l2-adv
ipAddressPools:
- default-pool
kamaji:
replicas: 1
Production:
network:
kubeOvn:
tunnelInterface: "bond1.516"
metallb:
pools:
- name: default-pool
addresses:
- 10.10.20.100-10.10.20.200
l2Advertisements:
- name: default-l2-adv
ipAddressPools:
- default-pool
kamaji:
replicas: 2
# Sub-chart override block: harden Kamaji controller
kamaji:
nodeSelector:
node-role.kubernetes.io/control-plane: ""
resources:
requests: { cpu: "1", memory: 512Mi }
limits: { cpu: "2", memory: 1Gi }
# Sub-chart override block: harden cert-manager
cert-manager:
nodeSelector:
node-role.kubernetes.io/control-plane: ""
cainjector:
nodeSelector:
node-role.kubernetes.io/control-plane: ""
webhook:
nodeSelector:
node-role.kubernetes.io/control-plane: ""
startupapicheck:
nodeSelector:
node-role.kubernetes.io/control-plane: ""
Tenant Clusters¶
Tenants are created as CAPI Cluster resources referencing kMetal's kubevirt-kubeadm ClusterClass. The control plane (Kamaji KamajiControlPlane/TenantControlPlane) and infrastructure (CAPK KubevirtCluster) are auto-created from the topology.
Basic (single-replica control plane):
apiVersion: cluster.x-k8s.io/v1beta2
kind: Cluster
metadata:
name: basic-tenant
namespace: <tenant-namespace>
spec:
clusterNetwork:
pods:
cidrBlocks: ["10.200.0.0/16"]
services:
cidrBlocks: ["10.201.0.0/16"]
topology:
classRef:
name: kubevirt-kubeadm
namespace: kmetal-capi-providers
version: v1.34.1
variables:
- name: controlPlane
value:
dataStoreName: default
network:
serviceAddress: <metallb-vip>
serviceType: LoadBalancer
certSANs: [<public-fqdn-or-ip>]
- name: machineSize
value: small
- name: bootstrapConfig
value:
serverAddress: <bootstrap-server>
- name: network
value:
subnet: <ovn-subnet-name>
workers:
machineDeployments:
- class: default-worker
name: md-0
replicas: 1
Production (HA control plane, multiple workers):
apiVersion: cluster.x-k8s.io/v1beta2
kind: Cluster
metadata:
name: ha-tenant
namespace: <tenant-namespace>
labels:
environment: production
spec:
clusterNetwork:
pods:
cidrBlocks: ["10.200.0.0/16"]
services:
cidrBlocks: ["10.201.0.0/16"]
topology:
classRef:
name: kubevirt-kubeadm
namespace: kmetal-capi-providers
version: v1.34.1
variables:
- name: controlPlane
value:
dataStoreName: default
network:
serviceAddress: <metallb-vip>
serviceType: LoadBalancer
certSANs: [<public-fqdn-or-ip>]
- name: machineSize
value: medium
- name: bootstrapConfig
value:
serverAddress: <bootstrap-server>
- name: network
value:
subnet: <ovn-subnet-name>
workers:
machineDeployments:
- class: default-worker
name: md-0
replicas: 3
Applications¶
Stateless:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 3
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web
image: nginx:1.24
ports:
- containerPort: 80
resources:
requests: { cpu: 100m, memory: 128Mi }
limits: { cpu: 500m, memory: 512Mi }
---
apiVersion: v1
kind: Service
metadata:
name: web-app
spec:
selector:
app: web-app
ports:
- port: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-app
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
ingressClassName: haproxy
tls:
- hosts:
- app.company.com
secretName: web-app-tls
rules:
- host: app.company.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-app
port:
number: 80
Stateful:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: database
spec:
serviceName: database
replicas: 3
selector:
matchLabels:
app: database
template:
metadata:
labels:
app: database
spec:
containers:
- name: postgres
image: postgres:15
env:
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: postgres-creds
key: password
ports:
- containerPort: 5432
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "" # Replace with your platform's StorageClass
resources:
requests:
storage: 20Gi
Security¶
Network Policy:
# Default deny
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
---
# Allow ingress
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress
spec:
podSelector:
matchLabels:
app: web-app
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector: {} # Restrict to your tenant cluster's ingress controller namespace
ports:
- protocol: TCP
port: 80