-
Notifications
You must be signed in to change notification settings - Fork 715
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
apiserver fails to start because livenessprobe is too aggressive #413
Comments
It seems that we set both No doubt we should probably tweak both of these values to accommodate lower-power machines. |
Once started it can respond to health checks in << 15s - it's really just all the extra stuff that the apiserver does between exec() and actually being ready to serve afaics. |
oh, and the docker pull time doesn't count against InitialDelaySeconds afaics (good). In other examples with larger (generic ubuntu) images over my slow network link, the pull can take many minutes but the initialDelaySeconds timer doesn't seem to start ticking until the pull has completed and the docker run has started. (I haven't looked at the relevant code - just frequent anecdotal experience) |
I am running the same problem. With slow machines |
@anguslees and @koalalorenzo, can you confirm that if you manually change the liveness probe settings (by editing the manifest files in I just want to make sure that this approach will actually fix the problem before we invest time into coding it up. Thanks! |
I'm also experiencing this issue when attempting to use kubeadm in QEMU without hardware-assisted virtualisation (which is a bad idea because it is terribly slow). Increasing the InitialDelaySeconds and TimeoutSeconds helps; the cluster will then eventually come up. |
@pipejakob I can confirm that (on my bananapi) running this in another terminal at the right point in the kubeadm run makes everything come up successfully:
(I usually also manually |
@anguslees Great! Thanks for confirmation. |
I can confirm I've also just had this issue, in my case on an raspberry pi 3. Changing to 180s fixed it, however I think I also encountered issue #106 as in my case it simply died with: Sep 1 10:47:30 raspberrypi kubelet[6053]: W0901 10:47:30.020409 6053 kubelet.go:1596] Deleting mirror pod "kube-apiserver-raspberrypi_kube-system(7c03df63-8efa-1 I had to manually HUP the kubelet process to get it to kick back to life. |
I can also confirm I had this and wanted to say thank you for saving my sanity. I have Raspberry Pi 2B and I was stuck at init phase for the last month. After running that one-liner once it started waiting for the control plane, I got it going forward. |
This issue still exists in Timeouts break otherwise correct logic, particularly in complex eventually-consistent systems - we should never add them "just because" :( My understanding is that |
@anguslees We had the "wait forever" behavior earlier; but that was very sub-optimal from an UX PoV, so now we do have timeouts. We might want to increase some of those timeouts if you want. The problem is that usage of kubeadm is two-fold. We both have users typing kubeadm interactively that want to know if something is happening or not and higher-level consumers. |
.. So what direction are we going to go here? Currently I use a fork of |
How about making them configurable? Does it make sense to have a single option that owns all of them? |
/priority important-soon |
Probably, or some kind of "weight" for all the timeouts to be multiplied with... Otherwise we'll get into config hell with 20 different types of timeout flags :) |
Running into the same issue using kubeadm upgrade on raspberry pi 2 cluster. Upgrade fails due to agressive timeouts. Changing the liveness probe settings in the manifests doesn't help. Any ideas? |
I still propose a pattern where any kubeadm timeout is inherited from the calling context (or part of a more sophisticated error recovery strategy), rather than sprinkling arbitrary timeouts throughout the lower levels of the kubeadm codebase. In its simplest form, this would behave almost exactly like removing all the timeouts from kubeadm and replacing them with one overall "run for xx mins, then abort if not finished" global timer (since kubeadm can't do much in the way of error recovery other than just waiting longer). For the original manifest livenessProbe timeouts, it's literally a one-liner patch. Unfortunately, fixing the livenessProbe alone is no longer sufficient since the "deviation from normal == error" fallacy has spread further throughout the kubeadm codebase. Changing cultural awareness is hard, so in the meantime I have a forked version of kubeadm here, if anyone wants to just install onto a raspberry pi. (Build with |
@anguslees Do you have a compiled 1.9.4 version of your patched kubeadm? I'm having trouble compiling your patched version. I'm surprised kubeadm doesn't have this behavior behind a flag. Perhaps a PR is in order? |
/assign @liztio |
@joejulian thanks for investigating! closing until further notice. /close |
is there a way to pass such settings in kubeadm init file? maybe in |
There is not. Perhaps that would be a good feature to add. Later updates have added even more things to check and the extended timeout my PR provided was no longer sufficient. I've given up on managing the timeout. The solution for me was to use ecdsa certificates. Additionally the controller services including etcd take up more ram, now, than a Raspberry Pi has so rather than double the number of nodes to host the control plane, I've upgraded to Rock64s. Excuse the pun, but my control plane has been rock solid ever since. |
I've just been trying to do an install on a Raspberry Pi 3+ and can confirm that the install does indeed fail. Using the 'watch' trick on the kube-apiserver.yaml listed above does seem to work consistently ... but only if I change the initialDelaySeconds to 360. The suggested value of 180 seems marginal on my machines. Just when things where getting too easy, kubeadm is now complaining that the version of Docker (18.09) is unsupported. A quick revert to 18.06 fixed the issue. |
in kubeadm 1.13 we are adding configuration flag under ClusterConfig->ApiServer that can control the api server timeout. |
Searching through the codebase for I don't think I've seen a counter-argument raised anywhere in the discussion around this issue. Is there a reason we don't just increase livenessProbe initialDelaySeconds and move on to some other problem? Aside: As far as I can see from a quick read, Afaics |
That's an excellent point and I wholeheartedly agree. |
yes, there are no plans to modify the liveness probes from kubeadm, yet. this rpi issue was qualified at a sig-cluster-lifecyle meeting as "something that should not happen", "seems almost like a race condition in the kubelet", "why does it only happen on rpi and not on other slower devices". i have to admit i haven't tested slow devices myself. i.e. there was an agreement that increasing this value:
the timeout was 30 minutes before being 4 minutes, because it took pulling images into consideration before 1.11. |
Those are all reasons to continue looking for another bug somewhere else as well, but none of those are reasons not to increase initialDelaySeconds. Is there actually a downside to increasing initialDelaySeconds? To approach it from another direction, if we know we have an issue elsewhere in kubernetes with a workaround that can be used in kubeadm - is it kubeadm's role to "hold the line" on purity and produce a known-broken result? That seems to conflict with the goal to be a tool that we expect people to actually use for actual deployments. So far I've been unable to use kubeadm on my cluster without patching it to increase timeouts (despite reporting it, with patches, over a year ago), which makes me sad. (Apologies for letting some of my frustration around this issue leak into my tone)
Sigh. I was trying to make the case for no timeout in kubeadm, but I have yet to find a way to phrase that proposal convincingly (see this and other failed attempts in this issue, for example) :( |
it is a small change, but it was agreed to not add this increase because it will also apply to systems that don't exercise the problem.
facing the end user is a goal for kubeadm, that's true.
you don't have to patch kubeadm, you can patch manifest files instead. if you do so you can break down your you can already do that in 1.11 and 1.12, but it's less straight forward. |
So .. what's wrong with that? We fix bugs all the time that only trigger on some systems. Anywhere we have timeouts, we're going to need to tune them for our slowest-ever system, not just some subset of our environments, no? Another angle on this is that as an ops guy, I'm terrified of cascading failures in overload situations, particularly with the apiserver itself. Afaics, the livenessprobe timeout should only ever trigger when things have clearly failed, not just when it deviates from someone's idea of "normal". Afaics we should have a very relaxed livenessprobe configured, even on our fastest hardware. My little rpi is just demonstrating this overload failure more easily - but it also applies to bigger servers under bigger overload/DoS scenarios. There is no upside to having a small initialDelaySeconds. kubeadm's default livenessprobe is unnecessarily aggressive on all platforms. I'm sorry I keep repeating the same points, but afaics there are strong practical and theoretical reasons to extend initialDelaySeconds, and I'm just not understanding the opposing argument for keeping it small :( |
adding a kubeadm configuration option for this is unlikely at this point. i'm trying to explain that this is already doable with 3 commands in 1.13:
|
I don't want an option, I'm trying to say the current fixed value (15) should be changed to a different fixed value (360 was suggested above). .. But I don't want to drag this out any further. It's clear that the decision is to stick with the current value, so I will withdraw defeated. Thanks for your patience :) |
@neolit123 that combination looks great - far easier than what I'd documented - having to wait for the control plane set then quickly running sed in another terminal. https://github.com/alexellis/k8s-on-raspbian/blob/master/GUIDE.md I'll test the instructions and look to update the guide. |
@neolit123 this is what I got using the config above on an RPi3 B+ [certs] apiserver serving cert is signed for DNS names [rnode-1 kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 192.168.0.110 192.168.0.26 192.168.0.26]
[certs] Generating "sa" key and public key
[kubeconfig] Using kubeconfig folder "/etc/kubernetes"
[kubeconfig] Writing "admin.conf" kubeconfig file
[kubeconfig] Writing "kubelet.conf" kubeconfig file
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0xaa7204]
goroutine 1 [running]:
k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig.validateKubeConfig(0xfa93f2, 0xf, 0xfb3d32, 0x17, 0x4032210, 0x68f, 0x7bc)
/workspace/anago-v1.13.1-beta.0.57+eec55b9ba98609/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig/kubeconfig.go:236 +0x120
k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig.createKubeConfigFileIfNotExists(0xfa93f2, 0xf, 0xfb3d32, 0x17, 0x4032210, 0x0, 0xf7978)
/workspace/anago-v1.13.1-beta.0.57+eec55b9ba98609/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig/kubeconfig.go:257 +0x90
k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig.createKubeConfigFiles(0xfa93f2, 0xf, 0x3ec65a0, 0x3f71c60, 0x1, 0x1, 0x0, 0x0)
/workspace/anago-v1.13.1-beta.0.57+eec55b9ba98609/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig/kubeconfig.go:120 +0xf4
k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig.CreateKubeConfigFile(0xfb3d32, 0x17, 0xfa93f2, 0xf, 0x3ec65a0, 0x1f7a701, 0xb9772c)
/workspace/anago-v1.13.1-beta.0.57+eec55b9ba98609/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig/kubeconfig.go:93 +0xe8
k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases.runKubeConfigFile.func1(0xf66a80, 0x4208280, 0x0, 0x0)
/workspace/anago-v1.13.1-beta.0.57+eec55b9ba98609/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/kubeconfig.go:155 +0x168
k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow.(*Runner).Run.func1(0x3cc2d80, 0x0, 0x0)
/workspace/anago-v1.13.1-beta.0.57+eec55b9ba98609/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow/runner.go:235 +0x160
k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow.(*Runner).visitAll(0x3ec9270, 0x3f71d68, 0x4208280, 0x0)
/workspace/anago-v1.13.1-beta.0.57+eec55b9ba98609/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow/runner.go:416 +0x5c
k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow.(*Runner).Run(0x3ec9270, 0x24, 0x416bdb4)
/workspace/anago-v1.13.1-beta.0.57+eec55b9ba98609/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow/runner.go:208 +0xc8
k8s.io/kubernetes/cmd/kubeadm/app/cmd.NewCmdInit.func1(0x3e97b80, 0x3e900e0, 0x0, 0x3)
/workspace/anago-v1.13.1-beta.0.57+eec55b9ba98609/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/cmd/init.go:141 +0xfc
k8s.io/kubernetes/vendor/github.com/spf13/cobra.(*Command).execute(0x3e97b80, 0x3e3ff80, 0x3, 0x4, 0x3e97b80, 0x3e3ff80)
/workspace/anago-v1.13.1-beta.0.57+eec55b9ba98609/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/vendor/github.com/spf13/cobra/command.go:760 +0x20c
k8s.io/kubernetes/vendor/github.com/spf13/cobra.(*Command).ExecuteC(0x3e96140, 0x3e97b80, 0x3e96780, 0x3d82100)
/workspace/anago-v1.13.1-beta.0.57+eec55b9ba98609/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/vendor/github.com/spf13/cobra/command.go:846 +0x210
k8s.io/kubernetes/vendor/github.com/spf13/cobra.(*Command).Execute(0x3e96140, 0x3c8c0c8, 0x116d958)
/workspace/anago-v1.13.1-beta.0.57+eec55b9ba98609/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/vendor/github.com/spf13/cobra/command.go:794 +0x1c
k8s.io/kubernetes/cmd/kubeadm/app.Run(0x3c9c030, 0x0)
/workspace/anago-v1.13.1-beta.0.57+eec55b9ba98609/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/kubeadm.go:48 +0x1b0
main.main()
_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/kubeadm.go:29 +0x20
In kubeadm-config.yaml - 192.168.0.26 is an LB pointing to 192.168.0.110
|
I get the same even without the external config/lb IP. Alex |
I've been pushing folks to use kubeadm for a while, even schools wanting to run it on their pi clusters. While I understand not wanting to complicate the code base, I think its probably a good thing for your user base to support running on these little devices. it allows young folks to kick the Kubernetes tires on cheep hardware that otherwise might not. The workaround above, while valid, is much harder for this use case. What about a compromise? Instead of making it configurable, add a simple heuristic that says, if not x86_64, set the default timeout higher? |
odd, the the panic comes from this line: |
I'm seeing the exact same error as ☝️ above with the following:
The following script does solve the issue for me using kubeadm versions 1.12, 1.13 (most of the time)
|
I was in the same situation, getting the same error with the approach suggested by @neolit123 . So I ported the script to python (which is installed by default on Raspbian, so no need for extra dependencies), in case anyone is interested:
To run it: |
Hi! this issue was of much help I found a fancy way to resolve this using kustomize
|
This actually did worked on low spec hardwares. Increasing Initial Delay for all the major control plane components (kube-apiserver, kuber-controller, kube-scheduler-manager) to 180 seconds brought stability, no more frequent re-starts of control plane components. |
note kubeadm has the --experimental-patches (--patches in 1.22) feature that can be used to apply kubectl-like patches to the manifests before they are deployed. so you don't have to use these patches can also be applied with |
[Lubomir] NOTE: possible fix was submitted here:
kubernetes/kubernetes#66264
Is this a BUG REPORT or FEATURE REQUEST?
BUG REPORT
Versions
kubeadm version (use
kubeadm version
):kubeadm version: &version.Info{Major:"1", Minor:"7", GitVersion:"v1.7.3+2c2fe6e8278a5", GitCommit:"2c2fe6e8278a5db2d15a013987b53968c743f2a1", GitTreeState:"not a git tree", BuildDate:"1970-01-01T00:00:00Z", GoVersion:"go1.8", Compiler:"gc", Platform:"linux/arm"}
Environment:
Kubernetes version (use
kubectl version
):Server Version: version.Info{Major:"1", Minor:"7", GitVersion:"v1.7.4", GitCommit:"793658f2d7ca7f064d2bdf606519f9fe1229c381", GitTreeState:"clean", BuildDate:"2017-08-17T08:30:51Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/arm"}
Cloud provider or hardware configuration:
arm32 (bananapi - basically a raspberrypi2)
OS (e.g. from /etc/os-release):
(my own OS image)
ID="containos"
NAME="containos"
VERSION="v2017.07"
VERSION_ID="v2017.07"
PRETTY_NAME="containos v2017.07"
Kernel (e.g.
uname -a
):Linux master2 4.9.20 kubeadm init starts paused containers on ubuntu 16.04 #2 SMP Wed Aug 16 15:36:20 AEST 2017 armv7l GNU/Linux
Others:
What happened?
kubeadm init
sits ~forever at the "waiting for control plane" stage. docker ps/logs investigation shows apiserver is being killed (SIGTERM) and restarted continuously.What you expected to happen?
Everything to work :) In particular, apiserver to come up and the rest of the process to proceed.
How to reproduce it (as minimally and precisely as possible)?
Run
kubeadm init
on a slow machine.Anything else we need to know?
For me, during the churn of all those containers starting at once, it takes apiserver about 90s(!) from its first log line to responding to HTTP queries. I haven't looked in detail at what it's doing at that point, but the logs mention what looks like etcd bootstrapping things.
My suggested fix is to set apiserver
initialDelaySeconds
to 180s. And probably similar elsewhere in general - I think there's very little reason to have aggressive initial delays.(Unless you're a unittest that expects to frequently encounter failures, my experience with production software suggests the correct solution to timeouts is almost always to have waited longer).
The text was updated successfully, but these errors were encountered: