Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TO BE MERGED]local pv usage & failover (#107) #2376

Merged
merged 1 commit into from
Nov 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@

# Use Local Persistent Volumes in a NebulaGraph cluster

Local Persistent Volumes in K8s store container data directly using the node's local disk directory. Compared with network storage, Local Persistent Volumes provide higher IOPS and lower read and write latency, which is suitable for data-intensive applications. This topic describes how to use Local Persistent Volumes in NebulaGraph clusters and how to handle node failures while using Local Persistent Volumes.

While using Local Persistent Volumes can enhance performance, it's essential to note that, unlike network storage, local storage does not support automatic backup. In the event of a node failure, all data in local storage may be lost. Therefore, the utilization of Local Persistent Volumes involves a trade-off among service availability, data persistence, and flexibility.


## Background

In K8s, data persistence mainly relies on [Persistent Volume (PV)](https://kubernetes.io/docs/concepts/storage/persistent-volumes/). PVs provided by K8s can be broadly categorized into two types: local storage and network storage. See [Types of Persistent Volumes](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#types-of-persistent-volumes) for details.


## Prerequisites

NebulaGraph Operator is installed. For details, see [Install NebulaGraph Operator](../../2.get-started/2.1.install-operator.md).

## Use a Local Persistent Volume

Using a Local Persistent Volume involves configuring local storage, creating a Local Persistent Volume, and other steps. The [Local Persistence Volume Static Provisioner](https://github.com/kubernetes-sigs/sig-storage-local-static-provisioner#overview) tool automates the management of Local Persistent Volumes. To use Local Persistent Volumes, storage disks need to be configured manually on each node. After the storage disks are placed in a specific directory, Local Persistence Volume Static Provisioner automatically creates the appropriate PVs for them. When the disk is no longer needed, the PVC can be deleted. The external static provisioner will clean up the disk and make the PV available for use again.


1. Prepare and configure local storage disks.

The preparation and configuration differ depending on how disks are mounted to nodes. For details, see [Prepare and set up local volumes in discovery directory](https://github.com/kubernetes-sigs/sig-storage-local-static-provisioner/blob/master/docs/operations.md#prepare-and-set-up-local-volumes-in-discovery-directory).


2. Create a StorageClass with the example file `default_example_storageclass.yaml`.

```bash
kubectl create -f deployment/kubernetes/example/default_example_storageclass.yaml
```

The configuration of the StorageClass is as follows:

```yaml
# Only create this for K8s 1.9+
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
# Supported policies: Delete, Retain
reclaimPolicy: Delete
```

!!! note

To use a Local Persistent Volume, the `volumeBindingMode` must be set to `WaitForFirstConsumer` in the StorageClass configuration. For details, see [Creating a StorageClass](https://kubernetes.io/blog/2019/04/04/kubernetes-1.14-local-persistent-volumes-ga/#how-to-use-a-local-persistent-volume)。


3. [Deploy Local Persistence Volume Static Provisioner](https://github.com/kubernetes-sigs/sig-storage-local-static-provisioner/blob/master/docs/getting-started.md#step-3-creating-local-persistent-volumes).

4. Verify that the Local Persistent Volume is automatically created.

```bash
$ kubectl get pv
NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE
local-pv-ce05be60 1024220Ki RWO Delete Available local-storage 26s

$ kubectl describe pv local-pv-ce05be60
Name: local-pv-ce05be60
Labels: <none>
Annotations: pv.kubernetes.io/provisioned-by=local-volume-provisioner-minikube-18f57fb2-a186-11e7-b543-080027d51893
StorageClass: local-storage
Status: Available
Claim:
Reclaim Policy: Delete
Access Modes: RWO
Capacity: 1024220Ki
NodeAffinity:
Required Terms:
Term 0: kubernetes.io/hostname in [my-node]
Message:
Source:
Type: LocalVolume (a persistent volume backed by local storage on a node)
Path: /mnt/disks/vol1
Events: <none>
```

5. Bind the PVC and StorageClass defined by `spec.storaged.dataVolumeClaims` or `spec.metad.dataVolumeClaim` in the cluster configuration file to the created Local Persistent Volume. For specific steps, see [Create a NebulaGraph cluster](../4.1.installation/4.1.1.cluster-install.md).

## Failover for Local Persistent Volumes

When using network storage (e.g., AWS EBS, Google Cloud Persistent Disk, Azure Disk Storage, Ceph, NFS, etc.) as a PV, the storage resource is independent of any particular node. Therefore, the storage resource can be mounted and used by Pods regardless of the node to which the Pods are scheduled. However, when using a local storage disk as a PV, the storage resource can only be used by Pods on a specific node due to [nodeAffinity](https://kubernetes.io/blog/2018/04/13/local-persistent-volumes-beta/#creating-a-local-persistent-volume).

The Storage service of NebulaGraph supports data redundancy, which allows you to set multiple odd-numbered partition replicas. When a node fails, the associated partition is automatically transferred to a healthy node. However, Storage Pods using Local Persistent Volumes cannot run on other nodes due to the node affinity setting and must wait for the node to recover. To run on another node, the Pods must be unbound from the associated Local Persistent Volume.

NebulaGraph Operator supports automatic failover in the event of a node failure while using Local Persistent Volumes. By setting `spec.enableAutoFailover` to `true` in the cluster configuration file, Pods are automatically unbound from the Local Persistent Volume, allowing the Pods to run on another node.

Example configuration:

```yaml
...
spec:
# Enable automatic failover for Local PV.
enableAutoFailover: true
# The time to wait for the Storage service to be in the `OFFLINE` status
# before automatic failover.
# The default value is 5 minutes.
# If the Storage service recovers to the `ONLINE` status during this period,
# failover will not be triggered.
failoverPeriod: "2m"
...
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# {{nebula.name}}集群中使用本地持久化存储卷

本地持久化存储卷(Local Persistent Volumes,Local PV)在 K8s 中,直接使用节点的本地磁盘目录存储容器数据。相比网络存储,Local PV 提供更高的 IOPS 和更低的读写延迟,适合数据密集型应用。本文介绍如何在{{nebula.name}}集群中使用 Local PV 以及在使用 Local PV 过程中节点发生故障的处理方法。

虽然使用 Local PV 能提升性能,但是不同于网络存储,本地存储数据不会自动备份。如果节点因任何原因停止,本地存储上的所有数据可能会丢失。因此,使用 Local PV 时,需要在服务可用性、数据持久性和灵活性方面做出一定权衡取舍。

## 背景信息

K8s中,数据的持久化主要依赖于[持久存储卷(Persistent Volume,PV)](https://kubernetes.io/docs/concepts/storage/persistent-volumes/)。K8s 提供的 PV 类型主要分为大致可以分为本地存储和网络存储两类。详情参见[持久化存储卷类型](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#types-of-persistent-volumes)。

## 前提条件

已安装 NebulaGraph Operator。详情参见[安装 NebulaGraph Operator](../../2.get-started/2.1.install-operator.md)。

## 使用 Local PV

使用 Local PV 涉及到配置本地存储、创建 Local PV 等步骤。静态配置 PV 工具 [Local Persistence Volume Static Provisioner](https://github.com/kubernetes-sigs/sig-storage-local-static-provisioner#overview) 可以自动化管理 Local PV。 Local PV 需要在每个节点上手动配置存储卷,放在特定目录下后,Local Persistence Volume Static Provisioner 就会自动为它们创建相应的 PV,并在不需要时清理这些 PV。

1. 准备和配置本地存储盘。

针对不同磁盘挂载方式,需要在每个节点上做不同的准备和配置工作。详情参见 [Prepare and set up local volumes in discovery directory](https://github.com/kubernetes-sigs/sig-storage-local-static-provisioner/blob/master/docs/operations.md#prepare-and-set-up-local-volumes-in-discovery-directory)。


2. 创建示例文件名为`default_example_storageclass.yaml`的 StorageClass。

```bash
kubectl create -f deployment/kubernetes/example/default_example_storageclass.yaml
```

该 StorageClass 的配置文件内容如下所示:

```yaml
# Only create this for K8s 1.9+
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
# Supported policies: Delete, Retain
reclaimPolicy: Delete
```

!!! note

Local PV 的`volumeBindingMode`必须设置为`WaitForFirstConsumer`。详情参见 [How to Use a Local Persistent Volume](https://kubernetes.io/blog/2019/04/04/kubernetes-1.14-local-persistent-volumes-ga/#how-to-use-a-local-persistent-volume)。


3. [部署 Local Persistence Volume Static Provisioner](https://github.com/kubernetes-sigs/sig-storage-local-static-provisioner/blob/master/docs/getting-started.md#step-3-creating-local-persistent-volumes)。

4. 查看自动创建的 Local PV。

```bash
$ kubectl get pv
NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE
local-pv-ce05be60 1024220Ki RWO Delete Available local-storage 26s

$ kubectl describe pv local-pv-ce05be60
Name: local-pv-ce05be60
Labels: <none>
Annotations: pv.kubernetes.io/provisioned-by=local-volume-provisioner-minikube-18f57fb2-a186-11e7-b543-080027d51893
StorageClass: local-storage
Status: Available
Claim:
Reclaim Policy: Delete
Access Modes: RWO
Capacity: 1024220Ki
NodeAffinity:
Required Terms:
Term 0: kubernetes.io/hostname in [my-node]
Message:
Source:
Type: LocalVolume (a persistent volume backed by local storage on a node)
Path: /mnt/disks/vol1
Events: <none>
```

5. 在集群配置文件中,通过`spec.storaged.dataVolumeClaims`或`spec.metad.dataVolumeClaim`定义的 PVC 和 StorageClass 来绑定 Local PV。具体操作步骤,参见[创建{{nebula.name}}集群](../4.1.installation/4.1.1.cluster-install.md)。


## Local PV 的故障转移

使用网络存储(如 AWS EBS、Google Cloud Persistent Disk、Azure Disk Storage、Ceph、NFS 等)作为 PV,存储资源不依赖于任何特定节点,因此无论 Pod 被调度到哪个节点,都能挂载并使用此存储资源。然而,使用本地存储盘作为 PV 时,由于[节点亲和性(NodeAffinity)](https://kubernetes.io/blog/2018/04/13/local-persistent-volumes-beta/#creating-a-local-persistent-volume),存储资源只能被特定节点上的 Pod 使用。

{{nebula.name}}的 Storage 服务具备数据冗余能力,可以设置多个奇数分片副本。节点故障时,关联分片会自动迁移到健康节点。但是,使用 Local PV 的 Storage Pod 由于节点亲和性,不能在其他节点运行,必须等待节点恢复。若要在其他节点运行,需要解除 Pod 与 Local PV 的绑定。

针对使用 Local PV 过程中发生节点故障的情况,NebulaGraph Operator 支持进行自动故障转移操作。通过在集群的配置文件中设置`spec.enableAutoFailover`为`true`,自动解除 Pod 与 Local PV 的绑定,从而使 Pod 能在其他节点上运行。

示例如下:

```yaml
...
spec:
# 开启自动故障转移
enableAutoFailover: true
# Storage 服务为`OFFLINE`状态后等待自动故障转移的时间。
# 默认值 5 分钟。
# 如果 Storage 服务在此期间内恢复正常状态,不会触发故障转移。
failoverPeriod: "2m"
...
```