I'm building a Kubernetes cluster on openSUSE Tumbleweed for learning, using five VMs: three control-plane nodes and two workers. On the first control-plane VM, kubeadm creates the certificates and static Pod manifests, but eventually fails with: `could not bootstrap the admin user in file admin.conf: unable to create ClusterRoleBinding: client rate limiter Wait returned an error: rate: Wait(n=1) would exceed context deadline`.
I configured CRI-O, cgroup v2, a systemd cgroup driver, and kube-vip with a virtual IP of `10.10.30.5`. The API server advertises `10.10.30.10`, while the control-plane endpoint is the kube-vip address. kube-vip was placed in `/etc/kubernetes/manifests` before running kubeadm, but it did not appear to start, and the API server was not reachable through the VIP.
The important clue is that the bootstrap succeeds when I run `setenforce 0`. SELinux is enforcing by default, and `container-selinux` is installed. Fedora works with SELinux enforcing, so I'm trying to understand what differs on Tumbleweed and how to fix this without disabling SELinux or writing an overly broad custom policy.
2 Answers
The denials point to the cgroup v2 device controller. With systemd cgroups, the runtime uses an eBPF program to enforce device access for container cgroups. On this Tumbleweed image, the SELinux policy prevents systemd from running that BPF program. As a result, CRI-O/crun cannot set up the container scopes correctly, so etcd, kube-apiserver, and the other static Pods repeatedly start and die. That explains why permissive mode lets the entire initialization finish.
The clean fix would be an updated openSUSE SELinux policy that grants the required permission, or a narrowly scoped local policy generated from the verified AVCs. Before creating one, update the system and policy packages and check whether the issue has already been fixed upstream. Otherwise, using a distribution whose policy supports this CRI-O/systemd/cgroup-v2 combination is more practical than weakening SELinux globally.
The missing kube-vip Pod is likely secondary. Inspect the kubelet and runtime logs for the static Pod; the API server cannot become healthy through the VIP until the underlying cgroup/BPF failure is resolved.
This looks like an SELinux policy problem rather than a kube-vip configuration problem. Check the audit log while reproducing the failure with commands such as `ausearch -m AVC -ts recent` or `journalctl -t setroubleshoot`. Compare the actual denials with the Fedora host, since the policy modules and container runtime behavior may differ even when both systems use enforcing mode.
The kubeadm timeout is probably only a symptom: if etcd or the API server static Pods cannot remain running, kubeadm eventually fails while trying to contact the API server. Check `crictl ps -a`, `crictl logs`, and the kubelet journal to find the first container failure.
I checked the AVC records. The relevant denials were not file-access or kubeconfig-labeling failures. They were repeated `prog_run` denials for `systemd` running a BPF program from an unconfined service domain.

That also explains why relabeling `/etc/kubernetes` did not help: the containers had the expected labels, and the denial was about executing the BPF program, not reading `admin.conf`. A custom policy may work, but it would need to be applied consistently to every node and maintained across policy updates.