Skip to content

Commit 5bfab47

Browse files
authored
unified function to set sysctl values (#580)
* unified function to set sysctl values and Enable arp_ignore and arp_announce
1 parent 4dce4b7 commit 5bfab47

File tree

2 files changed

+72
-38
lines changed

2 files changed

+72
-38
lines changed

pkg/controllers/proxy/network_services_controller.go

Lines changed: 31 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -275,28 +275,46 @@ func (nsc *NetworkServicesController) Run(healthChan chan<- *healthcheck.Control
275275
if err != nil {
276276
return errors.New("Failed to do add masquerad rule in POSTROUTING chain of nat table due to: %s" + err.Error())
277277
}
278-
278+
// https://www.kernel.org/doc/Documentation/networking/ipvs-sysctl.txt
279279
// enable ipvs connection tracking
280-
err = ensureIpvsConntrack()
281-
if err != nil {
282-
return errors.New("Failed to do sysctl net.ipv4.vs.conntrack=1 due to: %s" + err.Error())
280+
sysctlErr := utils.SetSysctl("net/ipv4/vs/conntrack", 1)
281+
if sysctlErr != nil {
282+
return errors.New(sysctlErr.Error())
283283
}
284284

285285
// LVS failover not working with UDP packets https://access.redhat.com/solutions/58653
286-
err = ensureIpvsExpireNodestConn()
287-
if err != nil {
288-
return errors.New("Failed to do sysctl net.ipv4.vs.expire_nodest_conn=1 due to: %s" + err.Error())
286+
sysctlErr = utils.SetSysctl("net/ipv4/vs/expire_nodest_conn", 1)
287+
if sysctlErr != nil {
288+
return errors.New(sysctlErr.Error())
289289
}
290290

291291
// LVS failover not working with UDP packets https://access.redhat.com/solutions/58653
292-
err = ensureIpvsQuiescentTemplate()
293-
if err != nil {
294-
return errors.New("Failed to do sysctl net.ipv4.vs.expire_quiescent_template=1 due to: %s" + err.Error())
292+
sysctlErr = utils.SetSysctl("net/ipv4/vs/expire_quiescent_template", 1)
293+
if sysctlErr != nil {
294+
return errors.New(sysctlErr.Error())
295295
}
296296

297-
err = ensureIpvsConnReuseMode()
298-
if err != nil {
299-
return fmt.Errorf("failed to set net.ipv4.vs.conn_reuse_mode=0: %s", err)
297+
// https://github.com/kubernetes/kubernetes/pull/71114
298+
sysctlErr = utils.SetSysctl("net/ipv4/vs/conn_reuse_mode", 0)
299+
if sysctlErr != nil {
300+
// Check if the error is fatal, on older kernels this option does not exist and the same behaviour is default
301+
// if option is not found just log it
302+
if sysctlErr.IsFatal() {
303+
return errors.New(sysctlErr.Error())
304+
}
305+
glog.Info(sysctlErr.Error())
306+
}
307+
308+
// https://github.com/kubernetes/kubernetes/pull/70530/files
309+
sysctlErr = utils.SetSysctl("net/ipv4/conf/all/arp_ignore", 1)
310+
if sysctlErr != nil {
311+
return errors.New(sysctlErr.Error())
312+
}
313+
314+
// https://github.com/kubernetes/kubernetes/pull/70530/files
315+
sysctlErr = utils.SetSysctl("net/ipv4/conf/all/arp_announce", 2)
316+
if sysctlErr != nil {
317+
return errors.New(sysctlErr.Error())
300318
}
301319

302320
// loop forever unitl notified to stop on stopCh
@@ -1405,31 +1423,6 @@ func deleteHairpinIptablesRules() error {
14051423
return nil
14061424
}
14071425

1408-
func ensureIpvsConntrack() error {
1409-
return ioutil.WriteFile("/proc/sys/net/ipv4/vs/conntrack", []byte(strconv.Itoa(1)), 0640)
1410-
}
1411-
1412-
func ensureIpvsConnReuseMode() error {
1413-
sysctlPath := "/proc/sys/net/ipv4/vs/conn_reuse_mode"
1414-
if _, err := os.Stat(sysctlPath); err != nil {
1415-
if os.IsNotExist(err) {
1416-
glog.Infof("%s not found, skipping setting net.ipv4.vs.conn_reuse_mode=0 (non fatal error, feature introduced into kernel in 4.1)", sysctlPath)
1417-
return nil
1418-
}
1419-
glog.Errorf("skipping setting net.ipv4.vs.conn_reuse_mode=0, error stating: %s : %s", sysctlPath, err.Error())
1420-
return nil
1421-
}
1422-
return ioutil.WriteFile(sysctlPath, []byte(strconv.Itoa(0)), 0640)
1423-
}
1424-
1425-
func ensureIpvsExpireNodestConn() error {
1426-
return ioutil.WriteFile("/proc/sys/net/ipv4/vs/expire_nodest_conn", []byte(strconv.Itoa(1)), 0640)
1427-
}
1428-
1429-
func ensureIpvsQuiescentTemplate() error {
1430-
return ioutil.WriteFile("/proc/sys/net/ipv4/vs/expire_quiescent_template", []byte(strconv.Itoa(1)), 0640)
1431-
}
1432-
14331426
func deleteMasqueradeIptablesRule() error {
14341427
iptablesCmdHandler, err := iptables.New()
14351428
if err != nil {

pkg/utils/sysctl.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package utils
2+
3+
import (
4+
"fmt"
5+
"io/ioutil"
6+
"os"
7+
"strconv"
8+
)
9+
10+
type SysctlError struct {
11+
err string
12+
option string
13+
value int
14+
fatal bool
15+
}
16+
17+
// Error return the error as string
18+
func (e *SysctlError) Error() string {
19+
return fmt.Sprintf("Sysctl %s=%d : %s", e.option, e.value, e.err)
20+
}
21+
22+
// IsFatal was the error fatal and reason to exit kube-router
23+
func (e *SysctlError) IsFatal() bool {
24+
return e.fatal
25+
}
26+
27+
// SetSysctl sets a sysctl value
28+
func SetSysctl(path string, value int) *SysctlError {
29+
sysctlPath := fmt.Sprintf("/proc/sys/%s", path)
30+
if _, err := os.Stat(sysctlPath); err != nil {
31+
if os.IsNotExist(err) {
32+
return &SysctlError{"option not found, Does your kernel version support this feature?", path, value, false}
33+
}
34+
return &SysctlError{"stat error: " + err.Error(), path, value, true}
35+
}
36+
err := ioutil.WriteFile(sysctlPath, []byte(strconv.Itoa(value)), 0640)
37+
if err != nil {
38+
return &SysctlError{"could not set due to: " + err.Error(), path, value, true}
39+
}
40+
return nil
41+
}

0 commit comments

Comments
 (0)