From 204517074bfb0d3725dedbcc04684ad954d91674 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 23 Jan 2024 03:26:32 -0500 Subject: [PATCH] fix: allow setting a custom ip address as the ip pf the dokku server This will provide the ability to override cases where the detected ip address is invalid for whatever reason. --- docs/deployment/schedulers/k3s.md | 24 ++++++- plugins/scheduler-k3s/functions.go | 31 +++++++++ .../src/subcommands/subcommands.go | 6 +- plugins/scheduler-k3s/subcommands.go | 67 +++++-------------- 4 files changed, 72 insertions(+), 56 deletions(-) diff --git a/docs/deployment/schedulers/k3s.md b/docs/deployment/schedulers/k3s.md index c39076768..068a2e0e7 100644 --- a/docs/deployment/schedulers/k3s.md +++ b/docs/deployment/schedulers/k3s.md @@ -41,6 +41,12 @@ By default, the k3s installation can run both app and system workloads. For clus dokku scheduler-k3s:initialize --taint-scheduling ``` +By default, Dokku will attempt to auto-detect the IP address of the server. In cases where the auto-detected IP address is incorrect, an override may be specified via the `--server-ip` flag: + +```shell +dokku scheduler-k3s:initialize --server-ip 192.168.20.15 +``` + ### Adding nodes to the cluster > [!WARNING] @@ -60,6 +66,12 @@ If the server isn't in the `known_hosts` file, the connection will fail. This ca dokku scheduler-k3s:cluster-add --insecure-allow-unknown-hosts ssh://root@worker-1.example.com ``` +By default, Dokku will attempt to auto-detect the IP address of the Dokku server for the remote server to connect to. In cases where the auto-detected IP address is incorrect, an override may be specified via the `--server-ip` flag: + +```shell +dokku scheduler-k3s:cluster-add --server-ip 192.168.20.15 ssh://root@worker-1.example.com +``` + #### Adding a server node > [!NOTE] @@ -76,13 +88,19 @@ dokku scheduler-k3s:cluster-add --role server ssh://root@server-1.example.com Server nodes allow any workloads to be scheduled on them by default, in addition to the control-plane, etcd, and the scheduler itself. To avoid app workloads being scheduled on your control-plane, use the `--taint-scheduling` flag: ```shell -dokku scheduler-k3s:cluster-add --role server --taint-scheduling ssh://root@cluster-1.example.com +dokku scheduler-k3s:cluster-add --role server --taint-scheduling ssh://root@server-1.example.com ``` If the server isn't in the `known_hosts` file, the connection will fail. This can be bypassed by setting the `--insecure-allow-unknown-hosts` flag: ```shell -dokku scheduler-k3s:cluster-add --role server --insecure-allow-unknown-hosts ssh://root@worker-1.example.com +dokku scheduler-k3s:cluster-add --role server --insecure-allow-unknown-hosts ssh://root@server-1.example.com +``` + +By default, Dokku will attempt to auto-detect the IP address of the Dokku server for the remote server to connect to. In cases where the auto-detected IP address is incorrect, an override may be specified via the `--server-ip` flag: + +```shell +dokku scheduler-k3s:cluster-add --role server --server-ip 192.168.20.15 ssh://root@server-1.example.com ``` #### Changing the network interface @@ -362,7 +380,7 @@ dokku scheduler-k3s:cluster-add --role server ssh://root@server-1.example.com Server nodes allow any workloads to be scheduled on them by default, in addition to the control-plane, etcd, and the scheduler itself. To avoid app workloads being scheduled on your control-plane, use the `--taint-scheduling` flag: ```shell -dokku scheduler-k3s:cluster-add --role server --taint-scheduling ssh://root@cluster-1.example.com +dokku scheduler-k3s:cluster-add --role server --taint-scheduling ssh://root@server-1.example.com ``` If the server isn't in the `known_hosts` file, the connection will fail. This can be bypassed by setting the `--insecure-allow-unknown-hosts` flag: diff --git a/plugins/scheduler-k3s/functions.go b/plugins/scheduler-k3s/functions.go index e7387bbac..1406a430b 100644 --- a/plugins/scheduler-k3s/functions.go +++ b/plugins/scheduler-k3s/functions.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "net" "os" "sort" "strconv" @@ -502,6 +503,36 @@ func getProcessResources(appName string, processType string) (ProcessResourcesMa return processResources, nil } +func getServerIP() (string, error) { + serverIP := "" + networkInterface := getGlobalNetworkInterface() + ifaces, err := net.Interfaces() + if err != nil { + return "", fmt.Errorf("Unable to get network interfaces: %w", err) + } + + for _, iface := range ifaces { + if iface.Name == networkInterface { + addr, err := iface.Addrs() + if err != nil { + return "", fmt.Errorf("Unable to get network addresses for interface %s: %w", networkInterface, err) + } + for _, a := range addr { + if ipnet, ok := a.(*net.IPNet); ok { + if ipnet.IP.To4() != nil { + serverIP = ipnet.IP.String() + } + } + } + } + } + + if len(serverIP) == 0 { + return "", fmt.Errorf(fmt.Sprintf("Unable to determine server ip address from network-interface %s", networkInterface)) + } + return serverIP, nil +} + func getStartCommand(input StartCommandInput) (StartCommandOutput, error) { command := extractStartCommand(input) fields, err := shell.Fields(command, func(name string) string { diff --git a/plugins/scheduler-k3s/src/subcommands/subcommands.go b/plugins/scheduler-k3s/src/subcommands/subcommands.go index 60bf79e23..38616f7d5 100644 --- a/plugins/scheduler-k3s/src/subcommands/subcommands.go +++ b/plugins/scheduler-k3s/src/subcommands/subcommands.go @@ -21,16 +21,18 @@ func main() { case "initialize": args := flag.NewFlagSet("scheduler-k3s:initialize", flag.ExitOnError) taintScheduling := args.Bool("taint-scheduling", false, "taint-scheduling: add a taint against scheduling app workloads") + serverIP := args.String("server-ip", "", "server-ip: IP address of the dokku server node") args.Parse(os.Args[2:]) - err = scheduler_k3s.CommandInitialize(*taintScheduling) + err = scheduler_k3s.CommandInitialize(*serverIP, *taintScheduling) case "cluster-add": args := flag.NewFlagSet("scheduler-k3s:cluster-add", flag.ExitOnError) allowUknownHosts := args.Bool("insecure-allow-unknown-hosts", false, "insecure-allow-unknown-hosts: allow unknown hosts") taintScheduling := args.Bool("taint-scheduling", false, "taint-scheduling: add a taint against scheduling app workloads") + serverIP := args.String("server-ip", "", "server-ip: IP address of the dokku server node") role := args.String("role", "worker", "role: [ server | worker ]") args.Parse(os.Args[2:]) remoteHost := args.Arg(0) - err = scheduler_k3s.CommandClusterAdd(*role, remoteHost, *allowUknownHosts, *taintScheduling) + err = scheduler_k3s.CommandClusterAdd(*role, remoteHost, *serverIP, *allowUknownHosts, *taintScheduling) case "cluster-list": args := flag.NewFlagSet("scheduler-k3s:cluster-list", flag.ExitOnError) format := args.String("format", "stdout", "format: [ stdout | json ]") diff --git a/plugins/scheduler-k3s/subcommands.go b/plugins/scheduler-k3s/subcommands.go index ee1a2b0c2..30d347b4b 100644 --- a/plugins/scheduler-k3s/subcommands.go +++ b/plugins/scheduler-k3s/subcommands.go @@ -5,7 +5,6 @@ import ( "crypto/rand" "encoding/json" "fmt" - "net" "net/url" "os" "os/signal" @@ -18,7 +17,7 @@ import ( ) // CommandInitialize initializes a k3s cluster on the local server -func CommandInitialize(taintScheduling bool) error { +func CommandInitialize(serverIP string, taintScheduling bool) error { if err := isK3sInstalled(); err == nil { return fmt.Errorf("k3s already installed, cannot re-initialize k3s") } @@ -34,31 +33,14 @@ func CommandInitialize(taintScheduling bool) error { cancel() }() - networkInterface := getGlobalNetworkInterface() - ifaces, err := net.Interfaces() - if err != nil { - return fmt.Errorf("Unable to get network interfaces: %w", err) - } - - serverIp := "" - for _, iface := range ifaces { - if iface.Name == networkInterface { - addr, err := iface.Addrs() - if err != nil { - return fmt.Errorf("Unable to get network addresses for interface %s: %w", networkInterface, err) - } - for _, a := range addr { - if ipnet, ok := a.(*net.IPNet); ok { - if ipnet.IP.To4() != nil { - serverIp = ipnet.IP.String() - } - } - } + if serverIP == "" { + var err error + serverIP, err = getServerIP() + if err != nil { + return fmt.Errorf("Unable to get server ip address: %w", err) } - } - if len(serverIp) == 0 { - return fmt.Errorf(fmt.Sprintf("Unable to determine server ip address from network-interface %s", networkInterface)) + common.LogVerboseQuiet(fmt.Sprintf("Using server ip address: %s", serverIP)) } common.LogInfo1Quiet("Initializing k3s") @@ -156,7 +138,7 @@ func CommandInitialize(taintScheduling bool) error { } } - nodeName := serverIp + nodeName := serverIP n := 5 b := make([]byte, n) if _, err := rand.Read(b); err != nil { @@ -280,7 +262,7 @@ func CommandInitialize(taintScheduling bool) error { } // CommandClusterAdd adds a server to the k3s cluster -func CommandClusterAdd(role string, remoteHost string, allowUknownHosts bool, taintScheduling bool) error { +func CommandClusterAdd(role string, remoteHost string, serverIP string, allowUknownHosts bool, taintScheduling bool) error { if err := isK3sInstalled(); err != nil { return fmt.Errorf("k3s not installed, cannot join cluster") } @@ -298,31 +280,14 @@ func CommandClusterAdd(role string, remoteHost string, allowUknownHosts bool, ta return fmt.Errorf("Taint scheduling can only be used on the server role") } - networkInterface := getGlobalNetworkInterface() - ifaces, err := net.Interfaces() - if err != nil { - return fmt.Errorf("Unable to get network interfaces: %w", err) - } - - serverIp := "" - for _, iface := range ifaces { - if iface.Name == networkInterface { - addr, err := iface.Addrs() - if err != nil { - return fmt.Errorf("Unable to get network addresses for interface %s: %w", networkInterface, err) - } - for _, a := range addr { - if ipnet, ok := a.(*net.IPNet); ok { - if ipnet.IP.To4() != nil { - serverIp = ipnet.IP.String() - } - } - } + if serverIP == "" { + var err error + serverIP, err = getServerIP() + if err != nil { + return fmt.Errorf("Unable to get server ip address: %w", err) } - } - if len(serverIp) == 0 { - return fmt.Errorf(fmt.Sprintf("Unable to determine server ip address from network-interface %s", networkInterface)) + common.LogVerboseQuiet(fmt.Sprintf("Using server ip address: %s", serverIP)) } ctx, cancel := context.WithCancel(context.Background()) @@ -464,7 +429,7 @@ func CommandClusterAdd(role string, remoteHost string, allowUknownHosts bool, ta "--node-name", nodeName, // server to connect to as the main "--server", - fmt.Sprintf("https://%s:6443", serverIp), + fmt.Sprintf("https://%s:6443", serverIP), // specify a token "--token", token,