Skip to content

k0sctl cannot set controller endpoint ip address for each individual HA controller differently #1026

@chaserhkj

Description

@chaserhkj

My nodes are interconnected with a VPN that has private IPs in 192.168.194.* range, the host I am running k0sctl on is in the same VPN, my configuration looks like this:

apiVersion: k0sctl.k0sproject.io/v1beta1
kind: Cluster
metadata:
  name: primary-cluster
  user: hkj
spec:
  hosts:
  - openSSH:
      address: 192.168.194.1
      user: root
      port: 22
      keyPath: ./secrets/k0sctl.deploy.key
      configPath: /dev/null
    role: controller+worker
    noTaints: true
    useExistingK0s: true
    privateInterface: tap0
    privateAddress: 192.168.194.1
  - openSSH:
      address: 192.168.194.2
      user: root
      port: 22
      keyPath: ./secrets/k0sctl.deploy.key
      configPath: /dev/null
    role: controller+worker
    noTaints: true
    useExistingK0s: true
    privateInterface: tap0
    privateAddress: 192.168.194.2
  - openSSH:
      address: 192.168.194.3
      user: root
      port: 22
      keyPath: ./secrets/k0sctl.deploy.key
      configPath: /dev/null
    role: controller+worker
    noTaints: true
    useExistingK0s: true
    privateInterface: tap0
    privateAddress: 192.168.194.3
  k0s:
    config:
      apiVersion: k0s.k0sproject.io/v1beta1
      kind: Cluster
      metadata:
        name: primary
      spec:
        api:
          k0sApiPort: 9443
          port: 6443
        installConfig:
          users:
            etcdUser: etcd
            kineUser: kube-apiserver
            konnectivityUser: konnectivity-server
            kubeAPIserverUser: kube-apiserver
            kubeSchedulerUser: kube-scheduler
        konnectivity:
          adminPort: 8133
          agentPort: 8132
        network:
          kubeProxy:
            disabled: false
            mode: iptables
          kuberouter:
            autoMTU: true
            mtu: 0
            peerRouterASNs: ""
            peerRouterIPs: ""
          podCIDR: 10.244.0.0/16
          provider: kuberouter
          serviceCIDR: 10.96.0.0/12
          nodeLocalLoadBalancing:
            enabled: true
            type: EnvoyProxy
          controlPlaneLoadBalancing:
            enabled: true
            type: Keepalived
            keepalived:
              vrrpInstances:
              - virtualIPs: ["192.168.198.255/21"]
                interface: tap0
                authPass: <redacted>
        podSecurityPolicy:
          defaultPolicy: 00-k0s-privileged
        storage:
          type: etcd
        telemetry:
          enabled: false
  options:
    wait:
      enabled: true
    drain:
      enabled: true
      gracePeriod: 2m0s
      timeout: 5m0s
      force: true
      ignoreDaemonSets: true
      deleteEmptyDirData: true
      podSelector: ""
      skipWaitForDeleteTimeout: 0s
    concurrency:
      limit: 30
      workerDisruptionPercent: 10
      uploads: 5
    evictTaint:
      enabled: false
      taint: k0sctl.k0sproject.io/evict=true
      effect: NoExecute
      controllerWorkers: false

And when I run 'k0sctl apply --config config.yaml`:

$ k0sctl apply --config config.yaml
----------------------------------------------------------------------------------------------------

⠀⣿⣿⡇⠀⠀⢀⣴⣾⣿⠟⠁⢸⣿⣿⣿⣿⣿⣿⣿⡿⠛⠁⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀█████████ █████████ ███
⠀⣿⣿⡇⣠⣶⣿⡿⠋⠀⠀⠀⢸⣿⡇⠀⠀⠀⣠⠀⠀⢀⣠⡆⢸⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀███          ███    ███
⠀⣿⣿⣿⣿⣟⠋⠀⠀⠀⠀⠀⢸⣿⡇⠀⢰⣾⣿⠀⠀⣿⣿⡇⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀███          ███    ███
⠀⣿⣿⡏⠻⣿⣷⣤⡀⠀⠀⠀⠸⠛⠁⠀⠸⠋⠁⠀⠀⣿⣿⡇⠈⠉⠉⠉⠉⠉⠉⠉⠉⢹⣿⣿⠀███          ███    ███
⠀⣿⣿⡇⠀⠀⠙⢿⣿⣦⣀⠀⠀⠀⣠⣶⣶⣶⣶⣶⣶⣿⣿⡇⢰⣶⣶⣶⣶⣶⣶⣶⣶⣾⣿⣿⠀█████████    ███    ██████████
k0sctl (devel) Copyright 2025, k0sctl authors.
INFO ==> Running phase: Set k0s version
INFO Looking up latest stable k0s version
INFO Using k0s version v1.34.3+k0s.0
INFO ==> Running phase: Connect to hosts
ControlSocket /home/hkj/.ssh/ctrl-b0bad2c1c3758b29ea6964b95527fefc790a6d61 already exists, disabling multiplexing
ControlSocket /home/hkj/.ssh/ctrl-0181e9b08cf056ec6c3d9b42b196fc7f6796901c already exists, disabling multiplexing
ControlSocket /home/hkj/.ssh/ctrl-825a11a131323b6ecf70f70f7753fdd20e2332df already exists, disabling multiplexing
INFO [OpenSSH] root@192.168.194.3:22: connected
INFO [OpenSSH] root@192.168.194.1:22: connected
INFO [OpenSSH] root@192.168.194.2:22: connected
INFO ==> Running phase: Detect host operating systems
INFO [OpenSSH] root@192.168.194.1:22: is running Arch Linux
INFO [OpenSSH] root@192.168.194.2:22: is running Arch Linux
INFO [OpenSSH] root@192.168.194.3:22: is running Arch Linux
INFO ==> Running phase: Acquire exclusive host lock
INFO ==> Running phase: Prepare hosts
INFO ==> Running phase: Gather host facts
INFO [OpenSSH] root@192.168.194.3:22: using miku as hostname
INFO [OpenSSH] root@192.168.194.1:22: using hatsune as hostname
INFO [OpenSSH] root@192.168.194.2:22: using kagumine as hostname
INFO ==> Running phase: Validate hosts
WARN failed to walk k0s.tmp.* files in /usr/local/bin/k0s: stat /usr/local/bin/k0s.tmp.*: file does not exist
WARN failed to walk k0s.tmp.* files in /usr/local/bin/k0s: stat /usr/local/bin/k0s.tmp.*: file does not exist
WARN failed to walk k0s.tmp.* files in /usr/local/bin/k0s: stat /usr/local/bin/k0s.tmp.*: file does not exist
INFO validating clock skew
INFO ==> Running phase: Gather k0s facts
INFO [OpenSSH] root@192.168.194.3:22: found existing configuration
INFO [OpenSSH] root@192.168.194.1:22: found existing configuration
INFO [OpenSSH] root@192.168.194.2:22: found existing configuration
INFO [OpenSSH] root@192.168.194.1:22: is running k0s controller+worker version v1.34.3+k0s.0
INFO [OpenSSH] root@192.168.194.1:22: listing etcd members
INFO [OpenSSH] root@192.168.194.1:22: useExistingK0s=true, reusing existing k0s v1.34.3+k0s.0
INFO [OpenSSH] root@192.168.194.2:22: useExistingK0s=true, reusing existing k0s v1.34.3+k0s.0
INFO [OpenSSH] root@192.168.194.3:22: useExistingK0s=true, reusing existing k0s v1.34.3+k0s.0
INFO ==> Running phase: Validate facts
INFO ==> Running phase: Validate etcd members
INFO [OpenSSH] root@192.168.194.1:22: validating configuration
INFO [OpenSSH] root@192.168.194.2:22: validating configuration
INFO [OpenSSH] root@192.168.194.3:22: validating configuration
INFO ==> Running phase: Configure k0s
INFO [OpenSSH] root@192.168.194.3:22: installing new configuration
INFO [OpenSSH] root@192.168.194.1:22: installing new configuration
INFO [OpenSSH] root@192.168.194.1:22: restarting k0s service
INFO [OpenSSH] root@192.168.194.2:22: installing new configuration
INFO [OpenSSH] root@192.168.194.1:22: waiting for k0s service to start
INFO ==> Running phase: Run Before Apply Hooks
INFO ==> Running phase: Install controllers
INFO [OpenSSH] root@192.168.194.1:22: generate join token for [OpenSSH] root@192.168.194.2:22
INFO [OpenSSH] root@192.168.194.1:22: generate join token for [OpenSSH] root@192.168.194.3:22
INFO [OpenSSH] root@192.168.194.3:22: validating api connection to https://192.168.2.51:9443
INFO [OpenSSH] root@192.168.194.2:22: validating api connection to https://192.168.2.51:9443
INFO * Running clean-up for phase: Acquire exclusive host lock
INFO * Running clean-up for phase: Install controllers
INFO [OpenSSH] root@192.168.194.3:22: cleaning up
INFO [OpenSSH] root@192.168.194.2:22: cleaning up
INFO ==> Apply failed
FATA apply failed - log file saved to /home/hkj/.cache/k0sctl/k0sctl.log: failed on 2 hosts:
 - [OpenSSH] root@192.168.194.3:22: failed to connect from controller to kubernetes api - check networking: context deadline exceeded
command failed: client exec: command failed: command wait: exit status 28
 - [OpenSSH] root@192.168.194.2:22: failed to connect from controller to kubernetes api - check networking: context deadline exceeded
command failed: client exec: command failed: command wait: exit status 28

For some reason k0sctl just keeps trying to validate API connection using the public (or precisely, internet-facing) IP address (on-site LAN address 192.168.2.51) of my 192.168.194.1 node. But these three nodes are not on the same site thus the other two just don't have access to that IP.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions