Professional Documents
Culture Documents
HA Kubernetes1-3 PDF
HA Kubernetes1-3 PDF
Alexey Nizhegolenko
Follow
Jan 6 · 18 min read
Hi all, in this article I wanna sort and share some experience about creating
and using the internal Kubernetes cluster.
For the last few years this container orchestration tech made a great step
forward and became a some kind of corporate standard for the thousands of
companies. Some of them use it in production, some just test it inside their
projects, but anyway there is a strong passion about it in IT community. So
if you never used it before, it’s de nitely time to start dive in to it.
0. Preamble
Kubernetes it’s a scalable orchestration technology, it can start from single
node installation, up to the huge HA clusters, based on hundreds nodes
inside. Most of the popular cloud providers, represent the di erent kind of
Kubernetes implementations, so you can start using it very fast and easy in
there. But there is a lot of situations and lot of companies that can’t use
clouds for their needs, but they wanna get all bene ts from the modern
technologies of using containers also. And there bare metal Kubernetes
installation comes on the scene.
1. Introduction.
In this example we’ll create a HA Kubernetes cluster with multi masters
topology, with external Etcd cluster as base layer and a MetalLB load
balancer inside. On all worker nodes we’ll deploy a GlusterFS like a easy
internal distributed cluster storage. Also, we’ll try to deploy some test
projects in it, by using our private Docker registry.
Kubeadm it’s a tool that was created by Kubernetes community exactly for
simplifying the Kubernetes installation and making this process easier.
Previously Kubeadm was recommended only for creating small single
master test clusters, just for getting started purposes. But for the last year
there were many improvements done on it and now we can use it for
creating multi masters HA clusters also. According to Kubernetes
community news, Kubeadm will be a recommended tool for Kubernetes
installation in the future time.
For this Kubernetes cluster schema we’ll need eight nodes. A three servers
for external etcd cluster(also LB services will use pair of them), two for the
control plane nodes (master nodes) and three for the worker nodes. It can
be bare metal or VM servers, it doesn’t matter. You can simply change this
schema by add more masters and placing HAProxy with Heartbeat on
separated nodes, if you have a lot of free servers. But in fact my variant be a
quite enough for the rst HA cluster implementation.
Optionally you can also add a small server with installed kubectl utility,
for managing this cluster, or you can use your own Linux desktop for it.
Also, choose some public or private network for this cluster, it no really
matter, what kind of IPS you’ll use, important that all servers must be
reachable for each other and for you of course. Inside Kubernetes cluster
we’ll con gure an overlay network later.
Also, mind that system requirements depends on of how big and powerful
cluster you need. Read a Kubernetes documentation for the addition
information.
Let’s install and con gure HAProxy with Heartbeat on rst and second
Let’s install and con gure HAProxy with Heartbeat on rst and second
etcd servers(192.168.0.2–3 in this example):
etcd1# mv /etc/haproxy/haproxy.cfg{,.back}
etcd1# vi /etc/haproxy/haproxy.cfg
etcd2# mv /etc/haproxy/haproxy.cfg{,.back}
etcd2# vi /etc/haproxy/haproxy.cfg
global
user haproxy
group haproxy
defaults
mode http
log global
retries 2
timeout connect 3000ms
timeout server 5000ms
timeout client 5000ms
frontend kubernetes
bind 192.168.0.1:6443
option tcplog
mode tcp
default_backend kubernetes-master-nodes
backend kubernetes-master-nodes
mode tcp
balance roundrobin
option tcp-check
server k8s-master-0 192.168.0.5:6443 check fall 3 rise 2
server k8s-master-1 192.168.0.6:6443 check fall 3 rise 2
As you can see, both HAProxy services will use 192.168.0.1 shared IP
address. This virtual IP will move between servers, so we need to make
some trick and enable net.ipv4.ip_nonlocal_bind sysctl option, to
allow system services binding on the non-local IP.
Add to the le /etc/sysctl.conf this option:
etcd1# vi /etc/sysctl.conf
net.ipv4.ip_nonlocal_bind=1
etcd2# vi /etc/sysctl.conf
net.ipv4.ip_nonlocal_bind=1
Run on both:
sysctl -p
OK, now we’ll install Heartbeat and con gure this virtual IP.
Now it’s time to create a few con guration les for it, they will be mostly the
same for the rst and second servers.
Create a /etc/ha.d/authkeys le rst, in this le Heartbeat stored data
for authenticating each other. File must be the same on both servers:
etcd1# vi /etc/ha.d/authkeys
auth 1
1 md5 bb77d0d3b3f239fa5db73bdf27b8d29a
etcd2# vi /etc/ha.d/authkeys
auth 1
1 md5 bb77d0d3b3f239fa5db73bdf27b8d29a
Next let’s create a main con guration le for Heartbeat on both servers, it’ll
be a bit di erent for both of them.
Create /etc/ha.d/ha.cf:
etcd1
etcd1# vi /etc/ha.d/ha.cf
etcd2
etcd2# vi /etc/ha.d/ha.cf
The “node” parameters for this con g you can get by running uname -n on
both Etcd servers. Also, use your network card name instead of ens18.
etcd1# vi /etc/ha.d/haresources
etcd1_hostname 192.168.0.1
etcd2# vi /etc/ha.d/haresources
etcd1_hostname 192.168.0.1
After all done, let’s start our Heartbeat services on both servers, and check
that on etcd1 node we got this declared virtual IP up:
etcd1# ip a
# nc -v 192.168.0.1 6443
Connection to 93.158.95.90 6443 port [tcp/*] succeeded!
The main bene t of Kubeadm is that you not need a lot of addition
software you only need to install kubeadm on all your hosts and then
use it, you can even use it for the CA certi cates generation.
Install docker-ce.
# apt-get update && apt-get -y install docker-ce
kubelet : the component that runs on all of the machines in your cluster
You can install kubectl optionally, but I often install it on all nodes, to
get availability to run some Kubernetes command for the debugging
reasons.
Add the Google repository key
# curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg |
apt-key add -
After you nish with installing kubeadm and rest packages, don’t forget
to disable swap.
# swapoff -a
Before we begin make sure that all etcd nodes can talk to each other over
ports 2379 and 2380, also you need to con gure a ssh access between them
for using scp.
We’ll start on the rst etcd node, and then just copy all needed certi cates
We’ll start on the rst etcd node, and then just copy all needed certi cates
and con g les on rest servers.
On all etcd nodes we need to add a new systemd con g le, for the
kubelet unit, with higher precedence:
Then ssh to the rst etcd node, we’ll use this node to generate all needed
kubeadm con gs for each etcd nodes and then will copy them.
# Export all our etcd nodes IP's as variables
etcd1# export HOST0=192.168.0.2
etcd1# export HOST1=192.168.0.3
etcd1# export HOST2=192.168.0.4
HOST=${ETCDHOSTS[$i]}
NAME=${NAMES[$i]}
done
etcd1# ls /etc/kubernetes/pki/etcd/
ca.crt ca.key
Now let’s generate certi cates for all our etcd nodes:
### Create certificates for the etcd3 node
etcd1# kubeadm init phase certs etcd-server --
config=/tmp/${HOST2}/kubeadmcfg.yaml
etcd1# kubeadm init phase certs etcd-peer --
config=/tmp/${HOST2}/kubeadmcfg.yaml
etcd1# kubeadm init phase certs etcd-healthcheck-client --
config=/tmp/${HOST2}/kubeadmcfg.yaml
etcd1# kubeadm init phase certs apiserver-etcd-client --
config=/tmp/${HOST2}/kubeadmcfg.yaml
etcd1# cp -R /etc/kubernetes/pki /tmp/${HOST2}/
Then let’s copy certi cates and kubeadm con gs to the etcd2 and etcd3
nodes.
First generate a ssh key pair on etcd1 and add public part to the etcd2
& 3 nodes. In this example all commands be done from the root user.
etcd1# scp -r /tmp/${HOST1}/* ${HOST1}:
etcd1# scp -r /tmp/${HOST2}/* ${HOST2}:
Ensure that les exist on all nodes before starting the etcd cluster:
/tmp/192.168.0.2
└── kubeadmcfg.yaml
---
/etc/kubernetes/pki
├── apiserver-etcd-client.crt
├── apiserver-etcd-client.key
└── etcd
├── ca.crt
├── ca.key
├── healthcheck-client.crt
├── healthcheck-client.key
├── peer.crt
├── peer.key
├── server.crt
└── server.key
/root
└── kubeadmcfg.yaml
---
/etc/kubernetes/pki
├── apiserver-etcd-client.crt
├── apiserver-etcd-client.key
└── etcd
├── ca.crt
├── healthcheck-client.crt
├── healthcheck-client.key
├── peer.crt
├── peer.key
├── server.crt
└── server.key
After all certi cates and con gs now in place we need to create the
manifests. On each node run the kubeadm command to generate a static
manifest for etcd cluster:
After that etcd cluster must be con gured and healthy, we can check it by
running this command on etcd1 node:
apiVersion: kubeadm.k8s.io/v1beta1
kind: ClusterConfiguration
kubernetesVersion: stable
apiServer:
certSANs:
- "192.168.0.1"
controlPlaneEndpoint: "192.168.0.1:6443"
etcd:
external:
endpoints:
- https://192.168.0.2:2379
- https://192.168.0.3:2379
- https://192.168.0.4:2379
caFile: /etc/kubernetes/pki/etcd/ca.crt
certFile: /etc/kubernetes/pki/apiserver-etcd-client.crt
keyFile: /etc/kubernetes/pki/apiserver-etcd-client.key
Move the previously copied certi cates and key to the properly directory on
master1 as we listed in con g.
If all previous steps was done right you will see this:
You can now join any number of machines by running the following on
each node
as root:
Copy this kubeadm init output to some text le, we’ll use this token in
future when will join the second master and worker nodes to our cluster.
As I said previously our Kubernetes cluster will use some overlay network
inside, for the Pods and other services, so at this point we need to install
some CNI plugin. I recommend a Weave CNI plugin, after some experience I
found it more useful and less problem, but you can choose another one like
Calico or other.
Wait a little and type next command for checking that pods of the
components get started:
master1# kubectl --kubeconfig /etc/kubernetes/admin.conf get pod -
n kube-system -w
It’s recommended to join new control plane nodes only after the rst
node has nished initializing.
Cool, the rst master node is UP and ready, now we can add second master
node and add our workers nodes, to complete the Kubernetes cluster
creation.
For adding a second master node make some ssh key on master1 and add
public part to the master2 node. Make test login and then copy some les
from the rst master node to the second:
master2#
mkdir -p /etc/kubernetes/pki/etcd
mv /root/ca.crt /etc/kubernetes/pki/
mv /root/ca.key /etc/kubernetes/pki/
mv /root/sa.pub /etc/kubernetes/pki/
mv /root/sa.key /etc/kubernetes/pki/
mv /root/apiserver-etcd-client.crt /etc/kubernetes/pki/
mv /root/apiserver-etcd-client.key /etc/kubernetes/pki/
mv /root/front-proxy-ca.crt /etc/kubernetes/pki/
mv /root/front-proxy-ca.key /etc/kubernetes/pki/
mv /root/etcd-ca.crt /etc/kubernetes/pki/etcd/ca.crt
mv /root/admin.conf /etc/kubernetes/admin.conf
Now let’s join the second master node to the cluster, for this we’ll need a join
command output, that was previously given to us by kubeadm init on the
rst node.
Run on master2:
Wait a bit before node complete joining the cluster and check the new
cluster state:
Also check that all pods from all master nodes started OK:
master1# kubectl — kubeconfig /etc/kubernetes/admin.conf get pod -n
kube-system -w
Well done, we almost nished with our Kubernetes cluster con guration,
the last thing we need to do, it’s add the three worker nodes that we
prepared previously.
Login to worker nodes and run the kubeadm join command without --
experimental-control-plane ag.
As you can see we now have a fully con gured HA Kubernetes cluster with
two master nodes and three worker nodes. This cluster based on a HA etcd
cluster with fault tolerance load balancer in front of our masters. Sounds
good as for me.
Good, now let’s run some test pod in our cluster and check how it works.
Congrats, you just run your rst Kubernetes deployment. And it means your
new HA Kubernetes cluster ready. Actually Kubernetes cluster con guration
process using kubeadm a pretty easy and fast.
In the next part of article we’ll add the internal storage by con guring a
GlusterFS on all worker nodes, and will con gure an internal load balancer
for our Kubernetes cluster and also run some stress tests by shutdown some
nodes and check how stable cluster can be.
Afterwords
Well, implementing this example you can meet some problems, don’t
worry, for canceling any changes and returning your nodes to the base state
you can just run kubeadm reset, it’ll totally remove all changes that
kubeadm was done before and you can start your con guration from
scratch again. Also, mind checking a docker containers state on your cluster
nodes, to be sure that all of them starts and working without error. For
getting more info about bad containers use docker logs container
id.
If this post was helpful, please click the clap button below a
few times to show your support for the author! ⬇
WRITTEN BY
Alexey Nizhegolenko
Follow
Faun
Follow
Discover Medium
Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Make Medium yours
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Become a member
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade
AboutHelpLegal