Kubernetes集群实践(十二)如何恢复etcd集群并重建k3s集群

本文主要介绍在etcd集群崩溃时如何恢复。

关键词:k8s

背景

本人在实习公司主要负责管理k8s集群工作。使用的发行版是v1.24.3+k3s1。

为什么使用k3s呢,主要因为这个搭建比较方便,只需要一个二进制文件就可以起来一个集群。

在搭建集群的时候,考虑要保证集群高可用,因此使用了官网提供的嵌入式DB的高可用 | Rancher文档方案。

网站上写了需要奇数的 server 节点,并且建议从三个节点开始

因为我们现在管理的集群比较小,因此就使用了两个节点作为server节点这为下文集群出现故障埋下了伏笔。

etcd 为了避免脑裂,采用了 raft 算法,规定只有过半数节点在线才能提供服务,即 N/2+1 节点在线才能选出 Leader。即如果有一个server挂了,那么集群就挂掉了!!

因为某些原因,我将集群中的一个server踢出了集群,此时集群就不可用了。具体表现为:

在master节点上执行kubectl get node无法正常回显。

于是就有了本文。

etcd集群恢复

当集群超过半数节点宕机,此时集群出于无法正常工作的状态,需要尽快恢复。

若机器宕机重启,IP保持不变,则证书无需重新生成;若IP更换,则还需要重新生成证书。

集群恢复还需要生成etcd的备份数据:使用etcdctl snapshot save命令备份或者从etcd数据目录复制snap/db文件。

将备份数据恢复至集群

首先明确k3s内置的etcd数据在/var/lib/rancher/k3s/server/db/etcd这个目录;

和etcd相关的证书在/var/lib/rancher/k3s/server/tls/etcd这个目录;

etcd配置文件在/var/lib/rancher/k3s/server/db/etcd/config这个文件。

以下操作都是在matser节点上执行的

  1. 将k3s相关服务先关闭

    1
    sudo systemctl stop k3s
  2. 安装一个etcd集群

    这里为了简化操作,使用一个etcd服务端代替集群。

    这里配置文件大部分还是使用原来k3s集群的配置文件,将数据的保存路径修改一下,安装完毕以后,将原有的etcd目录删除,然后启动etcd服务。

    1
    sudo etcd --config-file /newpath/etcd/config
  3. 使用etcd客户端执行恢复etcd数据命令,这里的证书还是原来k3s集群使用的证书

    1
    sudo etcdctl --endpoints=https://x.x.x.x:2379 --cert=client.crt --key=client.key --cacert=server-ca.crt --data-dir=/newpath/etcd/data snapshot restore snap/db
  4. 修改k3s服务端相关配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ExecStart=/usr/local/bin/k3s \
    server \
    '--disable=metrics-server' \
    '--flannel-backend=host-gw' \
    '--write-kubeconfig-mode=644' \
    '--datastore-endpoint=https://192.168.31.29:2379' \
    '--datastore-cafile=/var/lib/rancher/k3s/server/tls/etcd/server-ca.crt' \
    '--datastore-certfile=/var/lib/rancher/k3s/server/tls/etcd/server-client.crt' \
    '--datastore-keyfile=/var/lib/rancher/k3s/server/tls/etcd/server-client.key' \
    '--bind-address=192.168.31.29' \
    '--kube-scheduler-arg='config=/usr/local/etc/scheduler-policy-config.yaml'' \
  5. 重启k3s服务

    1
    systemctl restart k3s

    此时k3s 服务应该可以正常启动了,但是还会有些问题,如原来删除的节点的一些信息还存在etcd集群中,但是k3s apiserver中不存在相应的数据,此时只能执行强制删除操作。

    在master节点上执行

    1
    kubectl delete xxx --force --grace-period=0

​ 其中xxx代之相应的资源

  1. 如果还出现异常的话,需要链接到etcd服务端,直接执行删除操作:

    先查找所有的etcd对象

    1
    etcdctl.exe --cacert=certs\server-ca.crt --cert=certs\client.crt --key=certs\client.key --endpoints=https://192.168.31.29:2379 get ""  --prefix --keys-only

    然后删除和master节点有关的信息

    1
    etcdctl.exe --cacert=certs\server-ca.crt --cert=certs\client.crt --key=certs\client.key --endpoints=https://192.168.31.29:2379 del /registry/csinodes/pve-master
    1
    etcdctl.exe --cacert=certs\server-ca.crt --cert=certs\client.crt --key=certs\client.key --endpoints=https://192.168.31.29:2379 del /registry/csinodes/pve-master

完。