Skip to content

✨ Support VLAN sub-interface configuration for supervisor VSphereMachine#3956

Draft
shutingm-kubernetes wants to merge 3 commits intokubernetes-sigs:mainfrom
shutingm-kubernetes:topic/shutingm/vlan-subinterface
Draft

✨ Support VLAN sub-interface configuration for supervisor VSphereMachine#3956
shutingm-kubernetes wants to merge 3 commits intokubernetes-sigs:mainfrom
shutingm-kubernetes:topic/shutingm/vlan-subinterface

Conversation

@shutingm-kubernetes
Copy link
Copy Markdown

@shutingm-kubernetes shutingm-kubernetes commented Apr 21, 2026

What this PR does / why we need it:
This PR introduces a feature of VLAN Subinterface for supervisor based VSphereMachine, users can create VLAN sub-interfaces on top of secondary network interfaces. The actual VLAN sub-interface configuration is delegated to vm-operator via the VirtualMachine.spec.network.vlans field in the v1alpha6 schema.

User-facing API changes

  • New optional field spec.network.vlans on VSphereMachine/VSphereMachineTemplate (both v1beta1 and v1beta2 API):
    • name — VLAN sub-interface name inside the guest OS, Required
    • id — VLAN ID, an integer in [0, 4094], Required
    • link — name of the secondary interface this VLAN is associated with, Required

Example:

apiVersion: vmware.infrastructure.cluster.x-k8s.io/v1beta2
kind: VSphereMachine
spec:
  network:
    interfaces:
      secondary:
      - name: eth1
        networkRef:
          apiVersion: crd.nsx.vmware.com/v1alpha1
          kind: SubnetSet
          name: trunk-sub
    vlans:     ==============> create 2 vlan sub-interfaces on eth1
    - name: vl100
      id: 100
      link: eth1
    - name: vl200
      id: 200
      link: eth1

Testing Done

Steps:

  1. Apply a workload Cluster whose worker VSphereMachineTemplate defines two secondary interfaces(eth1 and eth2) and four VLANs (id=100/200, both linked to eth1 and eth2).
      network:
        interfaces:
          secondary:
            - name: eth1
              networkRef:
                apiVersion: crd.nsx.vmware.com/v1alpha1
                kind: Subnet
                name: vlan-ext
            - name: eth2
              networkRef:
                apiVersion: crd.nsx.vmware.com/v1alpha1
                kind: Subnet
                name: vlan-ext
        vlans:
          - name: vl100a
            id: 100
            link: eth1
          - name: vl200a
            id: 200
            link: eth1
          - name: vl100b
            id: 100
            link: eth2
          - name: vl200b
            id: 200
            link: eth2

Result:

  1. Created VSphereMachine, it has vlans field as expected:
apiVersion: vmware.infrastructure.cluster.x-k8s.io/v1beta2
kind: VSphereMachine
spec:
  className: best-effort-small
  imageName: vmi-36a17705445f0b65e
  network:
    interfaces:
      secondary:
      - name: eth1
        networkRef:
          apiVersion: crd.nsx.vmware.com/v1alpha1
          kind: Subnet
          name: vlan-ext
      - name: eth2
        networkRef:
          apiVersion: crd.nsx.vmware.com/v1alpha1
          kind: Subnet
          name: vlan-ext
    vlans:
    - id: 100
      link: eth1
      name: vl100a
    - id: 200
      link: eth1
      name: vl200a
    - id: 100
      link: eth2
      name: vl100b
    - id: 200
      link: eth2
      name: vl200b
  powerOffMode: hard
  providerID: vsphere://996145b7-f7ca-4013-ab17-c08fdfbd96e9
  storageClass: wcpglobal-storage-profile
