Skip to content
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

Fails to start 1.21.0 cluster - kubelet complains about missing cgroup #2189

Closed
Arnavion opened this issue Apr 8, 2021 · 9 comments
Closed
Labels
kind/bug Categorizes issue or PR as related to a bug.

Comments

@Arnavion
Copy link

Arnavion commented Apr 8, 2021

What happened:

kind create cluster --name v1.21 --image 'kindest/node:v1.21'

The kind command fails with:

Click here
$ kind create cluster --name v1.21 --image 'kindest/node:v1.21'

Loaded image: kindest/node:v1.21.0
Creating cluster "v1.21" ...
 ✓ Ensuring node image (kindest/node:v1.21.0) 🖼
 ✓ Preparing nodes 📦
 ✓ Writing configuration 📜
 ✗ Starting control-plane 🕹️
ERROR: failed to create cluster: failed to init node with kubeadm: command "docker exec --privileged v1.21-control-plane kubeadm init --skip-phases=preflight --config=/kind/kubeadm.conf --skip-token-print --v=6" failed with error: exit status 1
Command Output: I0408 21:33:41.777965     248 initconfiguration.go:246] loading configuration from "/kind/kubeadm.conf"
[config] WARNING: Ignored YAML document with GroupVersionKind kubeadm.k8s.io/v1beta2, Kind=JoinConfiguration
I0408 21:33:41.789251     248 kubelet.go:259] setting the KubeletConfiguration cgroupDriver to "systemd"
[init] Using Kubernetes version: v1.21.0
[certs] Using certificateDir folder "/etc/kubernetes/pki"
I0408 21:33:41.789357     248 certs.go:110] creating a new certificate authority for ca
[certs] Generating "ca" certificate and key
I0408 21:33:41.957924     248 certs.go:487] validating certificate period for ca certificate
[certs] Generating "apiserver" certificate and key
[certs] apiserver serving cert is signed for DNS names [kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local localhost v1.21-control-plane] and IPs [10.96.0.1 172.18.0.2 127.0.0.1]
I0408 21:33:42.469189     248 certs.go:110] creating a new certificate authority for front-proxy-ca
[certs] Generating "apiserver-kubelet-client" certificate and key
[certs] Generating "front-proxy-ca" certificate and key
I0408 21:33:42.602751     248 certs.go:487] validating certificate period for front-proxy-ca certificate
[certs] Generating "front-proxy-client" certificate and key
I0408 21:33:42.757067     248 certs.go:110] creating a new certificate authority for etcd-ca
[certs] Generating "etcd/ca" certificate and key
I0408 21:33:42.908739     248 certs.go:487] validating certificate period for etcd/ca certificate
[certs] Generating "etcd/server" certificate and key
[certs] etcd/server serving cert is signed for DNS names [localhost v1.21-control-plane] and IPs [172.18.0.2 127.0.0.1 ::1]
[certs] Generating "etcd/peer" certificate and key
[certs] etcd/peer serving cert is signed for DNS names [localhost v1.21-control-plane] and IPs [172.18.0.2 127.0.0.1 ::1]
[certs] Generating "etcd/healthcheck-client" certificate and key
[certs] Generating "apiserver-etcd-client" certificate and key
I0408 21:33:43.599110     248 certs.go:76] creating new public/private key files for signing service account users
[certs] Generating "sa" key and public key
[kubeconfig] Using kubeconfig folder "/etc/kubernetes"
I0408 21:33:43.927559     248 kubeconfig.go:101] creating kubeconfig file for admin.conf
[kubeconfig] Writing "admin.conf" kubeconfig file
I0408 21:33:44.299408     248 kubeconfig.go:101] creating kubeconfig file for kubelet.conf
[kubeconfig] Writing "kubelet.conf" kubeconfig file
I0408 21:33:44.716312     248 kubeconfig.go:101] creating kubeconfig file for controller-manager.conf
[kubeconfig] Writing "controller-manager.conf" kubeconfig file
I0408 21:33:44.875861     248 kubeconfig.go:101] creating kubeconfig file for scheduler.conf
[kubeconfig] Writing "scheduler.conf" kubeconfig file
I0408 21:33:45.208758     248 kubelet.go:63] Stopping the kubelet
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Starting the kubelet
[control-plane] Using manifest folder "/etc/kubernetes/manifests"
[control-plane] Creating static Pod manifest for "kube-apiserver"
I0408 21:33:45.291372     248 manifests.go:96] [control-plane] getting StaticPodSpecs
I0408 21:33:45.291840     248 certs.go:487] validating certificate period for CA certificate
I0408 21:33:45.291943     248 manifests.go:109] [control-plane] adding volume "ca-certs" for component "kube-apiserver"
I0408 21:33:45.291954     248 manifests.go:109] [control-plane] adding volume "etc-ca-certificates" for component "kube-apiserver"
I0408 21:33:45.291960     248 manifests.go:109] [control-plane] adding volume "k8s-certs" for component "kube-apiserver"
I0408 21:33:45.291966     248 manifests.go:109] [control-plane] adding volume "usr-local-share-ca-certificates" for component "kube-apiserver"
I0408 21:33:45.291974     248 manifests.go:109] [control-plane] adding volume "usr-share-ca-certificates" for component "kube-apiserver"
I0408 21:33:45.302742     248 manifests.go:126] [control-plane] wrote static Pod manifest for component "kube-apiserver" to "/etc/kubernetes/manifests/kube-apiserver.yaml"
I0408 21:33:45.302766     248 manifests.go:96] [control-plane] getting StaticPodSpecs
[control-plane] Creating static Pod manifest for "kube-controller-manager"
I0408 21:33:45.303107     248 manifests.go:109] [control-plane] adding volume "ca-certs" for component "kube-controller-manager"
I0408 21:33:45.303119     248 manifests.go:109] [control-plane] adding volume "etc-ca-certificates" for component "kube-controller-manager"
I0408 21:33:45.303125     248 manifests.go:109] [control-plane] adding volume "flexvolume-dir" for component "kube-controller-manager"
I0408 21:33:45.303132     248 manifests.go:109] [control-plane] adding volume "k8s-certs" for component "kube-controller-manager"
I0408 21:33:45.303138     248 manifests.go:109] [control-plane] adding volume "kubeconfig" for component "kube-controller-manager"
I0408 21:33:45.303144     248 manifests.go:109] [control-plane] adding volume "usr-local-share-ca-certificates" for component "kube-controller-manager"
I0408 21:33:45.303151     248 manifests.go:109] [control-plane] adding volume "usr-share-ca-certificates" for component "kube-controller-manager"
I0408 21:33:45.304293     248 manifests.go:126] [control-plane] wrote static Pod manifest for component "kube-controller-manager" to "/etc/kubernetes/manifests/kube-controller-manager.yaml"
I0408 21:33:45.304310     248 manifests.go:96] [control-plane] getting StaticPodSpecs
[control-plane] Creating static Pod manifest for "kube-scheduler"
I0408 21:33:45.304601     248 manifests.go:109] [control-plane] adding volume "kubeconfig" for component "kube-scheduler"
I0408 21:33:45.305220     248 manifests.go:126] [control-plane] wrote static Pod manifest for component "kube-scheduler" to "/etc/kubernetes/manifests/kube-scheduler.yaml"
[etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
I0408 21:33:45.306161     248 local.go:74] [etcd] wrote Static Pod manifest for a local etcd member to "/etc/kubernetes/manifests/etcd.yaml"
I0408 21:33:45.306176     248 waitcontrolplane.go:87] [wait-control-plane] Waiting for the API server to be healthy
I0408 21:33:45.307220     248 loader.go:372] Config loaded from file:  /etc/kubernetes/admin.conf
[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s
I0408 21:33:45.308956     248 round_trippers.go:454] GET https://v1.21-control-plane:6443/healthz?timeout=10s  in 0 milliseconds
I0408 21:33:45.810371     248 round_trippers.go:454] GET https://v1.21-control-plane:6443/healthz?timeout=10s  in 0 milliseconds

