mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 03:41:45 +00:00
ipvs: check for existence of scheduler module and fail if not found
Signed-off-by: Christopher M. Luciano <cmluciano@us.ibm.com>
This commit is contained in:
parent
65ff4e8227
commit
51ed242194
@ -111,6 +111,7 @@ func Test_getProxyMode(t *testing.T) {
|
|||||||
kernelVersion: "4.18",
|
kernelVersion: "4.18",
|
||||||
ipsetVersion: ipvs.MinIPSetCheckVersion,
|
ipsetVersion: ipvs.MinIPSetCheckVersion,
|
||||||
expected: proxyModeIPVS,
|
expected: proxyModeIPVS,
|
||||||
|
scheduler: "rr",
|
||||||
},
|
},
|
||||||
{ // flag says ipvs, ipset version ok, kernel modules installed for linux kernel 4.19
|
{ // flag says ipvs, ipset version ok, kernel modules installed for linux kernel 4.19
|
||||||
flag: "ipvs",
|
flag: "ipvs",
|
||||||
@ -118,6 +119,7 @@ func Test_getProxyMode(t *testing.T) {
|
|||||||
kernelVersion: "4.19",
|
kernelVersion: "4.19",
|
||||||
ipsetVersion: ipvs.MinIPSetCheckVersion,
|
ipsetVersion: ipvs.MinIPSetCheckVersion,
|
||||||
expected: proxyModeIPVS,
|
expected: proxyModeIPVS,
|
||||||
|
scheduler: "rr",
|
||||||
},
|
},
|
||||||
{ // flag says ipvs, ipset version too low, fallback on iptables mode
|
{ // flag says ipvs, ipset version too low, fallback on iptables mode
|
||||||
flag: "ipvs",
|
flag: "ipvs",
|
||||||
@ -151,13 +153,14 @@ func Test_getProxyMode(t *testing.T) {
|
|||||||
expected: proxyModeIPVS,
|
expected: proxyModeIPVS,
|
||||||
scheduler: "sed",
|
scheduler: "sed",
|
||||||
},
|
},
|
||||||
{ // flag says ipvs, ipset version ok, non-existent scheduler
|
{ // flag says ipvs, kernel modules not installed for sed scheduler, fallback to iptables
|
||||||
flag: "ipvs",
|
flag: "ipvs",
|
||||||
kmods: []string{"ip_vs", "ip_vs_rr", "ip_vs_wrr", "ip_vs_sh", "nf_conntrack", "ip_vs_sed"},
|
kmods: []string{"ip_vs", "ip_vs_rr", "ip_vs_wrr", "ip_vs_sh", "nf_conntrack"},
|
||||||
kernelVersion: "4.19",
|
kernelVersion: "4.19",
|
||||||
ipsetVersion: ipvs.MinIPSetCheckVersion,
|
ipsetVersion: ipvs.MinIPSetCheckVersion,
|
||||||
expected: proxyModeIPVS,
|
expected: proxyModeIPTables,
|
||||||
scheduler: "foobar",
|
kernelCompat: true,
|
||||||
|
scheduler: "sed",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for i, c := range cases {
|
for i, c := range cases {
|
||||||
@ -167,11 +170,7 @@ func Test_getProxyMode(t *testing.T) {
|
|||||||
modules: c.kmods,
|
modules: c.kmods,
|
||||||
kernelVersion: c.kernelVersion,
|
kernelVersion: c.kernelVersion,
|
||||||
}
|
}
|
||||||
scheduler := cases[i].scheduler
|
canUseIPVS, _ := ipvs.CanUseIPVSProxier(khandler, ipsetver, cases[i].scheduler)
|
||||||
if scheduler == "" {
|
|
||||||
scheduler = "rr"
|
|
||||||
}
|
|
||||||
canUseIPVS, _ := ipvs.CanUseIPVSProxier(khandler, ipsetver, scheduler)
|
|
||||||
r := getProxyMode(c.flag, canUseIPVS, kcompater)
|
r := getProxyMode(c.flag, canUseIPVS, kcompater)
|
||||||
if r != c.expected {
|
if r != c.expected {
|
||||||
t.Errorf("Case[%d] Expected %q, got %q", i, c.expected, r)
|
t.Errorf("Case[%d] Expected %q, got %q", i, c.expected, r)
|
||||||
|
@ -711,10 +711,11 @@ func CanUseIPVSProxier(handle KernelHandler, ipsetver IPSetVersioner, scheduler
|
|||||||
}
|
}
|
||||||
mods = utilipvs.GetRequiredIPVSModules(kernelVersion)
|
mods = utilipvs.GetRequiredIPVSModules(kernelVersion)
|
||||||
wantModules := sets.NewString()
|
wantModules := sets.NewString()
|
||||||
schedulerMod, modNotFound := utilipvs.GetRequiredSchedulerModules(scheduler)
|
// We check for the existence of the scheduler mod and will trigger a missingMods error if not found
|
||||||
if modNotFound != nil {
|
if scheduler == "" {
|
||||||
klog.Error(modNotFound)
|
scheduler = DefaultScheduler
|
||||||
}
|
}
|
||||||
|
schedulerMod := "ip_vs_" + scheduler
|
||||||
mods = append(mods, schedulerMod)
|
mods = append(mods, schedulerMod)
|
||||||
wantModules.Insert(mods...)
|
wantModules.Insert(mods...)
|
||||||
|
|
||||||
|
@ -348,13 +348,13 @@ func TestCanUseIPVSProxier(t *testing.T) {
|
|||||||
ipsetVersion: MinIPSetCheckVersion,
|
ipsetVersion: MinIPSetCheckVersion,
|
||||||
ok: true,
|
ok: true,
|
||||||
},
|
},
|
||||||
// case 10, non-existent scheduler, fallback to rr
|
// case 10, non-existent scheduler, error due to modules not existing
|
||||||
{
|
{
|
||||||
mods: []string{"ip_vs", "ip_vs_rr", "ip_vs_wrr", "ip_vs_sh", "nf_conntrack", "ip_vs_dh"},
|
mods: []string{"ip_vs", "ip_vs_rr", "ip_vs_wrr", "ip_vs_sh", "nf_conntrack", "ip_vs_dh"},
|
||||||
scheduler: "foobar",
|
scheduler: "foobar",
|
||||||
kernelVersion: "4.19",
|
kernelVersion: "4.19",
|
||||||
ipsetVersion: MinIPSetCheckVersion,
|
ipsetVersion: MinIPSetCheckVersion,
|
||||||
ok: true,
|
ok: false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,6 @@ limitations under the License.
|
|||||||
package ipvs
|
package ipvs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"net"
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -84,14 +83,6 @@ const (
|
|||||||
KernelModuleIPVSWRR string = "ip_vs_wrr"
|
KernelModuleIPVSWRR string = "ip_vs_wrr"
|
||||||
// KernelModuleIPVSSH is the kernel module "ip_vs_sh"
|
// KernelModuleIPVSSH is the kernel module "ip_vs_sh"
|
||||||
KernelModuleIPVSSH string = "ip_vs_sh"
|
KernelModuleIPVSSH string = "ip_vs_sh"
|
||||||
// KernelModuleIPVSLC is the kernel module "ip_vs_lc"
|
|
||||||
KernelModuleIPVSLC string = "ip_vs_lc"
|
|
||||||
// KernelModuleIPVSNQ is the kernel module "ip_vs_nq"
|
|
||||||
KernelModuleIPVSNQ string = "ip_vs_nq"
|
|
||||||
// KernelModuleIPVSDH is the kernel module "ip_vs_dh"
|
|
||||||
KernelModuleIPVSDH string = "ip_vs_dh"
|
|
||||||
// KernelModuleIPVSSED is the kernel module "ip_vs_sed"
|
|
||||||
KernelModuleIPVSSED string = "ip_vs_sed"
|
|
||||||
// KernelModuleNfConntrackIPV4 is the module "nf_conntrack_ipv4"
|
// KernelModuleNfConntrackIPV4 is the module "nf_conntrack_ipv4"
|
||||||
KernelModuleNfConntrackIPV4 string = "nf_conntrack_ipv4"
|
KernelModuleNfConntrackIPV4 string = "nf_conntrack_ipv4"
|
||||||
// KernelModuleNfConntrack is the kernel module "nf_conntrack"
|
// KernelModuleNfConntrack is the kernel module "nf_conntrack"
|
||||||
@ -148,26 +139,3 @@ func GetRequiredIPVSModules(kernelVersion *version.Version) []string {
|
|||||||
func IsRsGracefulTerminationNeeded(proto string) bool {
|
func IsRsGracefulTerminationNeeded(proto string) bool {
|
||||||
return !strings.EqualFold(proto, "UDP") && !strings.EqualFold(proto, "SCTP")
|
return !strings.EqualFold(proto, "UDP") && !strings.EqualFold(proto, "SCTP")
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRequiredSchedulerModules returns the required ipvs scheduler module for configured scheduler
|
|
||||||
func GetRequiredSchedulerModules(scheduler string) (string, error) {
|
|
||||||
switch s := scheduler; s {
|
|
||||||
case "rr":
|
|
||||||
return KernelModuleIPVSRR, nil
|
|
||||||
case "lc":
|
|
||||||
return KernelModuleIPVSLC, nil
|
|
||||||
case "nq":
|
|
||||||
return KernelModuleIPVSNQ, nil
|
|
||||||
case "dh":
|
|
||||||
return KernelModuleIPVSDH, nil
|
|
||||||
case "sh":
|
|
||||||
return KernelModuleIPVSSH, nil
|
|
||||||
case "sed":
|
|
||||||
return KernelModuleIPVSSED, nil
|
|
||||||
case "":
|
|
||||||
return KernelModuleIPVSRR, nil
|
|
||||||
default:
|
|
||||||
notFound := fmt.Errorf("ip_vs_%s is not a supported IPVS scheduler algorithm, falling back to round-robin", scheduler)
|
|
||||||
return KernelModuleIPVSRR, notFound
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -17,7 +17,6 @@ limitations under the License.
|
|||||||
package ipvs
|
package ipvs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"net"
|
"net"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
@ -414,51 +413,3 @@ func TestGetRequiredIPVSModules(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetRequiredSchedulerModules(t *testing.T) {
|
|
||||||
Tests := []struct {
|
|
||||||
name string
|
|
||||||
scheduler string
|
|
||||||
want string
|
|
||||||
expectedErrs error
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "scheduler explicitly set to rr",
|
|
||||||
scheduler: "rr",
|
|
||||||
want: "ip_vs_rr",
|
|
||||||
expectedErrs: nil,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "scheduler set to nq",
|
|
||||||
scheduler: "nq",
|
|
||||||
want: "ip_vs_nq",
|
|
||||||
expectedErrs: nil,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "unset scheduler",
|
|
||||||
scheduler: "",
|
|
||||||
want: "ip_vs_rr",
|
|
||||||
expectedErrs: nil,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "invalid scheduler algorithm",
|
|
||||||
scheduler: "foobar",
|
|
||||||
want: "ip_vs_rr",
|
|
||||||
expectedErrs: fmt.Errorf("ip_vs_%s is not a supported IPVS scheduler algorithm, falling back to round-robin", "foobar"),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, test := range Tests {
|
|
||||||
t.Run(test.name, func(t *testing.T) {
|
|
||||||
got, err := GetRequiredSchedulerModules(test.scheduler)
|
|
||||||
if !reflect.DeepEqual(got, test.want) {
|
|
||||||
t.Fatalf("GetRequiredSchedulerModules() = testCase %v failed- expected: %s scheduler, but got: %s", test.name, test.want, got)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
if err.Error() != test.expectedErrs.Error() {
|
|
||||||
t.Fatalf("Expected error: %v, got: %v", test.expectedErrs, err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user