status:
  addresses:
  - address: 172.26.0.35
    type: InternalIP
  biosUUID: 996145b7-f7ca-4013-ab17-c08fdfbd96e9
  conditions:
  - lastTransitionTime: "2026-04-23T03:09:54Z"
    message: ""
    observedGeneration: 2
    reason: Ready
    status: "True"
    type: Ready
  - lastTransitionTime: "2026-04-23T03:09:54Z"
    message: ""
    observedGeneration: 2
    reason: Provisioned
    status: "True"
    type: VirtualMachineProvisioned
  - lastTransitionTime: "2026-04-23T03:08:10Z"
    message: ""
    observedGeneration: 2
    reason: NotPaused
    status: "False"
    type: Paused
  deprecated:
    v1beta1:
      conditions:
      - lastTransitionTime: "2026-04-23T03:09:54Z"
        status: "True"
        type: Ready
      - lastTransitionTime: "2026-04-23T03:09:54Z"
        status: "True"
        type: VMProvisioned
  failureDomain: domain-c10
  initialization:
    provisioned: true
  network:
    interfaces:
    - deviceKey: 4000
      ip:
        addresses:
        - address: 172.26.0.35
          state: preferred
        - address: fe80::650:56ff:fe00:ac00
          state: unknown
        macAddr: 04:50:56:00:ac:00
      name: eth0
    - deviceKey: 4001
      ip:
        addresses:
        - address: 172.26.0.2
          state: preferred
        - address: fe80::650:56ff:fe00:ec00
          state: unknown
        macAddr: 04:50:56:00:ec:00
      name: eth1
    - deviceKey: 4002
      ip:
        addresses:
        - address: 172.26.0.3
          state: preferred
        - address: fe80::650:56ff:fe00:4000
          state: unknown
        macAddr: "04:50:56:00:40:00"
      name: eth2
    - deviceKey: 4001
      ip:
        addresses:
        - address: fe80::650:56ff:fe00:ec00
          state: unknown
        macAddr: 04:50:56:00:ec:00
      name: eth1
    - deviceKey: 4001
      ip:
        addresses:
        - address: fe80::650:56ff:fe00:ec00
          state: unknown
        macAddr: 04:50:56:00:ec:00
      name: eth1
    - deviceKey: 4002
      ip:
        addresses:
        - address: fe80::650:56ff:fe00:4000
          state: unknown
        macAddr: "04:50:56:00:40:00"
      name: eth2
    - deviceKey: 4002
      ip:
        addresses:
        - address: fe80::650:56ff:fe00:4000
          state: unknown
        macAddr: "04:50:56:00:40:00"
      name: eth2
  phase: Ready
  1. Created VirtualMachine, it has vlans filed as expected:
apiVersion: vmoperator.vmware.com/v1alpha6
kind: VirtualMachine
spec:
  affinity:
    vmAffinity:
      requiredDuringSchedulingPreferredDuringExecution:
      - labelSelector:
          matchLabels:
            cluster.x-k8s.io/deployment-name: wc-worker-vlans
        topologyKey: topology.kubernetes.io/zone
    vmAntiAffinity:
      preferredDuringSchedulingPreferredDuringExecution:
      - labelSelector:
          matchLabels:
            cluster.x-k8s.io/deployment-name: wc-worker-vlans
        topologyKey: kubernetes.io/hostname
  biosUUID: 996145b7-f7ca-4013-ab17-c08fdfbd96e9
  bootstrap:
    cloudInit:
      instanceID: 996145b7-f7ca-4013-ab17-c08fdfbd96e9
      rawCloudConfig:
        key: user-data
        name: wc-worker-vlans-47cm4-9hbxx
  className: best-effort-small
  groupName: wc
  hardware:
    ideControllers:
    - busNumber: 0
    - busNumber: 1
    scsiControllers:
    - busNumber: 0
      sharingMode: None
      type: ParaVirtual
  image:
    kind: ClusterVirtualMachineImage
    name: vmi-36a17705445f0b65e
  imageName: vmi-36a17705445f0b65e
  instanceUUID: edf43f3e-58e7-4be5-9a7b-d1d0fa298722
  network:
    interfaces:
    - name: eth0
      network:
        apiVersion: crd.nsx.vmware.com/v1alpha1
        kind: SubnetSet
        name: wc-dn4pp
    - gateway4: None
      gateway6: None
      name: eth1
      network:
        apiVersion: crd.nsx.vmware.com/v1alpha1
        kind: Subnet
        name: vlan-ext
    - gateway4: None
      gateway6: None
      name: eth2
      network:
        apiVersion: crd.nsx.vmware.com/v1alpha1
        kind: Subnet
        name: vlan-ext
    vlans:
    - id: 100
      link: eth1
      name: vl100a
    - id: 200
      link: eth1
      name: vl200a
    - id: 100
      link: eth2
      name: vl100b
    - id: 200
      link: eth2
      name: vl200b
  powerOffMode: Hard
  powerState: PoweredOn
  promoteDisksMode: Online
  reserved:
    resourcePolicyName: wc
  restartMode: TrySoft
  storageClass: wcpglobal-storage-profile
  suspendMode: TrySoft
  volumes:
  - controllerBusNumber: 0
    controllerType: SCSI
    diskMode: Persistent
    name: wc-worker-vlans-47cm4-9hbxx-97cdb4e7
    persistentVolumeClaim:
      claimName: wc-worker-vlans-47cm4-9hbxx-97cdb4e7
    removable: false
    sharingMode: None
    unitNumber: 0

Which issue(s) this PR fixes (optional, in fixes #<issue number>(, fixes #<issue_number>, ...) format, will close the issue(s) when PR gets merged):
Fixes #

@k8s-ci-robot k8s-ci-robot added do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Apr 21, 2026
@k8s-ci-robot
Copy link
Copy Markdown
Contributor

Hi @shutingm-kubernetes. Thanks for your PR.

I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work.

Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@k8s-ci-robot
Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign yastij for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label Apr 21, 2026
@shutingm-kubernetes shutingm-kubernetes changed the title ✨ Supports VLAN sub-interface creation on node ✨ Support VLAN sub-interface configuration for supervisor VSphereMachine Apr 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants