templates: set sysctl net.ipv4.tcp_keepalive_time to 30sec - #638
Conversation
This sets the interval for which the kernel will send TCP keepalives, in seconds. The default, 7200, is too high and causes idle but alive connections to be dropped by middleboxes and load balancers.
|
@mfojtik this should help with api issues. |
|
/lgtm |
|
/approve |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: squeed, sttts If they are not already assigned, you can assign the PR to them by writing The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
@squeed are there any open issues as reference for us on this? |
That /retest |
|
thanks @wking |
|
portal article on TCP keepalive which also implies we may want to be tuning the other values too? Would like to have at least one or two real world bugs that are motivating this change. |
+1 |
|
I'm confused why we need to set this at the machine level. We already set this in many places in the server - for instance, the servers set it with: which updates the descriptor: |
|
/hold |
|
Kube clients already set: in k8s.io/client-go/transport/cache.go - we have no need to set an explicit OS value. |
|
Not sure what I looked at yesterday after an 8h+ working day, but I see this now in Golang's library code: func setKeepAlivePeriod(fd *netFD, d time.Duration) error {
// The kernel expects seconds so round to next highest second.
d += (time.Second - time.Nanosecond)
secs := int(d.Seconds())
if err := fd.pfd.SetsockoptInt(syscall.IPPROTO_TCP, syscall.TCP_KEEPINTVL, secs); err != nil {
return wrapSyscallError("setsockopt", err)
}
err := fd.pfd.SetsockoptInt(syscall.IPPROTO_TCP, syscall.TCP_KEEPIDLE, secs)
runtime.KeepAlive(fd)
return wrapSyscallError("setsockopt", err)
}And we call this from k8s.io/apiserver with 120s, plus the mentioned client-go code. |
|
Yup, kube clients have a 30sec keepalive timeout: This probably isn't necessary, except for the (very minimal) potential non-client-go clients. |
|
This PR has a global effect on all TCP connections, including outbound etc. So if we're just trying to affect kube clients then it's a pretty heavy hammer. Bigger picture it feels like this is a kind of "race to the bottom" - NAT gateways want to clean up idle connections, apps want their TCP connections to stay open and not have spurious closed errors... |
|
@squeed: The following test failed, say
Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
This sets the interval for which the kernel will send TCP keepalives, in
seconds. The default, 7200, is too high and causes idle but alive
connections to be dropped by middleboxes and load balancers.
- How to verify it
- Description for the changelog
Update tcp_keepalive_time to 30 seconds.