--- # Namespace (trust zone; default-deny + policies apply) apiVersion: v1 kind: Namespace metadata: name: vm-demo labels: homelab.keithjackson.dev/app-namespace: 'true' annotations: homelab.keithjackson.dev/backup-policy: daily-offcluster --- # Default-deny baseline (R-NET-01): deny all, allow only DNS apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny namespace: vm-demo labels: homelab.keithjackson.dev/baseline: default-deny spec: podSelector: {} policyTypes: - Ingress - Egress ingress: [] egress: - to: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: kube-system ports: - protocol: UDP port: 53 - protocol: TCP port: 53 --- # CDI DataVolume (standalone; survives rebuild, R-STATE-01) apiVersion: cdi.kubevirt.io/v1beta1 kind: DataVolume metadata: name: vm-demo-rootdisk namespace: vm-demo spec: source: registry: url: docker://quay.io/containerdisks/fedora:41 storage: accessModes: - ReadWriteOnce storageClassName: longhorn resources: requests: storage: 6Gi --- # KubeVirt VirtualMachine (R-PLAT-03) apiVersion: kubevirt.io/v1 kind: VirtualMachine metadata: name: vm-demo namespace: vm-demo labels: app.kubernetes.io/name: vm-demo spec: running: false template: metadata: labels: kubevirt.io/vm: vm-demo homelab.keithjackson.dev/egress-class: internet homelab.keithjackson.dev/auth-mode: none spec: domain: cpu: cores: 1 memory: guest: 1536Mi devices: disks: - name: rootdisk disk: bus: virtio - name: cloudinit disk: bus: virtio interfaces: - name: default masquerade: {} resources: requests: memory: 1536Mi networks: - name: default pod: {} volumes: - name: rootdisk dataVolume: name: vm-demo-rootdisk - name: cloudinit cloudInitNoCloud: userData: "#cloud-config\npackage_update: true\npackages:\n - dnf-automatic\nwrite_files:\n - path: /etc/dnf/automatic.conf\n content: |\n [commands]\n upgrade_type = default\n random_sleep = 0\n download_updates = yes\n apply_updates = yes\nruncmd:\n - [ systemctl, enable, --now, dnf-automatic.timer ]\n" --- # CiliumNetworkPolicy world egress allow (egress class governs the path; R-NET-05): vm-demo-allow-internet-egress apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: name: vm-demo-allow-internet-egress namespace: vm-demo labels: app.kubernetes.io/name: vm-demo spec: endpointSelector: matchLabels: app.kubernetes.io/name: vm-demo egress: - toEntities: - world --- # ServiceMonitor (R-OBS-01) apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: vm-demo namespace: vm-demo labels: release: kube-prometheus-stack app.kubernetes.io/name: vm-demo spec: selector: matchLabels: app.kubernetes.io/name: vm-demo namespaceSelector: matchNames: - vm-demo endpoints: - port: metrics interval: 30s --- # PrometheusRule SLI alerts (R-OBS-01) apiVersion: monitoring.coreos.com/v1 kind: PrometheusRule metadata: name: vm-demo-slis namespace: vm-demo labels: release: kube-prometheus-stack app.kubernetes.io/name: vm-demo spec: groups: - name: vm-demo.slis rules: - alert: vm-demo-down expr: up{job="vm-demo"} == 0 for: 5m labels: severity: critical service: vm-demo annotations: summary: vm-demo is down description: 'vm-demo has been unreachable for 5m (SLI: up).'