在类Unix操作系统中,ETC文件夹用于保存配置数据。同样,Kubernetes 使用 ETCD 来保存配置数据和集群信息。 ETCD 这个名称来自 ETC 文件夹,加上字母 D,代表分布式系统。
ETCD 是 Kubernetes 集群的键值数据存储。存储数据用于服务发现和集群管理。备份 ETCD 作为预防故障的措施非常重要。
为了与 etcd 交互,出于备份和恢复的目的,我们将使用命令行工具: etcdctl
etcdctl 有一个快照选项,可以相对轻松地备份集群。在下一节中,我将向您展示如何使用 etcdctl 快照选项备份 etcd 集群。
那么,让我们开始吧。
备份etcd集群
1.首先,我们需要确保安装了etcdctl。
etcdctl version
如果安装了 etcdctl,您将看到类似上面的输出,如果没有安装,它将给出“命令未找到”错误。
如果您有可用的 etcdctl,则可以跳过此步骤。如果没有,您可以按照此url中提供的步骤安装 etcdctl。您可以找到 Linux、MacOS 和 Docker 的安装指南
现在我们有了 etcdctl 命令行工具,我们可以开始拍摄集群当前状态的快照。然而,为了做到这一点,我们需要从 etcd 获取一些信息。
首先,我们需要有关端点的信息。如果我们在同一台服务器上运行 etcd,那么我们可以简单地添加
--endpoints=https://127.0.0.1:2379
127.0.0.1 是本地主机 IP,2379 是 etcd 的官方端口号。如果 etcd 在另一台服务器上运行,那么我们需要将 localhost ip 更改为该服务器的 ip。
其次,我们需要证书来向 ETCD 服务器进行身份验证以进行备份。所需的证书是
--cert,--cacert,--key
- 如何获取端点和证书信息?
好吧,我们可以从 etcd pod 中检索它们,etcd pod 的清单文件位于 /etc/kubernetes/manifests 文件夹下
我们可以使用以下命令检索有关端点的信息:
cat /etc/kubernetes/manifests/etcd.yaml | grep listen
只需检查 —listen-client-urls。
另一方面,我们可以通过以下命令获取证书信息。
cat /etc/kubernetes/manifests/etcd.yaml | grep file
- 获得必要的信息后,我们可以使用 etcdctl 运行快照保存命令。
ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
snapshot save <backup-file-location>
- 这里需要注意的一件事是我们需要将 ETCDCTL_API=3 放在命令的开头。 etcdctl 用于与 etcd 通信的 API 版本可以通过 ETCDCTL_API 环境变量设置为版本 2 或 3。但是,我们需要确保它默认为 v3 API 才能拍摄快照。
如果您不想每次输入命令时都输入该信息,可以使用以下命令设置环境变量 ETCDCTL_API=3。
export ETCDCTL_API=3
- 让我们运行快照保存命令并将快照保存为“etcd-backup.db”
干得好!我们现在有了 etcd 的备份!
(请注意输出的最后一行“snapshot saving at etcd-backup.db”,这表明快照保存过程成功)
从快照恢复etcd
前两个步骤不是恢复过程的一部分。不过,我展示它们是为了让您更容易理解当前 etcd 和恢复后的 etcd 之间的过渡。
- 我们看一下default命名空间下的Pod。正如您在整个备份过程中所看到的,我没有创建任何 Pod。当我运行 get pods 命令时,我将没有资源
- 我们拍摄的快照包含集群中的所有当前数据。现在我们将创建一个新的 pod,只是为了确保一旦我们从快照恢复 etcd 后它就不再存在,因为我们拍摄的快照在默认命名空间中没有这个特定的 pod 或任何其他 pod。
kubectl run newpod --image=nginx
- 现在,我们可以继续实际恢复 etcd。想象一下 etcd 因某种原因失败了,我们需要将其恢复到上次保存的状态。我们知道我们有一个之前保存的 etcd-backup.db。
ETCDCTL_API=3 etcdctl --data-dir="/var/lib/etcd-backup" \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
snapshot restore etcd-backup.db
- 我们创建一个新目录并将备份数据移至该目录中。但是,我们还没有更改 etcd 集群。如果您检查 pod,您会发现我们仍然有“newpod”,这不是备份过程的一部分。
- 如您所知,kubernetes 将静态 pod 的清单保存在 /etc/kubernetes/manifests 文件夹中。 etcd.yaml(etcd pod 的清单文件)也在那里。我们需要编辑该文件并确保它使用新恢复的数据目录作为卷而不是旧的。
vi /etc/kubernetes/manifests/etcd.yaml
更改etcd.yaml中的以下部分
这是更改后 etcd.yaml 的样子
- 此时,您需要等待几分钟,让 etcd pod 以新状态启动。同时你将无法从 apiserver 获得响应。
- 让我们通过检查默认命名空间中的 Pod 来验证我们是否已成功恢复快照。您还记得,我们拍摄了没有 pod 的快照,但随后我们创建了一个名为 newpod 的 pod。如果 newpod 仍然在这里,那么我们无法从备份中恢复。如果default命名空间中没有pod,那么我们就成功从备份中恢复了。
kubectl get pods
欢呼!我们成功了!
9.彩蛋
为啥修改了yaml文件,etcd就会重启启动了呢?
etcd的数据文件是在/var/lib/etcd这里存放,上面的解决方案是把文件还原到了/etc/lib/etcd-bakup,那么能不能还原到原来的位置呢?
当然可以,可是就会稍微复杂一些,如果etcd还在正常使用数据文件,还原是无法覆盖原来的文件,kubernetes是如何停止etcd和apiserver呢,就是把/etc/kubernetes/manifests/路径下的yaml文件移走,等还原之后,再把yaml文件复制回来,etcd和apiserver就会根据yaml文件重新启动