Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IPAM to nmstate network config #793

Merged
merged 30 commits into from
Aug 9, 2024
Merged

IPAM to nmstate network config #793

merged 30 commits into from
Aug 9, 2024

Conversation

anmazzotti
Copy link
Contributor

@anmazzotti anmazzotti commented Jul 2, 2024

Part of #756

This PR should introduce network config support.
Note that the machine registration and reset flows still require DHCP support, however this PR removes the need of "infinite leases".

The elemental-operator will be able to use any CAPI IPAM provider to reserve and assign static IPAddresses to each MachineInventory.

The elemental-register will be able to ask for a network config to be applied. While the actual config in the NetworkTemplate is schemaless, this PR implements nmstate only.

This will require the OS to also have nmstate installed, so that the config can be applied.

Note that it is possible to define a NetworkTemplate on both MachineRegistration and MachineSelector. The latter will be applied during the MachineInventory adoption phase, so that it is possible to define IPPools per Cluster (rather per Registration only).

A registration example:

apiVersion: ipam.cluster.x-k8s.io/v1alpha2
kind: InClusterIPPool
metadata:
  name: elemental-inventory-pool
  namespace: fleet-default
spec:
  addresses:
    - 192.168.122.150-192.168.122.200
  prefix: 24
  gateway: 192.168.122.1
---
apiVersion: elemental.cattle.io/v1beta1
kind: MachineRegistration
metadata:
  name: fire-nodes
  namespace: fleet-default
spec:
  config:
    network:
      ipAddresses:
      - name: inventory-ip
        ipPoolRef:
          apiGroup: ipam.cluster.x-k8s.io
          kind: InClusterIPPool
          name: elemental-inventory-pool
      config:
        dns-resolver:
          config:
            server:
            - 192.168.122.1
            search: []
        routes:
          config:
          - destination: 0.0.0.0/0
            next-hop-interface: enp1s0
            next-hop-address: 192.168.122.1
            metric: 150
            table-id: 254
        interfaces:
          - name: enp1s0
            type: ethernet
            description: Main-NIC
            state: up
            ipv4:
              enabled: true
              dhcp: false
              address:
              - ip: "{inventory-ip}"
                prefix-length: 24
            ipv6:
              enabled: false

@github-actions github-actions bot added area/operator operator related changes area/register register related changes area/tests test related changes labels Jul 2, 2024
@anmazzotti anmazzotti force-pushed the ipam_nmstate_support branch from 9e1679e to ffbcba7 Compare July 2, 2024 15:50
@kkaempf
Copy link
Contributor

kkaempf commented Jul 3, 2024

Can I express fixed IP assignments somehow ? 🤔

@anmazzotti
Copy link
Contributor Author

anmazzotti commented Jul 3, 2024

The MachineInventory now carries complete information about the IPs and network config, so that on reconcile it's easier to manage everything.

apiVersion: v1
items:
  - apiVersion: elemental.cattle.io/v1beta1
    kind: MachineInventory
    metadata:
      annotations:
        elemental.cattle.io/network.applied: "false"
      name: test-btrfs-d47ca4cf-e95e-4e43-939b-e5bce460fbfc
      namespace: fleet-default
    spec:
      ipAddressClaims:
        inventory-ip:
          apiVersion: ipam.cluster.x-k8s.io/v1beta1
          kind: IPAddressClaim
          name: test-btrfs-d47ca4cf-e95e-4e43-939b-e5bce460fbfc-inventory-ip
          namespace: fleet-default
          uid: ac9d9629-c545-41ec-93f0-e7a59b2fcfd2
      ipAddressPools:
        - ipPoolRef:
            apiGroup: ipam.cluster.x-k8s.io
            kind: InClusterIPPool
            name: elemental-inventory-pool
          name: inventory-ip
      network:
        config:
          dns-resolver:
            config:
              search: []
              server:
                - 192.168.122.1
          interfaces:
            - description: Main-NIC
              ipv4:
                address:
                  - ip: '{inventory-ip}'
                    prefix-length: 24
                dhcp: false
                enabled: true
              ipv6:
                enabled: false
              name: enp1s0
              state: up
              type: ethernet
          routes:
            config:
              - destination: 0.0.0.0/0
                metric: 150
                next-hop-address: 192.168.122.1
                next-hop-interface: enp1s0
                table-id: 254
        ipAddresses:
          inventory-ip: 192.168.122.150
      tpmHash: 759d02b8cdfad743082ac528214a5b00cb3d6079aaa2b6bb35d87209e36f1fdb
    status:
      conditions:
        - lastTransitionTime: "2024-07-04T08:24:48Z"
          message: NetworkConfig is ready
          reason: ReconcilingNetworkConfig
          status: "True"
          type: NetworkConfigReady

@anmazzotti
Copy link
Contributor Author

Can I express fixed IP assignments somehow ? 🤔

Not really. What are you trying to accomplish here?
There should be no particular attachment to one IP rather than another one, this is why we are supporting an IPAM provider.
You could theoretically define IPPools with 1 IP only, but that will also force you to one registration per machine and completely defeat what we are implementing here.

@github-actions github-actions bot added the area/build build related changes label Jul 3, 2024
@kkaempf
Copy link
Contributor

kkaempf commented Jul 3, 2024

Can I express fixed IP assignments somehow ? 🤔

Not really. What are you trying to accomplish here?

I wonder how IP assignments to cluster nodes survive across reboots.

@anmazzotti
Copy link
Contributor Author

I wonder how IP assignments to cluster nodes survive across reboots.

The network config is persisted through a yip file in /oem

For example this is included post-installation.
Note this will also run in recovery mode:

name: Apply network config
stages:
    initramfs:
        - files:
            - path: /oem/network/applied-config.yaml
              permissions: 384
              owner: 0
              group: 0
              content: |
                dns-resolver:
                  config:
                    search: []
                    server:
                    - 192.168.122.1
                interfaces:
                - description: Main-NIC
                  ipv4:
                    address:
                    - ip: '192.168.122.150'
                      prefix-length: 24
                    dhcp: false
                    enabled: true
                  ipv6:
                    enabled: false
                  name: enp1s0
                  state: up
                  type: ethernet
                routes:
                  config:
                  - destination: 0.0.0.0/0
                    metric: 150
                    next-hop-address: 192.168.122.1
                    next-hop-interface: enp1s0
                    table-id: 254
              encoding: ""
              ownerstring: ""
          directories:
            - path: /oem/network
              permissions: 448
              owner: 0
              group: 0
          if: '[ ! -f /oem/network/applied-config.yaml ]'
    network.before:
        - commands:
            - nmstatectl apply /oem/network/applied-config.yaml

@anmazzotti anmazzotti changed the title IPAM to nmstate support IPAM to nmconnection support Jul 11, 2024
@anmazzotti anmazzotti force-pushed the ipam_nmstate_support branch from 1de4af9 to 44790b1 Compare July 30, 2024 09:40
@anmazzotti anmazzotti changed the title IPAM to nmconnection support IPAM to nmstate support Jul 30, 2024
@anmazzotti
Copy link
Contributor Author

A lot happened in this PR.
The current status of things is that it does use nmstatectl to generate *.nmconnection files during the Elemental installation phase.

For example, given a MachineRegistration such as:

apiVersion: elemental.cattle.io/v1beta1
kind: MachineRegistration
metadata:
  name: fire-nodes
  namespace: fleet-default
spec:
  machineName: test-btrfs-${System Information/UUID}
  config:
    network:
      ipAddresses:
        inventory-ip:
          apiGroup: ipam.cluster.x-k8s.io
          kind: InClusterIPPool
          name: elemental-inventory-pool
      config:
        dns-resolver:
          config:
            server:
            - 192.168.122.1
            search: []
        routes:
          config:
          - destination: 0.0.0.0/0
            next-hop-interface: enp1s0
            next-hop-address: 192.168.122.1
            metric: 150
            table-id: 254
        interfaces:
          - name: enp1s0
            type: ethernet
            description: Main-NIC
            state: up
            ipv4:
              enabled: true
              dhcp: false
              address:
              - ip: "{inventory-ip}"
                prefix-length: 24
            ipv6:
              enabled: false

Will lead to the following yip file (/oem/94_custom.yaml) to apply network configuration:

name: Apply network config
stages:
    initramfs:
        - files:
            - path: /etc/NetworkManager/system-connections/Wired connection 1.nmconnection
              permissions: 384
              owner: 0
              group: 0
              content: |
                [connection]
                id=Wired connection 1
                uuid=d26b4ae4-d525-3cbf-a557-33feb60343c0
                type=ethernet
                autoconnect-priority=-999
                interface-name=enp1s0
                timestamp=1722339542

                [ethernet]

                [ipv4]
                address1=192.168.122.150/24
                dhcp-timeout=2147483647
                dns=192.168.122.1;
                dns-options=
                dns-priority=40
                method=manual
                route1=0.0.0.0/0,192.168.122.1,150
                route1_options=table=254

                [ipv6]
                addr-gen-mode=eui64
                dhcp-timeout=2147483647
                method=disabled

                [proxy]

                [user]
                nmstate.interface.description=Main-NIC
              encoding: ""
              ownerstring: ""
          if: '[ -f /run/elemental/active_mode ]'

@anmazzotti anmazzotti self-assigned this Jul 30, 2024
@anmazzotti anmazzotti changed the title IPAM to nmstate support IPAM to nmstate Jul 30, 2024
@anmazzotti anmazzotti changed the title IPAM to nmstate IPAM to nmstate network config Jul 30, 2024
@anmazzotti anmazzotti marked this pull request as ready for review July 31, 2024 13:59
@anmazzotti anmazzotti requested a review from a team as a code owner July 31, 2024 13:59
fgiudici and others added 8 commits August 5, 2024 16:14
Signed-off-by: Francesco Giudici <francesco.giudici@suse.com>
Signed-off-by: Francesco Giudici <francesco.giudici@suse.com>
Signed-off-by: Francesco Giudici <francesco.giudici@suse.com>
Signed-off-by: Francesco Giudici <francesco.giudici@suse.com>
Signed-off-by: Andrea Mazzotti <andrea.mazzotti@suse.com>
Signed-off-by: Andrea Mazzotti <andrea.mazzotti@suse.com>
Signed-off-by: Andrea Mazzotti <andrea.mazzotti@suse.com>
This reverts commit 5400507.
Signed-off-by: Andrea Mazzotti <andrea.mazzotti@suse.com>
Signed-off-by: Andrea Mazzotti <andrea.mazzotti@suse.com>
Signed-off-by: Andrea Mazzotti <andrea.mazzotti@suse.com>
Signed-off-by: Andrea Mazzotti <andrea.mazzotti@suse.com>
Signed-off-by: Andrea Mazzotti <andrea.mazzotti@suse.com>
Signed-off-by: Andrea Mazzotti <andrea.mazzotti@suse.com>
Signed-off-by: Andrea Mazzotti <andrea.mazzotti@suse.com>
Signed-off-by: Andrea Mazzotti <andrea.mazzotti@suse.com>
Signed-off-by: Andrea Mazzotti <andrea.mazzotti@suse.com>
Signed-off-by: Andrea Mazzotti <andrea.mazzotti@suse.com>
Signed-off-by: Andrea Mazzotti <andrea.mazzotti@suse.com>
Signed-off-by: Andrea Mazzotti <andrea.mazzotti@suse.com>
Signed-off-by: Andrea Mazzotti <andrea.mazzotti@suse.com>
Signed-off-by: Andrea Mazzotti <andrea.mazzotti@suse.com>
Signed-off-by: Andrea Mazzotti <andrea.mazzotti@suse.com>
Signed-off-by: Andrea Mazzotti <andrea.mazzotti@suse.com>
@anmazzotti anmazzotti force-pushed the ipam_nmstate_support branch 2 times, most recently from 70ac272 to aded615 Compare August 5, 2024 14:21
Signed-off-by: Andrea Mazzotti <andrea.mazzotti@suse.com>
@anmazzotti anmazzotti force-pushed the ipam_nmstate_support branch from aded615 to 61bc658 Compare August 5, 2024 14:22
Signed-off-by: Andrea Mazzotti <andrea.mazzotti@suse.com>
@@ -132,20 +141,42 @@ func newCommand(fs vfs.FS, client register.Client, stateHandler register.StateHa
return fmt.Errorf("Installing local agent config")
}
} else {
log.Info("Retrieving Network configuration")
networkConfigData, err := client.GetNetworkConfig(cfg.Elemental.Registration, caCert, &registrationState)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we already have networkConfigData as part of data (and yaml unmarshalled cfg) above?
data should be the full MachineRegistration elemental config, including the networking part (if not there maybe we have to explicitly add on the operator side).
We may save extending the websocket protocol here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The data contains the MachineRegistration data, but this will not contain the real IPAddresses.

I want to avoid replacing this data (and wait for real IPs) at this stage, this is why I think it's better to have a more explicit request.
Extending the protocol is not a problem I believe, but definitely we can improve in the future by not closing the websocket connection.

anmazzotti and others added 3 commits August 6, 2024 09:34
Signed-off-by: Andrea Mazzotti <andrea.mazzotti@suse.com>
Signed-off-by: Francesco Giudici <francesco.giudici@suse.com>
Signed-off-by: Francesco Giudici <francesco.giudici@suse.com>
Copy link
Member

@fgiudici fgiudici left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will likely still rework this in few ways, also changing the API, but since this is working and already a pretty good starting point, let's merge it 🎉

@anmazzotti anmazzotti merged commit 342bba2 into main Aug 9, 2024
22 checks passed
@anmazzotti anmazzotti deleted the ipam_nmstate_support branch August 9, 2024 08:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/build build related changes area/operator operator related changes area/register register related changes area/tests test related changes
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

3 participants