Andrey Smirnov 641f6a1e4e
feat: expose strategic merge config patches
The end result is that every Talos CLI accepts both JSON and strategic
patches to patch machine configuration.

Signed-off-by: Andrey Smirnov <andrey.smirnov@talos-systems.com>
2022-07-12 15:38:01 +04:00

5.8 KiB

title, description
title description
Configuration Patches In this guide, we'll patch the generated machine configuration.

Talos generates machine configuration for two types of machines: controlplane and worker machines. Many configuration options can be adjusted using talosctl gen config but not all of them. Configuration patching allows modifying machine configuration to fit it for the cluster or a specific machine.

Configuration Patch Formats

Talos supports two configuration patch formats:

  • strategic merge patches
  • RFC6902 (JSON patches)

Strategic merge patches are the easiest to use, but JSON patches allow more precise configuration adjustments.

Strategic Merge patches

Strategic merge patches look like incomplete machine configuration files:

machine:
  network:
    hostname: worker1

When applied to the machine configuration, the patch gets merged with the respective section of the machine configuration:

machine:
  network:
    interfaces:
      - interface: eth0
        addresses:
          - 10.0.0.2/24
    hostname: worker1

In general, machine configuration contents are merged with the contents of the strategic merge patch, with strategic merge patch values overriding machine configuration values. There are some special rules:

  • If the field value is a list, the patch value is appended to the list, with the following exceptions:
    • values of the fields cluster.network.podSubnets and cluster.network.serviceSubnets are overwritten on merge
    • network.interfaces section is merged with the value in the machine config if there is a match on interface: or deviceSelector: keys

RFC6902 (JSON Patches)

JSON patches can be written either in JSON or YAML format. A proper JSON patch requires an op field that depends on the machine configuration contents: whether the path already exists or not.

For example, the strategic merge patch from the previous section can be written either as:

- op: replace
  path: /machine/network/hostname
  value: worker1

or:

- op: add
  path: /machine/network/hostname
  value: worker1

The correct op depends on whether the /machine/network/hostname section exists already in the machine config or not.

Examples

Machine Network

Base machine configuration:

# ...
machine:
  network:
    interfaces:
      - inteface: eth0
        dhcp: false
        addresses:
          - 192.168.10.3/24

The goal is to add a virtual IP 192.168.10.50 to the eth0 interface and add another interface eth1 with DHCP enabled.

{{< tabpane lang="yaml" >}} {{< tab header="Strategic merge patch" >}} machine: network: interfaces: - interface: eth0 vip: ip: 192.168.10.50 - interface: eth1 dhcp: true {{< /tab >}} {{< tab header="JSON patch" >}}

  • op: add path: /machine/network/interfaces/0/vip value: ip: 192.168.10.50
  • op: add path: /machine/network/interfaces/- value: interface: eth1 dhcp: true {{< /tab >}} {{< /tabpane >}}

Patched machine configuration:

machine:
  network:
    interfaces:
      - inteface: eth0
        dhcp: false
        addresses:
          - 192.168.10.3/24
        vip:
          ip: 192.168.10.50
      - interface: eth1
        dhcp: true

Cluster Network

Base machine configuration:

cluster:
  network:
    dnsDomain: cluster.local
    podSubnets:
      - 10.244.0.0/16
    serviceSubnets:
      - 10.96.0.0/12

The goal is to update pod and service subnets and disable default CNI (Flannel).

{{< tabpane lang="yaml" >}} {{< tab header="Strategic merge patch" >}} cluster: network: podSubnets: - 192.168.0.0/16 serviceSubnets: - 192.0.0.0/12 cni: name: none {{< /tab >}} {{< tab header="JSON patch" >}}

  • op: replace path: /cluster/network/podSubnets value:
    • 192.168.0.0/16
  • op: replace path: /cluster/network/serviceSubnets value:
    • 192.0.0.0/12
  • op: add path: /cluster/network/cni value: name: none {{< /tab >}} {{< /tabpane >}}

Patched machine configuration:

cluster:
  network:
    dnsDomain: cluster.local
    podSubnets:
      - 192.168.0.0/16
    serviceSubnets:
      - 192.0.0.0/12
    cni:
      name: none

Kubelet

Base machine configuration:

# ...
machine:
  kubelet: {}

The goal is to set the kubelet node IP to come from the subnet 192.168.10.0/24.

{{< tabpane lang="yaml" >}} {{< tab header="Strategic merge patch" >}} machine: kubelet: nodeIP: validSubnets: - 192.168.10.0/24 {{< /tab >}} {{< tab header="JSON patch" >}}

  • op: add path: /machine/kubelet/nodeIP value: validSubnets: - 192.168.10.0/24 {{< /tab >}} {{< /tabpane >}}

Patched machine configuration:

machine:
  kubelet:
    nodeIP:
      validSubnets:
        - 192.168.10.0/24

Configuration Patching with talosctl CLI

Several talosctl commands accept config patches as command-line flags. Config patches might be passed either as an inline value or as a reference to a file with @file.patch syntax:

talosctl ... --patch '[{"op": "add", "path": "/machine/network/hostname", "value": "worker1"}]' --patch @file.patch

If multiple config patches are specified, they are applied in the order of appearance. The format of the patch (JSON patch or strategic merge patch) is detected automatically.

Generated machine configuration can be patched with talosctl gen config:

talosctl gen config test-cluster https://172.20.0.1:6443 --config-patch @all.yaml --config-patch-control-plane @cp.yaml --config-patch-worker @worker.yaml

Machine configuration on the running Talos node can be patched with talosctl patch:

talosctl patch --nodes 172.20.0.2 --patch @patch.yaml