Kubernetes中有状态应用的存储管理与StatefulSet部署
立即解锁
发布时间: 2025-08-25 02:04:17 阅读量: 3 订阅数: 7 

### Kubernetes 中状态应用的存储与部署实践
在 Kubernetes 环境中,管理有状态应用的存储和部署是一项关键任务。本文将深入探讨存储类、单 Pod 有状态工作负载部署以及 StatefulSet 的相关内容,通过具体示例帮助你更好地理解和实践。
#### 1. 存储类(Storage Classes)
在 Kubernetes 中,存储类是描述动态存储类型以及如何配置请求卷的一种方式。默认情况下,平台提供商会有默认的动态配置行为,但有时我们需要对存储类型和数据保留策略进行调整。
##### 1.1 查看现有存储类
可以使用以下命令查看现有的存储类:
```bash
$ kubectl get storageclass
NAME PROVISIONER RECLAIMPOLICY
premium-rwo pd.csi.storage.gke.io Delete
standard kubernetes.io/gce-pd Delete
standard-rwo (default) pd.csi.storage.gke.io Delete
```
从输出中可以看到,默认的回收策略(RECLAIM POLICY)为 Delete,这意味着当 PersistentVolumeClaim(PVC)被删除时,绑定的 PersistentVolume(PV)和底层磁盘资源也会被删除。对于存储关键数据的工作负载,这种默认行为并不理想。
##### 1.2 回收策略
Kubernetes 提供了两种回收策略:
- **Delete**:删除 PVC 时,绑定的 PV 和底层磁盘资源也会被删除。适用于缓存服务等存储非关键数据的工作负载。
- **Retain**:删除 PVC 时,底层磁盘资源不会被删除,允许将磁盘保留并绑定到新的 PV 和 PVC,甚至可以在不同集群中使用。但需要手动删除不需要的磁盘,不太适合测试、开发或存储临时数据的工作负载。
##### 1.3 创建自定义存储类
为了使用 Retain 回收策略,我们可以创建自定义存储类。以下是具体步骤:
1. 导出默认存储类作为模板:
```bash
kubectl get -o yaml storageclass standard-rwo > storageclass.yaml
```
2. 编辑 `storageclass.yaml` 文件,设置新的名称、Retain 回收策略,并去除不必要的元数据字段:
```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
annotations:
storageclass.kubernetes.io/is-default-class: "true"
name: example-default-rwo
parameters:
type: pd-balanced
provisioner: pd.csi.storage.gke.io
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
```
3. 创建新的存储类:
```bash
kubectl create -f storageclass.yaml
```
如果将其设置为默认存储类,后续创建的所有新 PersistentVolume 都将使用该存储类。
#### 2. 单 Pod 有状态工作负载部署
利用 PersistentVolumeClaims,我们可以通过将 Pod 封装在 Deployment 中来部署单副本有状态工作负载。即使 Pod 被终止,Deployment 也会重新创建它。
以下是一个部署 MariaDB 数据库的示例:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mariadb-demo
spec:
replicas: 1
selector:
matchLabels:
app: mariadb
strategy:
type: Recreate
template:
metadata:
labels:
app: mariadb
spec:
containers:
- name: mariadb-container
image: mariadb:latest
volumeMounts:
- mountPath: /var/lib/mysql
name: mariadb-volume
resources:
requests:
cpu: 1
memory: 4Gi
env:
- name: MARIADB_ROOT_PASSWORD
value: "your database password"
volumes:
- name: mariadb-volume
persistentVolumeClaim:
claimName: mariadb-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mariadb-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
```
通过上述配置,我们部署了一个单 Pod 的 MariaDB 数据库,并且由于之前创建的存储类使用了 Retain 策略,即使整个 Kubernetes 集群被删除,附加的磁盘也不会被删除。
为了连接到该数据库,可以创建一个 Service,并通过本地客户端或容器化的 phpMyAdmin 进行连接。
#### 3. StatefulSet
虽然 Deployment 可以用于部署单副本有状态工作负载,但对于需要多个 Pod 且每个 Pod 都有自己磁盘的复杂有状态工作负载,Deployment 存在局限性。Kubernetes 提供了 StatefulSet 来解决这个问题。
##### 3.1 StatefulSet 的优势
- **Volume 模板**:可以定义 Volume 模板,Kubernetes 会为每个 Pod 创建新的 PVC,解决了 Deployment 中所有 Pod 共享相同 PVC 的问题。
- **稳定标识符**:为每个 Pod 分配稳定的标识符,与特定的 PVC 关联,并在创建、扩展和更新时提供顺序保证。
- **稳定网络身份**:每个 Pod 都有自己的稳定网络身份,可以通过序号进行寻址。
##### 3.2 部署 StatefulSet
以下是两个常见有状态工作负载(MariaDB 和 Redis)作为 StatefulSet 部署的示例。
**MariaDB StatefulSet**
```yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mariadb
spec:
```
0
0
复制全文
相关推荐