[...]

I0408 21:34:24.809786     248 round_trippers.go:454] GET https://v1.21-control-plane:6443/healthz?timeout=10s  in 0 milliseconds
[kubelet-check] Initial timeout of 40s passed.
[kubelet-check] It seems like the kubelet isn't running or healthy.
[kubelet-check] The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get "http://localhost:10248/healthz": dial tcp [::1]:10248: connect: connection refused.
I0408 21:34:25.310322     248 round_trippers.go:454] GET https://v1.21-control-plane:6443/healthz?timeout=10s  in 0 milliseconds

[...]

I0408 21:35:40.310530     248 round_trippers.go:454] GET https://v1.21-control-plane:6443/healthz?timeout=10s  in 0 milliseconds
[kubelet-check] It seems like the kubelet isn't running or healthy.
[kubelet-check] The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get "http://localhost:10248/healthz": dial tcp [::1]:10248: connect: connection refused.

        Unfortunately, an error has occurred:
                timed out waiting for the condition

        This error is likely caused by:
                - The kubelet is not running
                - The kubelet is unhealthy due to a misconfiguration of the node in some way (required cgroups disabled)

        If you are on a systemd-powered system, you can try to troubleshoot the error with the following commands:
                - 'systemctl status kubelet'
                - 'journalctl -xeu kubelet'

        Additionally, a control plane component may have crashed or exited when started by the container runtime.
        To troubleshoot, list all containers using your preferred container runtimes CLI.

        Here is one example how you may list all Kubernetes containers running in cri-o/containerd using crictl:
                - 'crictl --runtime-endpoint unix:///run/containerd/containerd.sock ps -a | grep kube | grep -v pause'
                Once you have found the failing container, you can inspect its logs with:
                - 'crictl --runtime-endpoint unix:///run/containerd/containerd.sock logs CONTAINERID'

couldn't initialize a Kubernetes cluster
k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/init.runWaitControlPlanePhase
        /go/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/init/waitcontrolplane.go:114
k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow.(*Runner).Run.func1
        /go/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow/runner.go:234
k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow.(*Runner).visitAll
        /go/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow/runner.go:421
k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow.(*Runner).Run
        /go/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow/runner.go:207
k8s.io/kubernetes/cmd/kubeadm/app/cmd.newCmdInit.func1
        /go/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/cmd/init.go:152
k8s.io/kubernetes/vendor/github.com/spf13/cobra.(*Command).execute
        /go/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/vendor/github.com/spf13/cobra/command.go:850
k8s.io/kubernetes/vendor/github.com/spf13/cobra.(*Command).ExecuteC
        /go/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/vendor/github.com/spf13/cobra/command.go:958
k8s.io/kubernetes/vendor/github.com/spf13/cobra.(*Command).Execute
        /go/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/vendor/github.com/spf13/cobra/command.go:895
k8s.io/kubernetes/cmd/kubeadm/app.Run
        /go/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/kubeadm.go:50
main.main
        _output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/kubeadm.go:25
runtime.main
        /usr/local/go/src/runtime/proc.go:225
runtime.goexit
        /usr/local/go/src/runtime/asm_amd64.s:1371
error execution phase wait-control-plane
k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow.(*Runner).Run.func1
        /go/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow/runner.go:235
k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow.(*Runner).visitAll
        /go/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow/runner.go:421
k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow.(*Runner).Run
        /go/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow/runner.go:207
k8s.io/kubernetes/cmd/kubeadm/app/cmd.newCmdInit.func1
        /go/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/cmd/init.go:152
k8s.io/kubernetes/vendor/github.com/spf13/cobra.(*Command).execute
        /go/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/vendor/github.com/spf13/cobra/command.go:850
k8s.io/kubernetes/vendor/github.com/spf13/cobra.(*Command).ExecuteC
        /go/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/vendor/github.com/spf13/cobra/command.go:958
k8s.io/kubernetes/vendor/github.com/spf13/cobra.(*Command).Execute
        /go/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/vendor/github.com/spf13/cobra/command.go:895
k8s.io/kubernetes/cmd/kubeadm/app.Run
        /go/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/app/kubeadm.go:50
main.main
        _output/dockerized/go/src/k8s.io/kubernetes/cmd/kubeadm/kubeadm.go:25
runtime.main
        /usr/local/go/src/runtime/proc.go:225
runtime.goexit
        /usr/local/go/src/runtime/asm_amd64.s:1371

journalctl inside the container reveals:

Apr 08 21:27:42 v1.21-control-plane systemd[1]: Starting kubelet: The Kubernetes Node Agent...
Apr 08 21:27:42 v1.21-control-plane systemd[1]: Started kubelet: The Kubernetes Node Agent.
Apr 08 21:27:42 v1.21-control-plane kubelet[1463]: Flag --fail-swap-on has been deprecated, This parameter should be set via the config file specified by the Kubelet's --config flag. See https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/ for more information.
Apr 08 21:27:42 v1.21-control-plane kubelet[1463]: Flag --provider-id has been deprecated, This parameter should be set via the config file specified by the Kubelet's --config flag. See https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/ for more information.
Apr 08 21:27:42 v1.21-control-plane kubelet[1463]: Flag --fail-swap-on has been deprecated, This parameter should be set via the config file specified by the Kubelet's --config flag. See https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/ for more information.
Apr 08 21:27:42 v1.21-control-plane kubelet[1463]: Flag --cgroup-root has been deprecated, This parameter should be set via the config file specified by the Kubelet's --config flag. See https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/ for more information.
Apr 08 21:27:42 v1.21-control-plane kubelet[1463]: I0408 21:27:42.485221    1463 server.go:197] "Warning: For remote container runtime, --pod-infra-container-image is ignored in kubelet, which should be set in that remote runtime instead"
Apr 08 21:27:42 v1.21-control-plane kubelet[1463]: Flag --fail-swap-on has been deprecated, This parameter should be set via the config file specified by the Kubelet's --config flag. See https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/ for more information.
Apr 08 21:27:42 v1.21-control-plane kubelet[1463]: Flag --provider-id has been deprecated, This parameter should be set via the config file specified by the Kubelet's --config flag. See https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/ for more information.
Apr 08 21:27:42 v1.21-control-plane kubelet[1463]: Flag --fail-swap-on has been deprecated, This parameter should be set via the config file specified by the Kubelet's --config flag. See https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/ for more information.
Apr 08 21:27:42 v1.21-control-plane kubelet[1463]: Flag --cgroup-root has been deprecated, This parameter should be set via the config file specified by the Kubelet's --config flag. See https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/ for more information.
Apr 08 21:27:42 v1.21-control-plane systemd[1]: Started Kubernetes systemd probe.
Apr 08 21:27:42 v1.21-control-plane kubelet[1463]: I0408 21:27:42.499384    1463 server.go:440] "Kubelet version" kubeletVersion="v1.21.0"
Apr 08 21:27:42 v1.21-control-plane kubelet[1463]: I0408 21:27:42.499704    1463 server.go:851] "Client rotation is on, will bootstrap in background"
Apr 08 21:27:42 v1.21-control-plane kubelet[1463]: I0408 21:27:42.502285    1463 certificate_store.go:130] Loading cert/key pair from "/var/lib/kubelet/pki/kubelet-client-current.pem".
Apr 08 21:27:42 v1.21-control-plane kubelet[1463]: I0408 21:27:42.503416    1463 dynamic_cafile_content.go:167] Starting client-ca-bundle::/etc/kubernetes/pki/ca.crt
Apr 08 21:27:42 v1.21-control-plane systemd[1]: run-r2444a3a0313e45eda80ef28542432b06.scope: Succeeded.
Apr 08 21:27:42 v1.21-control-plane kubelet[1463]: E0408 21:27:42.537150    1463 server.go:292] "Failed to run kubelet" err="failed to run Kubelet: invalid configuration: cgroup-root [\"kubelet\"] doesn't exist"
Apr 08 21:27:42 v1.21-control-plane systemd[1]: kubelet.service: Main process exited, code=exited, status=1/FAILURE
Apr 08 21:27:42 v1.21-control-plane systemd[1]: kubelet.service: Failed with result 'exit-code'.
Apr 08 21:27:43 v1.21-control-plane systemd[1]: kubelet.service: Scheduled restart job, restart counter is at 41.
Apr 08 21:27:43 v1.21-control-plane systemd[1]: Stopped kubelet: The Kubernetes Node Agent.

What you expected to happen:

Expected it to succeed.

How to reproduce it (as minimally and precisely as possible):

As above.

Anything else we need to know?:

This works with other Kubernetes versions from 1.14 through 1.20, so this is something 1.21-specific. The --cgroup-root=/kubelet parameter is given to kubelet for these versions too, without problems.

