Deploy a Kubernetes cluster, with Kubernetes
310
kubeception is a proof of concept variant of a mix between bootkube
and kubeadm.
It's a SUSE Hackweek 2018 project, and its purpose is to have some fun deploying a Kubernetes cluster using Kubernetes pieces.
This project is not trying to fill any gaps in the previous pieces of software, but it's instead written from scratch to understand how Kubernetes can launch (and maintain) Kubernetes, instead of another completely different tool to deploy and maintain it.
kubeception assumes some things on the host system:
etcd installed.kubelet installed.kubectl installed.kubeception supports different distro-targeted configurations. One is provided for openSUSE Kubic.
That being said, a simple way to launch kubeception in an openSUSE Kubic environment would be:
docker run -v /usr/bin/kubectl:/usr/bin/kubectl \
-v /etc/kubernetes/kubelet:/etc/kubernetes/kubelet \
-v /etc/sysconfig/etcd:/etc/sysconfig/etcd \
-v /etc/etcd:/etc/etcd \
-v /etc/kubernetes/manifests:/etc/kubernetes/manifests \
-v /etc/kubernetes/bootstrap-secrets:/etc/kubernetes/bootstrap-secrets \
-v /var/run/dbus:/var/run/dbus \
-e "RUST_LOG=info" --net=host \
-it ereslibre/kubeception kubeception bootstrap --config config/kubic.toml
In less than a minute, our node has become a Kubernetes master:
INFO 2018-07-19T10:24:20Z: kubeception::etcd: bootstrapping
INFO 2018-07-19T10:24:21Z: kubeception::k8s: bootstrapping
INFO 2018-07-19T10:24:21Z: kubeception::k8s: deploying control plane
INFO 2018-07-19T10:24:21Z: kubeception::k8s: applying control plane manifests
INFO 2018-07-19T10:24:21Z: kubeception::k8s: waiting for bootstrap apiserver
INFO 2018-07-19T10:24:39Z: kubeception::k8s: configuring local kubelet
INFO 2018-07-19T10:24:39Z: kubeception::k8s: waiting for bootstrap apiserver
INFO 2018-07-19T10:24:39Z: kubeception::k8s: pointing the kubelet to the boostrap apiserver
INFO 2018-07-19T10:24:39Z: kubeception::k8s: waiting for kubelet to be registered
INFO 2018-07-19T10:24:40Z: kubeception::k8s: labeling node and setting taints
INFO 2018-07-19T10:24:40Z: kubeception::k8s: waiting for bootstrap apiserver
INFO 2018-07-19T10:24:40Z: kubeception::k8s: performing stability check for cluster apiserver
INFO 2018-07-19T10:24:40Z: kubeception::k8s: waiting for cluster apiserver
INFO 2018-07-19T10:24:57Z: kubeception::k8s: waiting for cluster apiserver
INFO 2018-07-19T10:24:58Z: kubeception::k8s: waiting for cluster apiserver
INFO 2018-07-19T10:24:59Z: kubeception::k8s: waiting for cluster apiserver
INFO 2018-07-19T10:25:00Z: kubeception::k8s: waiting for cluster apiserver
INFO 2018-07-19T10:25:01Z: kubeception::k8s: waiting for cluster apiserver
INFO 2018-07-19T10:25:02Z: kubeception::k8s: waiting for cluster apiserver
INFO 2018-07-19T10:25:03Z: kubeception::k8s: waiting for cluster apiserver
INFO 2018-07-19T10:25:04Z: kubeception::k8s: waiting for cluster apiserver
INFO 2018-07-19T10:25:05Z: kubeception::k8s: pointing the kubelet to the cluster apiserver
INFO 2018-07-19T10:25:05Z: kubeception::k8s: removing static manifests
You can check that everything is running as expected, and that the node is now Ready:
linux-e9u2:~ # kubectl --kubeconfig=/etc/kubernetes/bootstrap-secrets/kubeconfig get nodes -o wide
NAME STATUS ROLES AGE VERSION EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
linux-e9u2 Ready master 41m v1.10.4 <none> openSUSE Tumbleweed Kubic 4.17.4-1-default docker://17.9.1
All pods should be in Running state as expected:
linux-e9u2:~ # kubectl --kubeconfig=/etc/kubernetes/bootstrap-secrets/kubeconfig get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system kube-apiserver-qb75b 1/1 Running 1 42m
kube-system kube-controller-manager-86c48ffdbd-qh8jh 1/1 Running 1 42m
kube-system kube-controller-manager-86c48ffdbd-qvwrj 1/1 Running 1 42m
kube-system kube-dns-5d84c799b5-2dn2q 3/3 Running 4 42m
kube-system kube-flannel-pf5qr 2/2 Running 1 4m
kube-system kube-flannel-xwdr5 2/2 Running 4 42m
kube-system kube-proxy-2wfn2 1/1 Running 1 42m
kube-system kube-proxy-bk4nh 1/1 Running 0 4m
kube-system kube-scheduler-54d5cb78b8-nd4ds 1/1 Running 1 42m
kube-system kube-scheduler-54d5cb78b8-pxbq6 1/1 Running 1 42m
kube-system kubeception-6f7d75db5d-rnhks 1/1 Running 1 42m
We have successfully kubeception'ed our openSUSE Kubic node!
Bootstrap is a safe operation that can be ran over and over. It doesn't matter the current state of the cluster, the bootstrap will perform the following operations:
Generate all keys and certificates needed for the cluster to start.
Set up etcd.
Write the configuration for the kubelet.
apiserver, replication-controller and scheduler manifests in the pod manifests path of the kubelet.
hostNetwork all the way.kubeconfig for the bootstrap control plane and the "final" control plane.kubelet config pointing to the bootstrap control plane.Start and enable the kubelet service.
At this point, the kubelet will be talking to the apiserver deployed with static manifests. Of course, the apiserver in both
variants (bootstrap control plane and final control plane) talk to the same etcd backend, so in turn what we ensure by starting
a new bootstrap control plane and talk to that one while we need it; so we continue:
Wait for the apiserver to be ready on its healthz endpoint.
Deploy all final control plane manifests using the bootstrap apiserver.
Deploy the kubeception manifests using the bootstrap apiserver.
Now, at this point, the kubelet will be downloading images in order to start all the control plane pieces; or it will be starting
the containers. Note that the bootstrap apiserver and the final one can coexist, because they listen on different ports.
apiserver to be ready. This is more a sanity check for when steps could be run in an independent way.kubelet to the bootstrap cluster. Same thing as before.kubelet to have registered against the apiserver.bootstrap apiserver).apiserver to be running in a stable manner (that is; 10 successful checks in a row).kubelet to the final cluster.bootstrap control plane manifests from the static pod manifest path.Starting our own bootstrap control plane has its advantages: we don't really care or depend on the current status of the cluster
at this moment, as long as etcd is healthy and can talk to us.
You can join new worker nodes to your existing Kubernetes installation. kubeception did create a deployment
of itself inside the cluster with an exposed node port. This means that you can reach to any machine at the
30000 port, and join the cluster.
BIG NOTE: NO SECURITY AT ALL. HTTP TRANSPORT, NO TOKENS, NOTHING (yet).
We also assume some things about your worker nodes:
kubelet installed.Now, let's join the cluster. From the machine to be joined, run:
docker run -v /etc/kubernetes/kubelet:/etc/kubernetes/kubelet \
-v /etc/kubernetes/bootstrap-secrets:/etc/kubernetes/bootstrap-secrets \
-v /var/run/dbus:/var/run/dbus \
-e "RUST_LOG=info" --net=host \
-it ereslibre/kubeception kubeception join --url http://linux-e9u2:30000/join --config config/kubic.toml
Now the node should have joined, it's an instant operation. It will become Ready when CNI is finally deployed on it (some images
need to be downloaded):
linux-e9u2:~ # kubectl --kubeconfig=/etc/kubernetes/bootstrap-secrets/kubeconfig get nodes -o wide
NAME STATUS ROLES AGE VERSION EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
linux-1n7n Ready <none> 3m v1.10.4 <none> openSUSE Tumbleweed Kubic 4.17.4-1-default docker://17.9.1
linux-e9u2 Ready master 41m v1.10.4 <none> openSUSE Tumbleweed Kubic 4.17.4-1-default docker://17.9.1
While this is a clean-room implementation (I didn't look at bootkube or kubeadm code to implement it at all), I took the
manifests and structure created by bootkube, and those manifests are present in this project to launch the bootstrap
control plane (apiserver, controller-manager and scheduler), and later on the "real" one.
While being a recreational project I find it interesting to continue experimenting with it. Some things I'd like to continue digging in:
Full containerization: the kubelet and etcd are two pieces that are not containerized in this project; however it would
be interesting to explore this. etcd has an etcd-operator project that would
make easier to properly containerize and manage etcd within the cluster itself.
Safe join (implemented by kubeadm already). This will probably include a 2-way trust channel (so the master knows about
the new node, and the new node can trust is talking to the right master before it tries to join).
Upgrade the cluster: (implemented by kubeadm already). How a cluster upgrade would be handled with this design, and in
the openSUSE Kubic context, how could we do the little orchestration needed to restart the Kubernetes workers in batches,
so they apply their new snapshot.
Certificates: would it make sense to use the own PKI to generate the very basic certificates to start the bootstrap server, and then use Kubernetes to generate the rest of certificates?
Refactors.
kubeception is licensed under the terms of the Apache 2.0 license.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Content type
Image
Digest
Size
746.4 MB
Last updated
about 8 years ago
docker pull ereslibre/kubeception