Skip to content

Feature: Select Metal3DataTemplate per Failure Domain for KCP #2716

@shibaPuppy

Description

@shibaPuppy

User Story
KCP spreads control plane Machines across failure domains via Machine.spec.failureDomain.

CAPM3’s Metal3MachineTemplate (M3MT) today references a single dataTemplate, so every control-plane node uses the same network definition/IP source even across different FDs.

In bare metal, FDs often have distinct L2/L3 (bonding + VLAN like bond1.11, different gateways/subnets). Operators want FD-specific IPPools and network configs.

Goal: When KCP sets Machine.spec.failureDomain, CAPM3 automatically selects a per-FD Metal3DataTemplate (thus the right IPPools) without splitting KCP.

Detailed Description

  • Allow a single KCP to apply different network definitions per FD.
  • Support bonding + VLAN (e.g., bond1.11, bond1.12) and FD-specific IPPools via Metal3DataTemplate.
  • Maintain backward compatibility: existing single dataTemplate flows must keep working unchanged.

Proposed Design
Option: Add an FD→DataTemplate map to Metal3MachineTemplate

Add a new, optional map so CAPM3 can pick a Metal3DataTemplate by failure domain. If no match, fall back to the existing dataTemplate.

apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3MachineTemplate
metadata:
  name: my-cluster-controlplane
  namespace: metal3
spec:
  template:
    spec:
      # Existing default (unchanged)
      dataTemplate:
        name: cp-net-default
        namespace: metal3

      # NEW: optional, per-FD mapping
      dataTemplatesByFailureDomain:
        az-a:
          name: cp-net-az-a
          namespace: metal3
        az-b:
          name: cp-net-az-b
          namespace: metal3

Controller behavior

  1. before creating Metal3DataClaim, read Machine.spec.failureDomain.
  2. if a matching key exists in dataTemplatesByFailureDomain, use that Metal3DataTemplate.
  3. otherwise, use the default spec.template.spec.dataTemplate (legacy behavior).
  • az-a datatemplate sample
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3DataTemplate
metadata:
  name: cp-net-az-a
  namespace: metal3
spec:
  template:
    networkData:
      links:
        ethernets:
          - id: nic0
            type: phy
            macAddress: { fromHostInterface: eno1 }
          - id: nic1
            type: phy
            macAddress: { fromHostInterface: eno2 }
        bonds:
          - id: bond1
            type: bond
            interfaces: ["nic0","nic1"]
            bondMode: "802.3ad"
            bondMiimon: 100
            bondLACPRate: "fast"
            bondXmitHashPolicy: "layer3+4"
        vlans:
          - id: bond1.11
            type: vlan
            link: bond1
            vlanID: 11
            mtu: 9000
          - id: bond1.12
            type: vlan
            link: bond1
            vlanID: 12
      networks:
        ipv4:
          - id: mgmt-a
            link: bond1.11
            ipAddressFromIPPool: mgmt-az-a-pool
            routes:
              - to: 0.0.0.0/0
                via: 192.168.11.1
          - id: storage-a
            link: bond1.12
            ipAddressFromIPPool: storage-az-a-pool
  • az-b datatemplate sample
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: Metal3DataTemplate
metadata:
  name: cp-net-az-b
  namespace: metal3
spec:
  template:
    networkData:
      # (links/bonding identical; adjust as needed)
      vlans:
        - id: bond1.21
          type: vlan
          link: bond1
          vlanID: 21
          mtu: 9000
        - id: bond1.22
          type: vlan
          link: bond1
          vlanID: 22
      networks:
        ipv4:
          - id: mgmt-b
            link: bond1.21
            ipAddressFromIPPool: mgmt-az-b-pool
            routes:
              - to: 0.0.0.0/0
                via: 192.168.21.1
          - id: storage-b
            link: bond1.22
            ipAddressFromIPPool: storage-az-b-pool

Anything else you would like to add:
I've been thinking about the functionality of a failure domain.
I think the 1:1 datatemplate mapping in KCP is problematic, and I think a new structure that can support 1:N mapping is needed.
please let me know if I'm wrong.

/kind feature

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/featureCategorizes issue or PR as related to a new feature.lifecycle/staleDenotes an issue or PR has remained open with no activity and has become stale.triage/acceptedIndicates an issue is ready to be actively worked on.

    Projects

    Status

    CAPM3 WIP

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions