首页 > 其他分享 >23-最后的防线:怎样对 Kubernete 集群进行灾备和恢复?

23-最后的防线:怎样对 Kubernete 集群进行灾备和恢复?

时间:2024-01-11 13:58:12浏览次数:28  
标签:kubernetes Kubernetes 23 -- 备份 集群 etcd Kubernete 灾备

Kubernetes 隐藏了所有容器编排的复杂细节,让我们可以专注在应用本身,而无须过多关注如何去做部署和维护。此外,Kubernetes 还支持多副本,可以保证我们业务的高可用性。而对于集群本身而言,我们一样也要保证其高可用性,你可以参考官方文档:利用 Kubeadm 来创建高可用集群

但是这些并不足以让我们高枕无忧,因为 Kubernetes 在帮助我们编排调度容器的同时,往往还保存了很多关键数据,比如集群自身关键数据、密钥、业务配置信息、业务数据等。我们在使用 Kubernetes 的时候,非常有必要进行灾备,防止出现操作失误(比如大规模无删除)、自然灾害、磁盘损坏无法修复、网络异常、机房断电等情况导致的数据丢失,严重时甚至会导致整个集群不可用。

所以在使用 Kubernetes 的时候,我们最好做个灾备以方便对集群进行恢复,回滚到早期的一个稳定的状态。

Kubernetes 需要备份哪些东西

在对 Kubernetes 集群做备份之前,我们首先得知道要备份哪些东西。

我们从整个 Kubernetes 的架构为出发点,来看看整个集群的组件。我在《02 | 高屋建瓴:Kubernetes 的架构为什么是这样的?》中讲到 Kubernetes 的官方架构图,如下:

Drawing 0.png

图 1:Kubernetes 官方架构图

从上图可以看出,整个 Kubernetes 集群可分为Master 节点(左侧)和 Node 节点(右侧)。

在 Master 节点上,我们运行着 Etcd 集群以及 Kubernetes 控制面的几大组件,比如 kube-apiserver、kube-controller-manager、kube-scheduler 和 cloud-controller-manager(可选)等。

在这些组件中,除了 Etcd,其他都是无状态的服务。只要保证 Etcd 的数据正常,其他几个组件不管出现什么问题,我们都可以通过重启或者新建实例来解决,并不会受到任何影响。因此我们只需要备份 Etcd 中的数据

看完了 Master 节点,我们再来看看 Node 节点。

Node 节点上运行着 kubelet、kube-proxy 等服务。Kubelet 负责维护各个容器实例,以及容器使用到的存储。为了保证数据的持久化存储,对于关键业务的关键数据,我都建议通过我在《10 | 存储管理:怎样对业务数据进行持久化存储?》中提到的 PV(Persistent Volume)来保存和使用。鉴于这一点,我们还需要对 PV 进行备份

如果是节点出现了问题,我们可以向集群中增加新的节点,替换掉有问题的节点。

看完 Kubernetes 的官方架构图之后,下面我们就来看看该如何备份 Etcd 中的数据和 PV。

对 Etcd 数据进行备份及恢复

Etcd 官方也提供了备份的文档,你有兴趣可以阅读一下。我在这里总结了一些实际操作,以便你后续可以借鉴并进行手动的备份和恢复。命令行里面的一些证书路径以及 endpoint 地址需要根据自己的集群参数进行更改。实际操作代码如下:

# 0. 数据备份
ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--key=/etc/kubernetes/pki/etcd/peer.key \
--cert=/etc/kubernetes/pki/etcd/peer.crt \
snapshot save ./new.snapshot.db
# 1. 查看 etcd 集群的节点
ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 \ 
--cacert=/etc/kubernetes/pki/etcd/ca.crt \ 
--cert=/etc/kubernetes/pki/etcd/peer.crt \ 
--key=/etc/kubernetes/pki/etcd/peer.key \
member list
# 2. 停止所有节点上的 etcd!(注意是所有!!)
## 如果是 static pod,可以听过如下的命令进行 stop
## 如果是 systemd 管理的,可以通过 systemctl stop etcd
mv /etc/kubernetes/manifests/etcd.yaml /etc/kubernetes/
# 3. 数据清理
## 依次在每个节点上,移除 etcd 数据
rm -rf /var/lib/etcd
# 4. 数据恢复
## 依次在每个节点上,恢复 etcd 旧数据
## 里面的 name,initial-advertise-peer-urls,initial-cluster=controlplane
## 等参数,可以从 etcd pod 的 yaml 文件中获取到。
ETCDCTL_API=3 etcdctl snapshot restore ./old.snapshot.db \
--data-dir=/var/lib/etcd \
--name=controlplane \
--initial-advertise-peer-urls=https://172.17.0.18:2380 \
--initial-cluster=controlplane=https://172.17.0.18:2380
# 5. 恢复 etcd 服务
## 依次在每个节点上,拉起 etcd 服务
mv /etc/kubernetes/etcd.yaml /etc/kubernetes/manifests/
systemctl restart kubelet

上述这些备份,都需要手动运行命令行进行操作。如果你的 Etcd 集群是运行在 Kubernetes 集群中的,你可以通过以下的定时 Job (CronJob) 来帮你自动化、周期性(如下的 YAML 文件中会每分钟对 Etcd 进行一次备份)地备份 Etcd 的数据。关于 CronJob 部分的内容,我们在后面单独章节会进行介绍。自动备份代码如下:

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: backup
  namespace: kube-system
spec:
  # activeDeadlineSeconds: 100
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: backup
            # Same image as in /etc/kubernetes/manifests/etcd.yaml
            image: k8s.gcr.io/etcd:3.2.24
            env:
            - name: ETCDCTL_API
              value: "3"
            command: ["/bin/sh"]
            args: ["-c", "etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt --key=/etc/kubernetes/pki/etcd/healthcheck-client.key snapshot save /backup/etcd-snapshot-$(date +%Y-%m-%d_%H:%M:%S_%Z).db"]
            volumeMounts:
            - mountPath: /etc/kubernetes/pki/etcd
              name: etcd-certs
              readOnly: true
            - mountPath: /backup
              name: backup
          restartPolicy: OnFailure
          hostNetwork: true
          volumes:
          - name: etcd-certs
            hostPath:
              path: /etc/kubernetes/pki/etcd
              type: DirectoryOrCreate
          - name: backup
            hostPath:
              path: /data/backup
              type: DirectoryOrCreate

对 PV 的数据进行备份

对于 PV 来讲,备份就比较麻烦了。Kubernetes 自身不提供存储能力,它依赖各个存储插件对存储进行管理和使用。因此对于存储的备份操作,尤其是 PV 的备份操作,我们需要依赖各个云提供商的 API 来做 snapshot。

但是上述对于 Etcd 和 PV 的备份操作并不是很方便,我推荐你通过Velero来备份 Kubernetes。Velero 功能强大,但是操作起来很简单,它可以帮你做到以下 3 点:

  1. 对 Kubernets 集群做备份和恢复。

  2. 对集群进行迁移。

  3. 对集群的配置和对象进行复制,比如复制到其他的开发和测试集群中去。

而且 Velero 还提供针对单个 Namespace 进行备份的能力,如果你只想备份某些关键的业务和数据,这是一个十分方便的功能。

说了这么多,下满我们来看看 Velero 是如何备份 Kubernetes 的。

使用 Velero 对 Kubernetes 进行备份

这是 Velero 的架构图:

Drawing 1.png

图 2:Velero 架构图

Velero 由两部分组成:

  • 一个命令行客户端,你可以运行在本地,通过命令行完成对 Etcd 以及 PV 的备份操作;你也可以像使用 kubectl 操作 Kubernetes 资源一样备份 Kubernetes。

  • 一个运行在 kubernetes 集群中的服务(BackupController),负责执行具体的备份和恢复操作。

我们来看看具体使用时的流程:

  1. 通过本地 Velero 客户端发送备份命令,比如图中的velero backup create test-project-s2i --include-namespaces test,这条命令会向 APIServer 中创建一个 Backup 对象。

  2. BackupController 会去监测并验证这个 Backup 对象的合法性,比如参数的定义。

  3. BackupController 通过向 APIServer 查询相关数据开始备份工作。

  4. BackupController 将查询到的数据备份到远端的对象存储中。

Velero 在 Kubernetes 集群中创建了很多 CRD (Custome Resource Definition)以及相关的控制器,通过这些进行备份恢复等操作。因此,对集群的备份和恢复,实质上是对这些相关 CRD 的操作。BackupController 会根据 CRD 来确定该进行何种操作。我会在《27 | K8s CRD:如何根据需求自定义你的 API?》中专门介绍 CRD 的使用。

Velero 支持两种关于后端存储的 CRD,分别是 BackupStorageLocation 和 VolumeSnapshotLocation。

  • BackupStorageLocation 主要用来定义 Kubernetes 集群资源的数据存放位置,也就是集群对象数据,而不是 PVC 和 PV 的数据。你可以从这个支持列表里面找到目前官方和第三方支持的后端存储服务,主要是以支持 S3 兼容的存储为主,比如 AWS S3、阿里云 OSS、Minio 等。

  • VolumeSnapshotLocation 主要用来给 PV 做快照,快照功能通常由 Amazon EBS Volumes、Azure Managed Disks、Google Persistent Disks 等云厂商提供,你可以根据需要选择使用各个云厂商的服务。或者你使用专门的备份工具Restic,把 PV 数据备份到Azure Files、阿里云 OSS 中去。阿里云目前已经提供了基于 Velero 的插件

除此之外,BackupController 在工作过程中,还会创建其他的 CRD,主要用于内部的逻辑处理。你可以参考阿里云的文档进一步学习。

如果你没有阿里云的 OSS,或者集群是线下的内部集群,你也可以自行搭建 Minio,作为对象存储服务来代替阿里云的 OSS。你可以参考官方的文档进行详细的安装配置工作。

写在最后

