Skip to content

3. Turn the CIDRs into variables

This is the step worth slowing down for. Everything else is picking things off a list; here you change the profile's behaviour, and you use the mechanism Palette gives you for values that vary between clusters.

What a CIDR is, briefly

Kubernetes needs two private IP ranges that exist only inside the cluster:

Range Used for
Pod CIDR Addresses for the containers
Service CIDR Addresses for the internal load balancers in front of them

These are invisible outside the cluster — but they must not overlap with any real network the cluster can reach. If they do, the cluster tries to route real traffic into itself and things break in ways that are genuinely hard to diagnose.

The pack defaults are 192.168.x.x and 192.169.x.x. 192.168.x.x is the single most common home and office network range in existence, so we change it every time.

Our standard:

Range Our standard
Pod CIDR 100.64.0.0/18
Service CIDR 100.64.64.0/18

100.64.x.x is reserved for carrier-grade NAT, so it almost never collides with a customer network.

Why variables instead of just typing the values

You could type 100.64.0.0/18 directly into the pack. But the pod CIDR appears in two different packs, and they must agree exactly. Type it twice and eventually someone updates one and not the other — a cluster that builds and then silently fails to network.

A profile variable is declared once and referenced everywhere. It also surfaces as a prompt at cluster-creation time, so the next person can change it without editing YAML at all.

Declare the two variables

  1. In your profile, find Profile Variables (top of the profile editor, near the profile name).
  2. Click Create Variable (not "Add Variable" — the button is labelled Create) and fill in the first one. Note the second field is the variable name your YAML will reference; the first is only a friendly display label:

    Field Value
    Name podCIDR
    Display name Pod CIDR
    Type String
    Default value 100.64.0.0/18
    Required Yes
  3. Add the second:

    Field Value
    Name serviceCIDR
    Display name Service CIDR
    Type String
    Default value 100.64.64.0/18
    Required Yes
  4. Save.

The name is case-sensitive

podCIDR and podcidr are different variables. If the reference in a pack does not match the declared name exactly, Palette passes the text through literally and Kubernetes receives the string {{.spectro.var.podCIDR}} as its network address. The cluster fails to build with an error that does not mention variables at all.

screenshot — Profile Variables panel with podCIDR and serviceCIDR defined

Edit 1 and 2 — the Kubernetes pack

Click the Palette eXtended Kubernetes – Edge layer. Its settings open as a YAML file on the right. Use the editor's search to find networking:.

You are looking for this:

      networking:
        podSubnet: 192.168.0.0/16
        serviceSubnet: 192.169.0.0/16

Change the values only. Do not paste the networking: line.

The networking: line is already in the file, in the right place. You are changing the two values underneath it — nothing else.

If you paste a block that includes networking:, you create a second one at whatever depth your cursor happened to be. That is still valid YAML, so nothing turns red and no error appears — Kubernetes simply ignores it, and the cluster fails later for reasons that look completely unrelated.

Change only the text after each colon:

On the line starting Select just this text Replace it with
podSubnet: 192.168.0.0/16 "{{.spectro.var.podCIDR}}"
serviceSubnet: 192.169.0.0/16 "{{.spectro.var.serviceCIDR}}"

Double-click the value to select it, then paste over it. Do not select the whole line — the spaces at the start of the line are what tell Kubernetes where the setting belongs.

The quotation marks are required.

Check it before moving on

Scroll up and down a little from your edit. The word networking: must start in the same column as etcd: and scheduler: — the vertical line below shows what that looks like:

      etcd:                                              # ← lines up
        local:
          extraArgs:
            - name: "cipher-suites"
              value: "TLS_ECDHE_..."
      networking:                                        # ← lines up
        podSubnet: "{{.spectro.var.podCIDR}}"
        serviceSubnet: "{{.spectro.var.serviceCIDR}}"
      scheduler:                                         # ← lines up

If networking: sits further to the right than etcd: and scheduler: — for example tucked underneath local: or extraArgs: — it is in the wrong place. Drag it back left until the three words line up.

Edit 3 — the Cilium pack

This is the one people miss. Cilium keeps its own copy of the pod range, and it has to match the one you just set.

Click the Cilium layer, click Values, and press Ctrl-F for clusterPoolIPv4PodCIDRList:

    clusterPoolIPv4PodCIDRList: ["10.0.0.0/8"]

Again, change only the text after the colon — select ["10.0.0.0/8"] and replace it with:

["{{.spectro.var.podCIDR}}"]

Keep the square brackets and the quotes inside them. Do not select the whole line.

Leave the IPAM mode alone

Further up this pack you will see ipam: mode: "kubernetes". Leave it exactly as it is. Kubernetes hands each node its pod range and Cilium reads it from there — which only works if Edit 2 landed in the right place.

If you skip this edit

The cluster will build and report healthy. Kubernetes will hand out addresses from 100.64.0.0/18 while Cilium hands out addresses from 10.0.0.0/8, and containers will not be able to reach each other. It looks like a working cluster right up until you deploy something onto it. This is exactly the failure the variable is there to prevent.

What good looks like

Three references to two variables:

Pack Setting Now reads
PXK-E podSubnet "{{.spectro.var.podCIDR}}"
PXK-E serviceSubnet "{{.spectro.var.serviceCIDR}}"
Cilium clusterPoolIPv4PodCIDRList ["{{.spectro.var.podCIDR}}"]

Now click Finish / Save to publish the profile.

Next: deploy the cluster →