Environment:

  • kind version: (use kind version): kind v0.10.0 go1.15.7 linux/amd64
  • Kubernetes version: (use kubectl version): 1.21.0
  • Docker version: (use docker info): Server Version: 20.10.5-ce
  • OS (e.g. from /etc/os-release): openSUSE Tumbleweed 20210330

I guess v1.21 changed to require cgroups v2? That's the only thing that makes sense.

If that's the case, then yes my distro doesn't have the file it's looking for. The kubelet service unit has an ExecStartPre (injected via /etc/systemd/system/kubelet.service.d/10-kubeadm.conf ):

ExecStartPre=/bin/sh -euc "if [ -f /sys/fs/cgroup/cgroup.controllers ]; then create-kubelet-cgroup-v2; fi"

which means the script is entirely skipped on cgroup v1 hosts. If the script was run, it would've produced a more descriptive error:

if [[ ! -f "/sys/fs/cgroup/cgroup.controllers" ]]; then
        echo 'ERROR: this script should not be called on cgroup v1 hosts' >&2
        exit 1
fi

If v1.21 requires cgroups v2, it would be useful to run that script unguarded so that the error can be seen in the journal.

My distro added support for cgroups v2, and I can see the kubelet cgroup being created, but kubelet still exits with the same error that the cgroup is missing.

$ docker exec -it v1.21-control-plane cat /sys/fs/cgroup/kubelet/cgroup.controllers

cpuset cpu io memory hugetlb pids rdma
@Arnavion Arnavion added the kind/bug Categorizes issue or PR as related to a bug. label Apr 8, 2021
@BenTheElder
Copy link
Member

#2188 (comment) response here. This is an intentional breakage upstream in Kubernetes and is not any of the (good!) guesses here, it relates to the container runtime and kubelet mismatching drivers because kubeadm made a breaking change in v1.21

@BenTheElder
Copy link
Member

KIND in Kubernetes presubmit but using kind @ HEAD because Kubernetes can and will make breaking changes like this and we have to keep up.

@neolit123
Copy link
Member

should it be mentioned in https://kind.sigs.k8s.io/docs/user/quick-start/#creating-a-cluster that kind create cluster should no be used with a k8s version newer than X?

i see this as a re-occurring problem from users.

@BenTheElder
Copy link
Member

Well I'd like to stop letting this happen, it is relatively rare that most components have breaking changes versus users moving to cgroupsv2 etc., but it does seem to be technically allowed in upstream components ..

I think Kubernetes should stop doing this and not have single release action-required changes, as it's a bad experience for people trying to run it themselves. Most things like the end user facing APIs do not do this.

@neolit123
Copy link
Member

Well I'd like to stop letting this happen, it is relatively rare that most components have breaking changes versus users moving to cgroupsv2 etc., but it does seem to be technically allowed in upstream components ..

I think Kubernetes should stop doing this and not have single release action-required changes, as it's a bad experience for people trying to run it themselves.

it is a multi-layered problem for a WIP platform that is not versioned properly. not following SemVer and doing breaking changes on MINORs post a v1.x is definitely something that i do not agree with.

Most things like the end user facing APIs do not do this.

users are still forced to use tools like kubectl convert to migrate their outdated manifests on disk that include outdated non-GA API groups. i don't see how this can go without an action-required for new clusters.

@Arnavion
Copy link
Author

Arnavion commented Apr 9, 2021

Not every k8s release has a corresponding kind release, so it's not possible for a user to know up-front whether a new k8s will work an existing kind or not.

I'm not sure if the SIGs can coordinate to ensure the release of kind is synchronous with the release of k8s in case of breaking changes. If not, either users like me are going to open issues for tracking, or if you know up-front that breakage will happen you can create a pinned issue for it yourself. I only opened my issue after not finding an existing one.

@neolit123
Copy link
Member

documenting a support matrix can help.

@Arnavion
Copy link
Author

For completeness, I should note that my distro added support for cgroups v2, and I can see the cgroup being created via the ExecStartPre script inside the container, but kubelet exits with the same error anyway. (This is still with kind 0.10.0, not with master.)

@Arnavion
Copy link
Author

Fixed with the 0.11.0 release. I was successfully able to deploy a 1.21.1 cluster.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug Categorizes issue or PR as related to a bug.
Projects
None yet
Development

No branches or pull requests

3 participants