在分布式的世界里,我们很难保证万无一失。当你在 Kubernetes 集群中部署越来越多的业务的时候,对集群和数据的灾备是非常有必要的。在今年 7 月份,我们常用的代码托管平台 Github 就发生了 Kubernetes 故障 ,导致了持续 4 个半小时的严重故障。所以,我建议对于关键性的业务数据,要记得时常备份。

那么,你对于 Kubernetes 的备份还有哪些想要了解的呢?欢迎在留言区留言。


标签:kubernetes,Kubernetes,23,--,备份,集群,etcd,Kubernete,灾备
From: https://www.cnblogs.com/huangjiale/p/17958424

相关文章

  • 26-网络插件:Kubernete 搞定网络原来可以如此简单?
    通过之前的学习,相信你对Kubernetes越来越熟悉了。理论上,Kubernetes可以跑在任何环境中,比如公有云、私有云、物理机、虚拟机、树莓派,但是任何基础设施(Infrastructure)对网络的需求都是最基本的。网络同时也是Kubernetes中比较复杂的一部分。我们今天就来聊聊Kubernetes中的......
  • 29-Kubernete 中也有定时任务吗?
    前面我们学习了Deployment、Statefulset、Daemonset这些工作负载,它们可以帮助我们在不同的场景下运行长伺型(LongRunning)的服务。但是有一类业务(一次性作业和定时任务)运行完就结束了,不需要长期运行,如果使用上述的那些工作负载就无法满足我们的要求。比如Pod运行结束后,会被De......
  • 28-面向 K8 编程:如何通过 Operator 扩展 Kubernete API?
    你好,我是正范。在上一讲,我们学习了如何通过一个YAML文件来定义一个CRD,即扩展API。这种扩展API跟Kubernetes内置的其他API同等地位,都可以通过kubectl或者REST接口访问,在使用过程中不会有任何差异。但只是定义一个CRD并没有什么作用。虽说kube-apiserver会将其数......
  • 08-配置管理:Kubernete 管理业务配置方式有哪些?配置管理:Kubernete 管理业务配置方式有
    通过前面几节课的学习,我们已经对Kubernetes中的Pod以及一些业务负载有所了解。你可以根据课程中提供的示例,自己动手尝试在集群中实践起来。在使用过程中,我们常常需要对Pod进行一些配置管理,比如参数配置文件怎么使用,敏感数据怎么保存传递,等等。有些人可能会觉得,为什么不把这......
  • 14-日志采集:如何在 Kubernete 中做日志收集与管理?
    说到日志,你应该不陌生。日志中不仅记录了代码运行的实时轨迹,往往还包含着一些关键的数据、错误信息,等等。日志方便我们进行分析统计及监控告警,尤其是在后期问题排查的时候,我们通过日志可以很方便地定位问题、现场复现及问题修复。日志也是做可观测性(Observability)必不可少的一部分......
  • 13-服务守护进程:如何在 Kubernete 中运行 DaemonSet 守护进程?
    通过前面课程的学习,我们对Kubernetes中一些常见工作负载已经有所了解。比如无状态工作负载Dployment可以帮助我们运行指定数目的服务副本,并维护其状态,而对于有状态服务来说,我们同样可以采用StatefulSet来做到这一点。但是,在实际使用的时候,有些场景,比如监控各个节点的状态,使......
  • 15-Prometheu:Kubernete 怎样实现自动化服务监控告警?
    通过之前的学习,我们已经对Kubernetes有了一定的理解,也知道如何在Kubernetes中部署自己的业务系统。Kubernetes强大的能力让我们非常方便地使用容器部署业务。Kubernetes自带的副本保持能力,可以避免部署的业务系统出现单点故障,提高可用性。各种探针也可以帮助我们对运行中的......
  • 17-案例实战:教你快速搭建 Kubernete 监控平台
    Prometheus和Grafana可以说是Kubernetes监控解决方案中最知名的两个。Prometheus负责收集、存储、查询数据,而Grafana负责将Prometheus中的数据进行可视化展示,当然Grafana还支持其他平台,比如ElasticSearch、InfluxDB、Graphite等。CNCF博客也将这两者称为黄金组合,目......
  • 16-迎战流量峰值:Kubernete 怎样控制业务的资源水位?
    通过前面的学习,相信你已经见识到了Kubernetes的强大能力,它能帮你轻松管理大规模的容器服务,尤其是面对复杂的环境时,比如节点异常、容器异常退出等,Kubernetes内部的Service、Deployment会动态地进行调整,比如增加新的副本、关联新的Pod等。当然Kubernetes的这种自动伸缩能......
  • 18-权限分析:Kubernete 集群权限管理那些事儿
    你好,我是正范。通过前面的课程学习,你已经学会了使用kubectl命令行,或者直接发送REST请求,以及使用各种语言的client库来跟APIServer进行交互。那么你是否知道在这其中Kubernetes是如何对这些请求进行认证、授权的呢?这节课,我们就来一探究竟。任何请求访问Kubernetes的kub......