-
Notifications
You must be signed in to change notification settings - Fork 717
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
Additional phases and subphases in kubeadm init/join #2457
Comments
hi @micahhausler i must point out that i have zero experience with Bottlerocket. the kubeadm phases are not perfect and we do see occasional requests for changes. this request is by far the largest and most elaborate one to date., yet we must also weight in how many other users would see this change as beneficial and how many users this would break. as a rule of thumb for phases the general advice is to do this:
and not break the whole init/join commands into all their phases:
this is difficult to support for both kubeadm users and maintainers. because all changes become breaking once you expose all the implementation details of the software. [1] as an example, if we wish to separate the i can comment on your requests, but also please respond to my state machine idea above.
kubeadm init actually has a hidden phase to wait for the kubelet and kube-apiserver to report 200 at /healthz:
complexity explained in [1]
similar breaking change to [1]. |
👍 You got it.
I think this is doable for most of the waiting steps (wait for kubelet to come online, wait for kube-apiserver to come online)
This all makes sense. I think the most painful parts for us are when we have to wait for If we know that kubelet/kube-apiserver/etcd will fail, could we either pass a custom timeout for some of those? Or just a fast-fail option? |
i think
one timeout that can be controlled is ClusterConfiguration.apiServer.timeoutForControlPlane (defaults to 4 minutes) which is the timeout for the status 200 on the api-server /healthz. but the kubelet TLS bootstrap and etcd timeouts are not configurable. we are currently working on v1beta3 and if you'd like we could log a separate issue with a proposal for an API change to control etcd / kubelet tls timeouts, but this would mean these controls would only be possible for kubeadm >1.22. there are already some pending changes here with established priority: |
Additional user(s) reporting for duty with a real world use case 😄
Will do. /close |
@micahhausler: Closing this issue. In response to this:
Instructions 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. |
Is this a BUG REPORT or FEATURE REQUEST?
FEATURE REQUEST
/kind feature
/area phases
We're prototyping support for joining Bottlerocket nodes in cluster-api clusters, and have encountered the need for finer-grained control of the starting the kubernetes control plane. (Bottlerocket is a free and open-source Linux-based operating system meant for hosting containers)
Bottlerocket omits many components such as a package manager, SSH, shell, and instead relies on user-specified containers ("host containers") for initial configuration. It does not include cloud-config but rather parses a TOML based user-data boot script for configuration. Configuration values, including Kubelet settings, can be set or accessed via a local API.
Bottlerocket additionally doesn't allow writes to
/etc
by most processes (including host containers), but the Bottlerocket API supports updating some of the kubelet settings file and kubeconfig stored in/etc
. Because of a read-only/etc
, we've had to override several paths that kubeadm writes in static pod manifests (paths for/etc/kubernetes/pki
,/etc/kubernetes/{scheduler,controller-manager}.conf
to something writable) and some other hacky workarounds. We'd really like the bootstrap process to be cleaner and not rely on failures and timeouts, and we think adding a few more phases underkubeadm join
would really help us out without creating anything provider-specific.Here are roughly the current steps we have to take to create an initial Control Plane node:
/etc/kubernetes
in a host container to the writable/var/lib/kubeadm
on the host (/.bottlerocket/rootfs/var/lib/kubeadm
in the host-container)kubeadm init phase certs all
kubeadm init phase kubeconfig all
kubeadm init phase control-plane all
kubeadm init phase etcd local
/etc/kubernetes/manifests
and use the Bottlerocketapiclient
to write them to the host’s/etc/kubernetes/manifests
kubeadm init phase bootstrap-token
kubeadm token create
apiclient
to set API endpiont, CA data, bootstrap token, etc for the kubeletkubeadm init --skip-phases preflight,kubelet-start,certs,kubeconfig,bootstrap-token,control-plane,etcd
apiclient
to set the cluster DNS IP for kubeletSimilarly for joining additional Control Plane nodes, we have to:
/etc/kubernetes
in a host container to the writable/var/lib/kubeadm
on the host (/.bottlerocket/rootfs/var/lib/kubeadm
in the host-container)timeout 10 kubeadm join --skip-phases preflight
(which writes out keys, certs, static pod manifests, and kubelet config, but fails because static pods aren’t really written)apiclient
to set API endpiont, CA data, bootstrap token, etc for the kubeletapiclient
to write static pod manifests read from/var/lib/kubeadm/manifests
kubeadm join --skip-phases preflight,control-plane-prepare,kubelet-start
to write out the etcd manifest, after which kubeadm will fail because the static pod hasn’t been writtenapiclient
to write etcd static pod manifestkubeadm join --skip-phases preflight,control-plane-prepare,kubelet-start,control-plane-join/etcd
and succeedAnd then for a worker node join we have to:
/etc/kubernetes
in a host container to the writable/var/lib/kubeadm
on the host (/.bottlerocket/rootfs/var/lib/kubeadm
in the host-container)timeout 10 kubeadm join —skip-phases preflight
which writes out keys, kubelet config to a writeable path, but intentionally fails because the host kubelet kubeconfig isn't actually updated.apiclient
to set kubelet kubeconfig and config file optionsWe think the following additional phases and subphases would really be useful when the host’s
/etc
ins’t writable to kubeadm.kubeadm init
In
kubeadm init
:kubeadm join (control plane)
kubeadm join phase kubelet-start
forkubeadm join phase control-plane-join/etcd
kubeadm join (kubelet only)
Covered by the above request, of separate phases for config/certs/start/wait
Versions
kubeadm version (use
kubeadm version
): AllEnvironment:
kubectl version
): Alluname -a
):5.4.105
What happened?
What you expected to happen?
How to reproduce it (as minimally and precisely as possible)?
Anything else we need to know?
cc @bcressey @jaxesn @vignesh-goutham
The text was updated successfully, but these errors were encountered: