snapshot 是 Kubernetes Volume 在任何给定时间点的状态。
要创建现有集群的快照,
从 Longhorn UI,可以安排周期性快照和备份。
要设置时间表(schedule),您将转到 Longhorn 中的卷详细信息视图。然后你将设置:
• schedule 类型,备份(backup)或快照(snapshot)
• 将创建备份或快照的时间,以 CRON expression 的形式
• 要保留的备份或快照的数量
• 应应用于备份或快照的任何标签(Any labels)
然后 Longhorn 会自动为当时的用户创建快照或备份,只要该卷附加到一个节点。
可以使用 Longhorn UI 或使用 Kubernetes StorageClass 配置周期性快照。
注意:为了避免当卷长时间没有新数据时,recurring jobs 可能会用相同的备份和空快照覆盖旧的备份/快照的问题,Longhorn 执行以下操作:
1. Recurring backup job 仅在自上次备份以来卷有新数据时才进行新备份。
2. Recurring snapshot job 仅在卷头(volume head)中有新数据(实时数据)时才拍摄新快照。
可以从卷详细信息页面配置周期性快照和备份。要导航到此页面,请单击 Volume,,然后单击卷的名称。
可以在 StorageClass 的 recurringJobs 参数中配置计划备份和快照。
使用这个 StorageClass 创建的任何未来卷都将自动设置这些 recurring jobs。
recurringJobs 字段应遵循以下 JSON 格式:
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: longhorn
provisioner: driver.longhorn.io
parameters:
numberOfReplicas: "3"
staleReplicaTimeout: "30"
fromBackup: ""
recurringJobs: '[
{
"name":"snap",
"task":"snapshot",
"cron":"*/1 * * * *",
"retain":1
},
{
"name":"backup",
"task":"backup",
"cron":"*/2 * * * *",
"retain":1
}
]'
应为每个 recurring job 指定以下参数:
Longhorn 提供了 allow-recurring-job-while-volume-detached 设置,即使卷已分离,您也可以进行周期性备份(recurring backup)。您可以在 Longhorn UI 中找到该设置。
启用该设置后,Longhorn 将自动附加卷并在需要执行周期性快照/备份(recurring snapshot/backup)时进行快照/备份。
请注意,在卷自动附加(attached automatically)期间,卷尚未准备好处理工作负载。Workload 必须等到 recurring job 完成。
容灾 (DR) 卷是一种特殊卷,主要用于在整个主集群出现故障时将数据存储在备份集群中。灾难恢复卷用于提高 Longhorn 卷的弹性。
对于灾难恢复卷,Last Backup 表示其原始备份卷的最新备份。
如果代表灾难卷的图标为灰色,则表示该卷正在恢复 Last Backup,并且该卷无法激活。如果图标为蓝色,则表示该卷已恢复 Last Backup。
先决条件: 设置两个 Kubernetes 集群。它们将被称为集群 A 和集群 B。在两个集群上安装 Longhorn,并在两个集群上设置相同的备份目标。
备份目标是用于访问 Longhorn 中 backupstore 的端点。backupstore 是 NFS 服务器或 S3 兼容服务器,用于存储 Longhorn 卷的备份。备份目标可以在 Settings/General/BackupTarget 中设置。
Longhorn 还支持通过 Longhorn UI 或 Kubernetes Storage Class 为卷设置周期性快照/备份(recurring snapshot/backup)作业。
在以下情况下,您可能需要为 S3 兼容的备份存储启用这种新的寻址方法
您想立即切换到这种新的访问方式,这样您就无需担心 Amazon S3 路径弃用计划;
您使用的 backupstore 只支持 virtual-hosted-style 的访问,例如:Alibaba Cloud(Aliyun) OSS;
您已配置 MINIO_DOMAIN 环境变量以启用 MinIO 服务器的 virtual-host-style 请求;
这个错误 … error: AWS Error: SecondLevelDomainForbidden Please use virtual hosted style to access. … 被触发。
启用 virtual-hosted-style 访问的方法
将值为 true 的新字段 VIRTUAL_HOSTED_STYLE 添加到您的备份目标 secret。例如:
apiVersion: v1
kind: Secret
metadata:
name: oss-backup-target-secret
namespace: longhorn-system
type: Opaque
data:
AWS_ACCESS_KEY_ID: bG9uZ2hvcm4tdGVzdC1hY2Nlc3Mta2V5
AWS_SECRET_ACCESS_KEY: bG9uZ2hvcm4tdGVzdC1zZWNyZXQta2V5
AWS_ENDPOINTS: aHR0cHM6Ly9taW5pby1zZXJ2aWNlLmRlZmF1bHQ6OTAwMA==
VIRTUAL_HOSTED_STYLE: dHJ1ZQ== # true
在 Longhorn 所在的命名空间(默认为 longhorn-system)中创建一个名称为 oss-backup-target-secret的 Kubernetes secret。secret 必须在 longhorn-system 命名空间中创建,以便 Longhorn 访问它:
kubectl create secret generic oss-backup-target-secret --from-literal=AWS_ACCESS_KEY_ID=<your accessKeyID > --from-literal=AWS_SECRET_ACCESS_KEY=<your accessKeySecret> --from-literal=AWS_ENDPOINTS=<阿里云ENDPOINTS地址> --from-literal=VIRTUAL_HOSTED_STYLE=true -n longhorn-system
转到 Longhorn UI。在顶部导航栏中,单击 Settings。 在 Backup 部分中,将 Backup Target 设置为:
s3://<your-bucket-name>@<your-aws-region>/mypath/
attention:
your-bucket-name: Bucket名称
your-aws-region:Bucket所在区域,例如oss-cn-beijing
确保末尾有 /,否则会报错。可以使用子目录(前缀):
在备份部分将 备份目标凭据 Secret(Backup Target Credential Secret) 设置为:oss-backup-target-secret
要将 NFS 服务器用作备份存储,NFS 服务器必须支持 NFSv4。
目标 URL 应如下所示:
nfs://longhorn-test-nfs-svc.default:/opt/backupstore
Longhorn 中的 Backups 是在集群外备份存储中的对象。快照的备份被复制到备份存储,访问备份存储的端点是备份目标。
先决条件: 必须设置备份目标。有关更多信息,请参阅设置备份目标。如果尚未设置 BackupTarget,则会出现错误。
要创建备份,
Result: 备份已创建。要查看它,请单击顶部导航栏中的 Backup。
Longhorn 可以轻松地将备份恢复到一个卷。
还原备份时,默认情况下会创建一个同名的卷。如果已存在与备份同名的卷,则不会恢复备份。
要恢复备份,
Result: 恢复的卷在 Volume 页面上可用。
Longhorn 支持恢复备份,该特性的一个用例是恢复 Kubernetes StatefulSet 中使用的数据,这需要为备份的每个副本恢复一个卷。
要恢复,请按照以下说明操作。下面的示例使用一个 StatefulSet。
Backup Name | Restored Volume |
---|---|
pvc-01a | statefulset-vol-0 |
pvc-01b | statefulset-vol-1 |
对需要恢复的每个卷重复此步骤。
例如,如果使用具有名为 pvc-01a 和 pvc-02b 的卷的两个副本恢复 StatefulSet,则恢复可能如下所示:
1. 在 Kubernetes 中,为每个恢复的 Longhorn 卷创建一个 Persistent Volume来绑定它。storage 容量、numberOfReplicas、storageClassName 和 volumeHandle 必须在下面替换。在这个例子中,我们在 Longhorn 中引用了 statefulset-vol-0 和 statefulset-vol-1,并使用 longhorn 作为我们的 storageClassName。
kind: PersistentVolume
apiVersion: v1
metadata:
name: statefulset-vol-0
spec:
capacity:
storage: 20Gi # 和Longhron中恢复的卷的大小保持一致
storageClassName: longhorn # must be same name that we will use later
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
csi:
driver: driver.longhorn.io # driver must match this
fsType: ext4
volumeAttributes:
numberOfReplicas: '3' # Longhorn恢复的卷的副本数
staleReplicaTimeout: '30'
volumeHandle: statefulset-vol-0 # 在Longhorn中恢复的卷的名称
---
kind: PersistentVolume
apiVersion: v1
metadata:
name: statefulset-vol-1
spec:
capacity:
storage: 20Gi # 和Longhron中恢复的卷的大小保持一致
storageClassName: longhorn # must be same name that we will use later
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
csi:
driver: driver.longhorn.io # driver must match this
fsType: ext4
volumeAttributes:
numberOfReplicas: '3' # Longhorn恢复的卷的副本数
staleReplicaTimeout: '30'
volumeHandle: statefulset-vol-1 # 在Longhorn中恢复的卷的名称
在 namespace 中,将部署 StatefulSet,为上面创建的每个 Persistent Volume 创建 PersistentVolume Claims来进行绑定。Persistent Volume Claim 的名称必须遵循以下命名方案:
<name of Volume Claim Template>-<name of StatefulSet>-<index>
StatefulSet Pod 是零索引(zero-indexed)的。 在这个例子中,Volume Claim Template 的名字是 data,StatefulSet 的名字是 webapp, 并且有两个副本,分别是索引 0 和 1。
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: data-webapp-0
namespace: database
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi # 必须和上边定义的PV中的大小保持一致
storageClassName: longhorn
volumeName: statefulset-vol-0 # 上边创建的PV的名字
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: data-webapp-1
namespace: database
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi # 必须和上边定义的PV中的大小保持一致
storageClassName: longhorn
volumeName: statefulset-vol-1 # 上边创建的PV的名字
创建 StatefulSet:
apiVersion: apps/v1beta2
kind: StatefulSet
metadata:
name: webapp # match this with the PersistentVolumeClaim naming scheme
spec:
selector:
matchLabels:
app: nginx # has to match .spec.template.metadata.labels
serviceName: "nginx"
replicas: 2 # by default is 1
template:
metadata:
labels:
app: nginx # has to match .spec.selector.matchLabels
spec:
terminationGracePeriodSeconds: 10
containers:
- name: nginx
image: k8s.gcr.io/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: data
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: data # match this with the PersistentVolumeClaim naming scheme
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: longhorn # must match name from earlier
resources:
requests:
storage: 20Gi # must match size from earlier
Result: 现在应该可以从 StatefulSet Pods 内部访问恢复的数据。
整个恢复流程如下: