3 servers are too many! I have only one!
OpenShift has a single-node installation. Can you do the same with pure Kubernetes?
Last time, we installed Kubernetes on IBM Power using kubeadm. It was easy and fast. But you need at least three servers for the installation! Not the biggest problem unless you don’t have them. I don’t want to install and operate three servers for a development Kubernetes cluster. I want to have only one server with Kubernetes and no cluster. Is it possible?
Yes, it is possible! It will probably be the shortest newsletter in one year. Why? Because you already have everything you need. We must change only one part of the playbook, and it is ready for single-node Kubernetes installation!
Before we start
Because I create a single-node installation, my inventory is very simple today:
kube ansible_host=10.11.0.10 ansible_user=root ansible_password=P@ssw0rd
You also need the playbook from the last newsletter because we will change it.
Firewall
I last installed the Kubernetes cluster on Ubuntu. This time, I am installing it on Red Hat Enterprise Linux 9. There is a subtle difference between these two installations in my environment. Ubuntu has no firewall by default, while Red Hat has one. Again, it is in my environment, and your environment may be (is) different.
I must either disable FirewallD in Red Hat Enterprise Linux or open ports. I will do the second:
- name: Open Kubernetes ports
ansible.posix.firewalld:
port: "{{ item }}/tcp"
permanent: true
state: enabled
loop:
- 6443
- 10250
Remove host conditions
When we install a Kubernetes cluster, we need to perform some tasks on the control plane and some on the worker nodes. If we have a single-node installation, all tasks are performed on our single node, so we don’t need any conditions anymore.
Find all lines like:
when: inventory_hostname == groups.apiserver.0
and remove them.
Remove join commands and node roles
We have a single node. There is no need to join any other node to our cluster, and we no longer distinguish between node roles.
Find the code below in your playbook and remove it completely:
- name: Get join command from control plane
ansible.builtin.command:
cmd: /usr/local/bin/kubeadm token create --print-join-command
when: inventory_hostname == groups.apiserver.0
register: joincmd
- name: Stop if there is no join command
ansible.builtin.fail:
msg: "Join command is undefined"
when: hostvars[groups.apiserver.0].joincmd is undefined
- name: Join rest of control planes to the cluster
ansible.builtin.command:
cmd: "{{ hostvars[groups.apiserver.0].joincmd.stdout_lines.0 }}"
when: inventory_hostname in groups['apiserver'] and inventory_hostname != groups.apiserver.0
- name: Set control plane role
ansible.builtin.command:
cmd: "kubectl label node {{ item }}.{{ domain }} node-role.kubernetes.io/control-plane=''"
environment:
KUBECONFIG: /etc/kubernetes/admin.conf
when: inventory_hostname == groups.apiserver.0
loop: "{{ groups['apiserver'] }}"
- name: Join worker nodes to the cluster
ansible.builtin.command:
cmd: "{{ hostvars[groups.apiserver.0].joincmd.stdout_lines.0 }}"
when: inventory_hostname in groups['workers']
- name: Set worker node role
ansible.builtin.command:
cmd: "kubectl label node {{ item }}.{{ domain }} node-role.kubernetes.io/worker=''"
environment:
KUBECONFIG: /etc/kubernetes/admin.conf
when: inventory_hostname == groups.apiserver.0
loop: "{{ groups['workers'] }}"
Enable workloads on our single node
After we created the single-node “cluster”, our node is the control node by default and doesn’t accept any workload. We must “untaint” the node and enable workloads on it. It is one (only one!) command:
- name: Untaint nodes
ansible.builtin.command:
cmd: "kubectl taint nodes --all node-role.kubernetes.io/control-plane-"
environment:
KUBECONFIG: /etc/kubernetes/admin.conf
Join me at Common Europe Congress 2025!
If you are in Europe, you are welcome to join me at the Common Europe Congress 2025. Even if you are not in Europe, you are still welcome!
The Common Europe Congress 2025 will be held from June 2nd to 5th in Gothenburg, Sweden, in a very beautiful place—Gothia Towers. Sweden is always beautiful, especially its nature. I like visiting Sweden, and I am there at least once every year.
The agenda for the Congress is already published. Last years it was the biggest IBM Power-related event in Europe. Just take a second and think about it. The biggest IBM Power event in Europe is organized by volunteers, not IBM. This is the reason to be there. This is not a marketing injection made by IBM, but real gurus and practitioners from all parts of Europe. You usually pay tons of money to get them to your site. The Congress costs just a fraction of their daily price, and you can ask your questions on all three days.
The early bird price is only 1020€ and valid till May 1st. If you are a member of a local Common country group, your price may even be lower (or zero). You can register here.
Remember to say hello to me in Sweden! By the way, “hello” in Swedish is “Hej.”
Your Kubernetes single-node installation is ready to use!
There are no other changes in the playbook you should make. Prepare a Linux on IBM Power server, execute your playbook, and your new Kubernetes single-node installation is ready to use.
One, two, three…
Have fun with your new Kubernetes single-node installation!
Andrey
Hi, I am Andrey Klyachkin, IBM Champion and IBM AIX Community Advocate. This means I don’t work for IBM. Over the last twenty years, I have worked with many different IBM Power customers all over the world, both on-premise and in the cloud. I specialize in automating IBM Power infrastructures, making them even more robust and agile. I co-authored several IBM Redbooks and IBM Power certifications. I am an active Red Hat Certified Engineer and Instructor.
Follow me on LinkedIn, Twitter and YouTube.
You can meet me at events like IBM TechXchange, the Common Europe Congress, and GSE Germany’s IBM Power Working Group sessions.