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.
This commit is contained in:
Jose Diaz-Gonzalez
2024-01-23 03:26:32 -05:00
parent c6838b645e
commit 204517074b
4 changed files with 72 additions and 56 deletions

View File

@@ -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:

View File

@@ -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 {

View File

@@ -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 ]")

View File

@@ -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,