使用kubeadm搭建一个高可用k8s集群

这是一篇关于如何使用kubeadm工具搭建Kubernetes集群的文章。
kubeadm是由kubernetes官方社区维护的一款kubernetes集群部署工具,kubeadm会帮我们部署kubernetes里的一些关键服务,以及一些必要的证书,Kubeadm还会通过运行一系列预检查来确保服务器具有运行Kubernetes所需的所有必要组件和配置,从而使整个部署过程变得简单。

集群整体架构

这里采用kubernetes官网的图片进行说明:

捕获.PNG
如图,每个控制面节点都运行一份API服务器(kube-apiserver)、调度器(kube-scheduler)和控制器管理器(kube-controller-manager)实例。API服务器通过负载均衡器暴露给工作节点。etcd分布式数据库分别运行一个实例在控制面节点上,而且每个控制面节点的API服务器只会与本机的etcd实例进行通信。

集群整体硬件配置

这次的部署是在虚拟机上进行的,总共使用了7台虚拟机,都是Ubuntu 22.04.2 LTS系统,详细如下:

主机名 IP CPU Mem 作用
haproxy1 192.168.1.9 2核 2G 负载均衡器
haproxy2 192.168.1.10 2核 2G 负载均衡器
control1 192.168.1.4 2核 2G 控制面节点
control2 192.168.1.5 2核 2G 控制面节点
contorl3 192.168.1.6 2核 2G 控制面节点
work1 192.168.1.7 2核 2G 工作节点
work2 192.168.1.8 2核 2G 工作节点

控制面节点就是我们所说的主节点,只不过kubernetes官网称为控制面节点。

如上表所示,由于是在我的个人电脑上部署,所以每个虚拟机分配的资源并不多,不过已经足够跑起来了。

我们还要确保每个节点上主机名、MAC地址和product_uuid的唯一性。主机名可以通过hostname命令查看,然后通过hostnamectl set-hostname 新主机名设置;MAC地址可以通过ip link查看;product_uuid可以通过cat /sys/class/dmi/id/product_uuid查看。

控制面节点和工作节点还需禁用交换分区:

swapoff -a
(crontab -l 2>/dev/null; echo "@reboot /sbin/swapoff -a") | crontab - || true

必要端口开放设置

请确保在防火墙配置中允许这些端口:

控制面节点:

捕获.PNG

工作节点:

捕获.PNG

工作节点里的端口范围30000-32767主要用于NodePort型的网络服务。

ubuntu系统中防火墙相关命令有:ufw allow 端口号ufw enableufw status

配置Kubernetes运行所需的内核模块和网络参数

在每个节点进行如下配置。

加载并启用Linux文件系统层叠功能模块和桥接设备的网络过滤模块:

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF


modprobe overlay
modprobe br_netfilter

配置Linux网络内核参数:

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1 #这个参数设置 Linux 桥接设备在进行网络地址转换 (NAT) 时调用 iptables 进行数据包处理。
net.bridge.bridge-nf-call-ip6tables = 1 #类似于上一个参数,但针对 IPv6 数据包。
net.ipv4.ip_forward                 = 1 #这个参数启用 Linux 内核的 IP 转发功能,允许系统将接收到的数据包从一个网络接口路由到另一个网络接口.
EOF

#重新加载sysctl配置,以应用新的参数设置。--system 选项表示从/etc/sysctl.conf和/etc/sysctl.d/目录中的配置文件加载参数,并将这些参数应用到系统。
sysctl --system

安装负载均衡器

负载均衡器是实现集群高可用的关键,用于代理三台控制面节点的6443端口,也就是API服务器(kube-apiserver)。这里我们将使用两个节点(haproxy1和haproxy2)来部署负载均衡器,其中一个作为主负载均衡器,另一个作为备用。采用的技术架构是keepalived 和 HAProxy

Keepalived简单来讲就是一个主备切换工具,备用节点会不断的对主节点进行探活,当主节点故障时,备用节点会替代主节点进行工作,下文会大概介绍下它的工作原理。

HAProxy则是一款负载均衡器和代理服务器软件,这里不做过多介绍。

下面开始负载均衡器的具体搭建:

在节点haproxy1编写配置文件/etc/keepalived/keepalived.conf
! /etc/keepalived/keepalived.conf

! Configuration File for keepalived

global_defs {

    router_id LVS_DEVEL

}

vrrp_script check_apiserver {

  script "/etc/keepalived/check_apiserver.sh"

  interval 3

  weight -2

  fall 10

  rise 2

}



vrrp_instance VI_1 {

    state MASTER
    interface ens33

    virtual_router_id 51

    priority 101
    authentication {

        auth_type PASS

        auth_pass 42

    }

    virtual_ipaddress {

        192.168.1.120

    }

    track_script {

        check_apiserver

    }

}

上述文件里的一些关键配置:

  • vrrp_script: 配置的是Keepalived的探活脚本,后面将会提到;
  • state:只有MASTERBACKUP两种值,用于区分主备,节点haproxy1是主,所以这里写MASTER;
  • interface:网卡名;
  • virtaul_router_id:用于区分所属子网,在同一个kubernetes集群中所有Keepalived节点都配置相同的即可;
  • priority:优先级,主节点要高于备用节点才行;
  • auth_pass:用于Keepalived节点之间的认证,要配置成一样的;
  • virtual_ipaddress:这是一个关键配置,当所有Keepalived节点运行时,它们都会拥有一个相同的虚拟IP,而只有主Keepalived节点会通过ARP协议对外宣称拥有这个虚拟IP,而其它备用节点则会保持缄默。当备用节点发现主节点挂掉时,则会替代主节点对外宣称拥有这个虚拟IP,这就是Keepalived主备切换的大概原理;
在节点haproxy2编写配置文件/etc/keepalived/keepalived.conf
! /etc/keepalived/keepalived.conf

! Configuration File for keepalived

global_defs {

    router_id LVS_DEVEL

}

vrrp_script check_apiserver {

  script "/etc/keepalived/check_apiserver.sh"

  interval 3

  weight -2

  fall 10

  rise 2

}



vrrp_instance VI_1 {

    state BACKUP
    interface ens33

    virtual_router_id 51

    priority 100
    authentication {

        auth_type PASS

        auth_pass 42

    }

    virtual_ipaddress {

        192.168.1.120

    }

    track_script {

        check_apiserver

    }

}

配置和节点haproxy1的基本一样,主要是statepriority这两个配置不同。

在节点haproxy1和haproxy2编写探活脚本/etc/keepalived/check_apiserver.sh
#!/bin/sh
# /etc/keepalived/check_apiserver.sh
APISERVER_DEST_PORT=6443
APISERVER_VIP="192.168.1.120"
errorExit() {
    echo "*** $*" 1>&2
    exit 1
}
curl --silent --max-time 2 --insecure https://localhost:${APISERVER_DEST_PORT}/ -o /dev/null || errorExit "Error GET https://localhost:${APISERVER_DEST_PORT}/"
if ip addr | grep -q ${APISERVER_VIP}; then
    curl --silent --max-time 2 --insecure https://${APISERVER_VIP}:${APISERVER_DEST_PORT}/ -o /dev/null || errorExit "Error GET https://${APISERVER_VIP}:${APISERVER_DEST_PORT}/"
fi
在节点haproxy1和haproxy2安装并运行Keepalived

运行以下命令进行安装:

apt-get update

apt-get install keepalived
systemctl enable keepalived --now

安装完成后,我们发现节点haproxy1和haproxy2都有了虚拟IP192.168.1.120

捕获.PNG

捕获.PNG

在节点haproxy1和haproxy2安装并运行HAProxy

运行以下命令进行安装:

apt-get update

apt-get install haproxy
systemctl enable haproxy --now
在节点haproxy1和haproxy2替换配置文件/etc/haproxy/haproxy.cfg,并重启HAProxy服务
# /etc/haproxy/haproxy.cfg
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
    log /dev/log local0
    log /dev/log local1 notice
    daemon

#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 1
    timeout http-request    10s
    timeout queue           20s
    timeout connect         5s
    timeout client          20s
    timeout server          20s
    timeout http-keep-alive 10s
    timeout check           10s

#---------------------------------------------------------------------
# apiserver frontend which proxys to the control plane nodes
#---------------------------------------------------------------------
frontend apiserver
    bind 0.0.0.0:6443
    mode tcp
    option tcplog
    default_backend apiserver

#---------------------------------------------------------------------
# round robin balancing for apiserver
#---------------------------------------------------------------------
backend apiserver
    mode tcp
    option tcp-check
    balance roundrobin
        server control1 192.168.1.4:6443 check
        server control2 192.168.1.5:6443 check
        server contorl3 192.168.1.6:6443 check

重启HAProxy:systemctl restart haproxy.service

通过配置文件我们可以看到HAProxy绑定了本地的6443端口,并且将请求转发到后面的三个控制面节点。

到这里我们两个节点的负载均衡器就搭建完成了,不过这时候你会看到HAProxy不停报后端不可达的错误,这是正常的,因为我们的控制面节点还没有搭建。

在控制面节点和工作节点安装容器运行时

我们采用containerd作为容器运行时。
执行以下命令来安装containerd:

apt update
apt install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
apt update
apt install containerd.io

然后我们初始下containerd的默认配置:

containerd config default | tee /etc/containerd/config.toml

我们还需要把containerd的cgroup驱动设置为systemd,在配置文件/etc/containerd/config.toml里设置:

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
  ...

  [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
    SystemdCgroup = true

我们还要给containerd配置一个国内的sanbox镜像文件,不然可能会出现拉取不了镜像的问题,在配置文件/etc/containerd/config.toml里设置:

[plugins."io.containerd.grpc.v1.cri"]
  ...

  sandbox_image = "registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9"

重启containerd:systemctl restart containerd.service

在控制面节点和工作节点安装kubeadm、kubectl、kubelet工具

apt-get update && apt-get install -y apt-transport-https
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add - 
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list 
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF  
apt-get update
apt-get install -y kubelet kubeadm kubectl
apt-mark hold kubelet kubeadm kubectl

工作节点可以不安装kubectl。

在节点control1执行kubeadm init

kubeadm init --pod-network-cidr="10.51.32.0/24" --node-name "control1" --control-plane-endpoint "192.168.1.120:6443" --upload-certs --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers

其中,

--pod-network-cidr配置的是我们kubernetes内部的网络段;

--control-plane-endpoint配置的是我们虚拟IP;

--upload-certs表示要将kubeadm自动生成的证书上传至etcd,因为我们是多控制面节点,其它节点加入时可以从etcd获取相关证书信息;

--image-repository是用来配置国内镜像源,因为kubeadm初始化时,会自动安装API服务器(kube-apiserver)、调度器(kube-scheduler)、控制器管理器(kube-controller-manager)和etcd等这些必要组件,
而且这些组件都是以pod的形式运行,所以配置个国内镜像源,这些pod的yaml文件都会被kubeadm在初始化时放在/etc/kubernetes/manifests

kubeadm init命令运行成功后,我们将会看到这样的一个输出:


...
You can now join any number of control-plane node by running the following command on each as a root:
    kubeadm join 192.168.1.120:6443 --token 9vr73a.a8uxyaju799qwdjv --discovery-token-ca-cert-hash sha256:7c2e69131a36ae2a042a339b33381c6d0d43887e2de83720eff5359e26aec866 --control-plane --certificate-key f8902e114ef118304e561c3ecd4d0b543adc226b7a07f675f56564185ffe0c07


Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use kubeadm init phase upload-certs to reload certs afterward.

Then you can join any number of worker nodes by running the following on each as root:
    kubeadm join 192.168.1.120:6443 --token 9vr73a.a8uxyaju799qwdjv --discovery-token-ca-cert-hash sha256:7c2e69131a36ae2a042a339b33381c6d0d43887e2de83720eff5359e26aec866

这里有两种kubeadm join命令,一种用于控制面节点的加入,另一种用于工作节点的加入。

在其余控制面节点和工作节点分别执行对应的kubeadm join命令

都加入完成后,我们可以执行kubectl get nodes -o wide命令查看节点状态。

安装calico网络组件

安装calico组件前,还需让各节点开放179端口。
执行以下命令进行安装:

curl https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml -o calico.yaml
kubectl apply -f calico.yaml

执行apply后,你可能发现你的calico组件pod一直在重启,那可能是因为它不知道关联主机上的哪个网络接口,所以用这一步指定calico使用哪个网络接口,我的虚拟机网络接口都是ens33,所以我就写成ens*,各位可根据自身情况配置,比如eth* 等等:

kubectl set env daemonset/calico-node -n kube-system IP_AUTODETECTION_METHOD=interface=ens*

安装Metrics Server

安装Metrics Server组件前,还需让各节点开放4443端口。

# 记得修改yaml文件里使用的镜像为国内源,不然你可能拉取不到镜像,比如配置成:registry.aliyuncs.com/google_containers/metrics-server:v0.6.2
curl  https://raw.githubusercontent.com/techiescamp/kubeadm-scripts/main/manifests/metrics-server.yaml -o metrics.yaml
kubectl apply -f metrics.yaml

完成

这些步骤都正常执行完成后,通过kubectl get pods -n kube-system你应该就能够看到集群里的pod状态了:

捕获.PNG

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYHa3EV6' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片