越来越多的K8S应用采用RedHat OpenShift进行部署,IT团队需要部署容灾功能,来防范系统崩溃导致业务受损。一部分行业通常有较强的监管要求,在出现大规模错误的时候必须有数据保护。例如HIPAA 监管要求中的CFR 164.308(7)(ii)(B),要求公司必须能够在出现系统错误的时候“恢复所有数据”。这种情况下对于Openshift上的关键应用来说,容灾是必须的。本文讲解了用户如何使用OpenShift和Portworx来实现零RPO的容灾。Portworx是Redhad容器目录认证的厂商,在OperaterHub上也有经过认证的Operator。能够为Red Hat客户提供完整的OpenShift体验。在我们进入如何在OpenShift上达到零RPO容灾之前,让我们首先来分析一下,传统的容灾方案为什么不适用于K8S。传统的备份和恢复方案是在虚拟机(VM)层面来实现的。如果一个单一应用运行在单一虚拟机上,这种方案很合适。因为备份虚拟机和备份应用一样的。而运行在OpenShift上的容器化应用,却很不一样。一个虚拟机通常可以运行多个Pods,但不是所有的这些Pods都是为一个应用服务的。同样,一个应用也可能跨越多个虚拟机。容器化应用的通常架构模式中应用是分布在一组服务器集群上的。所以仅仅备份虚拟机就不合适了。要么过多备份了无用的内容,要么没有备份关键的应用数据。例如我想备份应用A,备份虚拟机的过程中,也会备份包括应用B和应用C的数据,这就会导致过多的备份。如果我备份了整个VM,而应用A运行在其他VM上的部分就没有被有效的备份,这就导致没有备份关键的应用数据。
为了解决这个问题,Openshift上的容灾需要的解决方案应是:
- 容器颗粒度的
- Kubernetes命名空间可感知的
- 应用一致的
- 能够备份数据和应用配置
- 能够为数据中心提供同步和异步备份的不同方式
Portworx企业版数据平台的PX-DR就是按照以上的原则设计的。容器颗粒度的Openshift容灾PX-DR是一个容器颗粒度的DR方案。它不是去备份VM或者物理机上的所有数据,而是备份运行在主机上的特定的Pod,或者备份一组Pod。在下面的图中,我们看到一个3节点的OpenShift集群、一个三节点的Cassandra环,和三个单独节点的PostgreSQL数据库。
通过PX-DR我们可以去备份我们想要备份的特定Pods。例如,我们想备份3节点的Cassandra环,或者想备份一个单独的PostgreSQL数据库。通过提供容器颗粒度的备份,我们避免了在备份所有VM过程中复杂的数据提取,转化和加载(ETL)过程。通过仅仅备份单独的应用,我们可以大量节省存储成本,以及保持很低的RTO。
对整个Kubernetes命名空间的容灾具备容器颗粒度的备份代表我们也可以对整个命名空间进行备份。Kubernetes上的命名空间,通常可以运行有关联的一组应用。例如,某企业的一个命名空间代表了该企业的一个分支机构的所有应用。通常在备份命名空间的时候,我们会备份整个命名空间,而不是仅备份命名空间里的某一个应用。传统的备份方案是无法对命名空间进行备份的,因为命名空间是跨VM边界的。PX-DR,可以备份整个命名空间,不论与这个命名空间关联的Pods在哪里。对 OpenShift备份过程中保持应用的一致性PX-DR可以保持应用的一致性。如上面的例子,3个Cassandr pods是一个分布式系统。通过对它们进行快照的过程中,如果需要支持应用在无数据损失的情况下恢复,就需要在快照过程中保持所有的Pods被锁定。对VM进行快照无法锁定所有Pods。而进行系列快照也不能达到。Portworx提供了Kubernetes组快照规则引擎,允许Operators自动的执行前置和后置快照命令。例如对Cassandra,我们必须运行nodetool flush命令来达到对多个Cassandra容器快照过程中保持应用的一致性。
apiVersion: stork.libopenstorage.org/v1alpha1
kind: Rule
metadata:
name: cassandra-presnap-rule
spec:
– podSelector:
app: cassandra
actions:
– type: command
value: nodetool flush
为Openshift应用备份数据和应用配置我们已经叙述了容器颗粒度备份、命名空间感知、应用一致性备份的重要性。现在我们来看一下为什么OpenShift的DR要求能够备份数据和应用配置。在OpenShift上备份和恢复一个应用需要两件事情:数据、和应用配置。如果我们仅仅备份数据,恢复应用的时间会非常长,因为我们需要重建应用配置,会增加RTO。如果我们仅仅备份应用的配置 – 所有的Yaml文件(定义了应用的部署、服务账户、PVCs等),但我们却没有应用数据。因此我们需要同时备份应用数据和应用配置。PX-DR可以通过一个OpenShift命令备份应用数据和应用配置。恢复OpenShift应用的时候使用 `oc -f apply myapp.yml` 命令,因为恢复应用的过程与最初部署应用过程是一样的。
对Openshift的同步或异步DR针对我们的目标和数据中心的不同架构,我们可以选择正确的OpenShift容灾策略。我们可以选择同步或者异步的备份模式。在一些情况下,也可以同时选取同步和异步备份,因为同步和异步提供了不同层级的系统保护。
例如,一个银行有本地部署的数据中心,并且通过专线连接到了一个AWS数据中心,可能会需要为一个重要商业应用选择零RPO的DR策略,同时要求RTO<1分钟。在这种情况下,我们倾向于推荐同步备份的PX-DR,由于两个环境的延时极低,因此可以提供零数据损失的恢复。
另一个例子,如果一个制造业的公司在较远的两地有两个数据中心,应用要求较低的RTO,但按每小时的备份频率对于RPO的目标来说已经足够了,在这种情况下,异步备份的PX-DR,使用连续增量式的备份就已经足够。
下面是不同情况下OpenShift DR策略的选择
较远网络的OpenShift容灾策略(两个站点之间的往返延迟 >10毫秒的情况)
近距离网络的OpenShift的容灾策略(两个站点之间的往返延迟 < 10毫秒的情况)
如何在OpenShift上通过PX-DR实现零RPO的DRPX-DR支持在OpenShift上的同步和异步容灾,下面我们来关注下零RPO的同步容灾。我们先看一下通过Portworx和OpenShift同步容灾的相关概念和配置,包括初始setup和模拟出一个系统错误。一个单独的Portworx数据管理层横跨多个站点,如上图所示,同步PX-DR使用位于多个OpenShift集群下的、一个单独的Portworx数据管理层。这会在每一个OpenShift站点上提供永远可用的数据复制。一个单独的数据管理层意味着:有两个Portworx集群域,其中总有一个Portworx集群是可用的。
通过集群域,Portworx数据管理层来区分主站点和容灾站点。集群域在Portworx集群被安装的时候就会配置完成。在每一个OpenShift集群上(主集群或DR集群)配置Portworx来包括同一个Key-value的存储端点和集群名称,但使用不同的集群域来区分主站点和DR站点,看下面的例子。
Primary DR Site args: [“-k”, “etcd:http://etcd:2379”, “-c”, “px-cluster-synchronous”, “-s”, “type=gp2,size=250”, “-secret_type”, “k8s”, “-cluster_domain”, “primary” “-x”, “kubernetes”] “` args: [“-k”, “etcd:http://etcd:2379”, “-c”, “px-cluster-synchronous”, “-s”, “type=gp2,size=250”, “-secret_type”, “k8s”, “-cluster_domain”, “dr-site” “-x”, “kubernetes”]
低延时要求同步PX-DR需要很低的延时。因为每一个写入操作都会被同步的复制到容灾站点上,如果延时较高,应用的性能就会受到很大影响。这也是为什么在这样的架构中,卷必须设定复制因子在2以上。到DR站点的往返延迟不能够超过10毫秒,甚至有一些应用要求的延时比10毫秒还要低。当设计应用时,同时需要思考DR的架构和延时的要求。可以在两个站点间使用Ping来测试延时。测试延时可以返回最小、最大和平均延时以及分布。
$ ping ip-10-0-131-167 PING (10.0.131.167) 56(84) bytes of data. 64 bytes from (10.0.131.167): icmp_seq=1 ttl=255 time=0.019 ms 64 bytes from (10.0.131.167): icmp_seq=2 ttl=255 time=0.028 ms 64 bytes from (10.0.131.167): icmp_seq=3 ttl=255 time=0.035 ms 64 bytes from (10.0.131.167): icmp_seq=4 ttl=255 time=0.029 ms 64 bytes from (10.0.131.167): icmp_seq=5 ttl=255 time=0.028 ms ^C — ip-10-0-131-167.us-west-2.compute.internal ping statistics — 5 packets transmitted, 5 received, 0% packet loss, time 4080ms rtt min/avg/max/mdev = 0.019/0.027/0.035/0.008 ms
Setup Openshift集群配对
一旦完成两个站点都在运行Portworx,在正确的集群域设定基础上,它们就可以正常的来Sync了。我们可以通过Portworx命令 “` $ pxctl cluster domains show “` 来进行验证。验证完成后,并且两个集群域都是正常的情况下,就可以创建集群配对对象。这样两个站点就可以共享一个OpenShift应用YAML文件。这些YAML文件代表了应用的配置,对于在出问题时保证低RTO有着重要的作用。首先为目标命名空间产生集群配对,然后把YAML文件应用到主站点上。
$ storkctl generate clusterpair -n appns dr-site > dr-site.yaml
$ oc create -f dr-site.yaml
可以通过下面的命令来验证集群配对。
$ storkctl get clusterdomainsstatus
创建一个调度和迁移
取决于你的组织的RTO要求,你可以选择应用的sync频率。通过创建一个策略来定义调度,然后把调度和应用的迁移关联起来。
首先,创建一个调度,下面的例子中在每一分钟迁移应用配置。把它保存成一个Yaml文件,然后使用`oc create -f` 来创建策略。
apiVersion: stork.libopenstorage.org/v1alpha1
kind: SchedulePolicy
metadata:
name: sched-policy
namespace: appns
policy:
interval:
intervalMinutes: 1
daily:
time: “10:14PM”
weekly:
day: “Thursday”
time: “10:13PM”
monthly:
date: 14
time: “8:05PM”
接下来,创建一个迁移:针对 “appns”命名空间、“dr-site”集群配对、和使用这个调度。注意文件最下方的“schedulePolicyName”。存成一个yaml文件,然后通过` oc create -f` 来应用它。
apiVersion: stork.libopenstorage.org/v1alpha1
kind: MigrationSchedule
metadata:
name: migrationschedule
namespace: appns
spec:
template:
spec:
clusterPair: dr-site
includeResources: true
startApplications: false
includeVolumes: false
namespaces:
– demo
schedulePolicyName: sched-policy
注意以上仅仅设定includeResources是true,而设定其他的都是false,因为同步DR集群已经在两个集群上都配置了数据,因此我们不再需要include卷,并且直到有系统错误发生前,我们也不想启动这个应用。如果我们使用异步PX-DR方式,我们需要把`includeVolumes` 改为true。
你可以通过运行下面的命令来验证迁移是否已经完成。
$ storkctl get migration
通过OpenShift DR站点来恢复
现在OpenShift集群都已经sync完成,应用也sync完成。我们准备好来恢复应用了。当一个主站点的灾难发生后,下面的步骤即可在DR站点上恢复,并且是零RPO。
首先,关闭主站点,等待域变成 (NotInSync)
$ storkctl deactivate clusterdomain ocs-primary
$ storkctl get clusterdomainsstatus
接下来,如果你有权限访问主站点,把复制集变成0。如果你没有权限访问主站点,直接走到下一步,在容灾站点上恢复应用。
$ oc scale deploy -n demo –replicas=0 –all
通过向迁移调度增加 `suspend:true` ,并且更新spec,可以暂停迁移
apiVersion: stork.libopenstorage.org/v1alpha1
kind: MigrationSchedule
metadata:
name: migrationschedule
namespace: appns
spec:
template:
spec:
clusterPair: dr-site
includeResources: true
startApplications: false
includeVolumes: false
namespaces:
– demo
schedulePolicyName: sched-policy
suspend: true
$oc apply -f migration-schedule.yaml
最后,在DR站点上,启动迁移,打开DR站点上的Pods。
$ storkctl activate migration -n appns
你的“appns”命名空间里的应用现在已经在OpenShift DR站点上重启了,并且是0数据损失。
PX-DR包括一个API可以自动化的实现上面的步骤,另外,当主站点又重新启动后,应用的配置和数据会重新被sync,这样就可以重新在主站点上启动应用。