本文档风哥主要介绍Linux系统大规模Kubernetes存储配置与管理,包括K8s存储基础概念、存储类型介绍、存储类与持久卷、PV与PVC配置、存储类配置、存储监控以及实战案例等内容,风哥教程参考Kubernetes官方文档、Linux官方文档Storage等内容,适合系统管理员在生产环境中使用。
Part01-基础概念与理论知识
1.1 K8s存储基础概念
Kubernetes存储是容器编排的重要组成部分,负责为Pod提供持久化存储。Kubernetes存储模型包括:
- 持久卷(PV):集群级别的存储资源,由管理员创建
- 持久卷声明(PVC):Pod对存储资源的请求,由用户创建
- 存储类(StorageClass):动态创建PV的模板,定义存储的类型和参数
- 卷(Volume):Pod中的存储挂载点,生命周期与Pod相同
- 临时卷(Ephemeral Volume):临时存储,生命周期与Pod相同
- 解耦存储与计算:存储资源与Pod分离,实现数据持久化
- 动态配置:通过StorageClass动态创建PV,简化管理
- 多存储后端:支持多种存储类型,满足不同应用需求
- 可移植性:存储配置与底层存储实现分离,提高可移植性
1.2 存储类型介绍
Kubernetes支持多种存储类型,根据不同的场景选择合适的存储类型:
– 本地存储:使用节点本地磁盘,性能好,但不支持数据持久化
– NFS:网络文件系统,支持多节点访问,适合共享存储
– iSCSI:块存储协议,性能较好,适合数据库等应用
– Ceph:分布式存储系统,支持块存储、文件存储和对象存储
– GlusterFS:分布式文件系统,适合大规模存储
– 云存储:AWS EBS、Azure Disk、GCP Persistent Disk等
– 存储插件:通过CSI(Container Storage Interface)集成第三方存储
# 存储类型选择因素
– 性能:I/O吞吐量和延迟
– 可靠性:数据冗余和故障恢复
– 可扩展性:支持的存储容量和并发访问
– 成本:存储成本和维护成本
– 集成性:与Kubernetes的集成程度
1.3 存储类与持久卷
存储类(StorageClass)是Kubernetes中用于动态创建PV的资源。存储类定义了:
- 存储提供者:如NFS、Ceph、云存储等
- 存储参数:如存储大小、IOPS、副本数等
- 回收策略:如Retain、Delete、Recycle
持久卷(PV)是集群级别的存储资源,由管理员创建或通过StorageClass动态创建。PV具有以下特性:
- 独立于Pod的生命周期
- 可以被多个Pod使用
- 支持多种存储类型
- 具有回收策略
Part02-生产环境规划与建议
2.1 存储架构设计
生产环境存储架构设计要点:
– 本地存储:适合无状态应用和缓存
– 共享存储:适合有状态应用,如数据库
– 分布式存储:适合大规模应用和高可用场景
– 分层存储:根据数据访问频率使用不同存储类型
# 存储容量规划
– 预估应用存储需求:根据应用类型和数据量
– 预留增长空间:考虑数据增长和备份需求
– 多存储池:根据性能需求划分不同存储池
– 容量监控:实时监控存储使用情况
# 存储高可用
– 数据冗余:使用RAID、副本等技术
– 多路径:使用多路径技术提高可靠性
– 故障转移:配置存储故障自动转移
– 备份策略:定期备份数据,确保可恢复性
2.2 存储方案选择
生产环境存储方案选择要点:
– 小规模集群(< 100节点):NFS、本地存储 - 中规模集群(100-500节点):Ceph、GlusterFS - 大规模集群(> 500节点):Ceph、云存储
# 应用场景
– 无状态应用:本地存储、NFS
– 有状态应用:Ceph、iSCSI、云存储
– 数据库:Ceph RBD、iSCSI、云存储
– 大数据:Ceph、GlusterFS
– 媒体存储:对象存储
# 性能需求
– 高IOPS:SSD存储、NVMe
– 高吞吐量:分布式存储、并行文件系统
– 低延迟:本地存储、NVMe
2.3 性能考虑因素
from PG视频:www.itpux.com
生产环境存储性能考虑因素:
– I/O模式:随机I/O还是顺序I/O
– I/O大小:小I/O还是大I/O
– 并发访问:并发请求数
– 数据一致性:是否需要强一致性
– 延迟要求:应用对延迟的敏感程度
# 性能优化策略
– 使用SSD存储:提高I/O性能
– 配置适当的块大小:根据I/O模式调整
– 优化文件系统:选择适合的文件系统和挂载选项
– 使用缓存:使用缓存减少I/O操作
– 负载均衡:分散存储负载
Part03-生产环境项目实施方案
3.1 PV与PVC配置
3.1.1 配置静态PV与PVC
$ kubectl apply -f – << EOF apiVersion: v1 kind: PersistentVolume metadata: name: pv-nfs labels: type: nfs spec: capacity: storage: 10Gi accessModes: - ReadWriteMany nfs: server: 192.168.1.100 path: /exports persistentVolumeReclaimPolicy: Retain EOF # 查看PV状态 $ kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv-nfs 10Gi RWX Retain Available 5m # 创建PVC $ kubectl apply -f - << EOF apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-nfs namespace: default spec: accessModes: - ReadWriteMany resources: requests: storage: 5Gi selector: matchLabels: type: nfs EOF # 查看PVC状态 $ kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE pvc-nfs Bound pv-nfs 10Gi RWX 5m # 创建使用PVC的Pod $ kubectl apply -f - << EOF apiVersion: v1 kind: Pod metadata: name: nginx-pod namespace: default spec: containers: - name: nginx image: nginx volumeMounts: - name: nfs-volume mountPath: /usr/share/nginx/html volumes: - name: nfs-volume persistentVolumeClaim: claimName: pvc-nfs EOF # 查看Pod状态 $ kubectl get pods NAME READY STATUS RESTARTS AGE nginx-pod 1/1 Running 0 5m
3.1.2 配置动态PV与PVC
$ kubectl apply -f – << EOF apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: nfs-storage provisioner: k8s.学习交流加群风哥微信: itpux-comio/nfs parameters: server: 192.168.1.100 path: /exports readOnly: "false" reclaimPolicy: Delete allowVolumeExpansion: true volumeBindingMode: Immediate EOF # 查看StorageClass $ kubectl get storageclass NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE nfs-storage k8s.io/nfs Delete Immediate true 5m # 创建PVC $ kubectl apply -f - << EOF apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-dynamic namespace: default spec: accessModes: - ReadWriteMany resources: requests: storage: 5Gi storageClassName: nfs-storage EOF # 查看PVC状态 $ kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE pvc-dynamic Bound pvc-12345678-1234-1234-1234-1234567890ab 5Gi RWX nfs-storage 5m # 查看PV状态 $ kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-12345678-1234-1234-1234-1234567890ab 5Gi RWX Delete Bound default/pvc-dynamic nfs-storage 5m
3.2 存储类配置
3.2.1 配置Ceph存储类
$ helm repo add ceph-csi https://ceph.github.io/csi-charts
$ helm install ceph-csi-rbd ceph-csi/ceph-csi-rbd –namespace ceph-csi
# 创建Ceph存储类
$ kubectl apply -f – << EOF
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ceph-rbd
provisioner: rbd.csi.ceph.com
parameters:
clusterID: ceph-cluster
pool: kubernetes
imageFeatures: layering
csi.storage.k8s.io/provisioner-secret-name: ceph-secret
csi.storage.k8s.io/provisioner-secret-namespace: ceph-csi
csi.storage.k8s.io/controller-expand-secret-name: ceph-secret
csi.storage.k8s.io/controller-expand-secret-namespace: ceph-csi
csi.storage.k8s.io/node-stage-secret-name: ceph-secret
csi.storage.k8s.io/node-stage-secret-namespace: ceph-csi
reclaimPolicy: Delete
allowVolumeExpansion: true
volumeBindingMode: Immediate
EOF
# 查看存储类
$ kubectl get storageclass
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
ceph-rbd rbd.csi.ceph.com Delete Immediate true 5m
nfs-storage k8s.io/nfs Delete Immediate true 10m
3.3 存储监控
3.3.1 配置存储监控
$ helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
$ helm install prometheus prometheus-community/kube-prometheus-stack
# 安装存储监控插件
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/deploy/kubernetes/snapshot-controller/rbac-snapshot-controller.yaml
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/deploy/kubernetes/snapshot-controller/setup-snapshot-controller.yaml
# 查看存储使用情况
$ kubectl top pod
NAME CPU(cores) MEMORY(bytes)
nginx-pod 1m 24Mi
# 查看PV使用情况
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-12345678-1234-1234-1234-1234567890ab 5Gi RWX Delete Bound default/pvc-dynamic nfs-storage 10m
# 查看PVC使用情况
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc-dynamic Bound pvc-12345678-1234-1234-1234-1234567890ab 5Gi RWX nfs-storage 10m
Part04-生产案例与实战讲解
4.1 NFS存储配置案例
4.1.1 企业级NFS存储部署
# 环境:3节点K8s集群,1台NFS服务器
# 目标:部署NFS存储,为Pod提供共享存储
# 1. 配置NFS服务器
$ sudo dnf install -y nfs-utils
$ sudo mkdir -p /exports
$ sudo chmod 777 /exports
$ sudo echo “/exports 192.168.1.0/24(rw,sync,no_root_squash)” >> /etc/exports
$ sudo systemctl start nfs-server
$ sudo systemctl enable nfs-server
# 2. 安装NFS CSI插件
$ helm repo add nfs-subdir-external-provisioner https://ku学习交流加群风哥QQ113257174bernetes-sigs.github.io/nfs-subdir-external-provisioner/
$ helm install nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner –set nfs.server=192.168.1.100 –set nfs.path=/exports
# 3. 创建StorageClass
$ kubectl apply -f – << EOF
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-client
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
parameters:
pathPattern: {.PVC.namespace}/{.PVC.name}
onDelete: delete
reclaimPolicy: Delete
allowVolumeExpansion: true
volumeBindingMode: Immediate
EOF
# 4. 创建PVC
$ kubectl create namespace fgedu-app
$ kubectl apply -f - << EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-storage
namespace: fgedu-app
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
storageClassName: nfs-client
EOF
# 5. 部署应用
$ kubectl apply -f - << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
namespace: fgedu-app
spec:
replicas: 3
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: app-volume
mountPath: /usr/share/nginx/html
volumes:
- name: app-volume
persistentVolumeClaim:
claimName: app-storage
EOF
# 6. 测试存储
$ kubectl exec -it web-app-6799fc88d8-2q4x2 -n fgedu-app -- bash -c "echo 'Hello from NFS storage' > /usr/share/nginx/html/index.html”
$ kubectl exec -it web-app-6799fc88d8-5b678 -n fgedu-app — cat /usr/share/nginx/html/index.html
Hello from NFS storage
$ curl http://$(kubectl get svc -n fgedu-app web-app -o jsonpath='{.spec.clusterIP}’)
Hello from NFS storage
4.2 Ceph存储配置案例
4.2.1 企业级Ceph存储部署
# 环境:5节点K8s集群,3节点Ceph集群
# 目标:部署Ceph存储,为Pod提供高性能存储
# 1. 部署Ceph集群
$ helm repo add rook-release https://charts.rook.io/release
$ helm install rook-ceph rook-release/rook-ceph –namespace rook-ceph –create-namespace
$ helm install rook-ceph-cluster rook-release/rook-ceph-cluster –namespace rook-ceph
# 2. 创建Ceph存储类
$ kubectl apply -f – << EOF
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: rook-ceph-block
provisioner: rook-ceph.rbd.csi.ceph.com
parameters:
clusterID: rook-ceph
pool: replicapool
imageFormat: "2"
imageFeatures: layering
csi.storage.k8s.io/provisioner-secret-name: rook-csi-rbd-provisioner
csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph
csi.storage.k8s.io/controller-expand-secret-name: rook-csi-rbd-provisioner
csi.storage.k8s.io/controller-expand-secret-namespace: rook-ceph
csi.storage.k8s.io/node-stage-secret-name: rook-csi-rbd-node
csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph
reclaimPolicy: Delete
allowVolumeExpansion: true
volumeBindingMode: Immediate
EOF
# 3. 创建PVC
$ kubectl create namespace fgedu-db
$ kubectl apply -f - << EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-storage
namespace: fgedu-db
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Gi
storageClassName: rook-ceph-block
EOF
# 4. 部署MySQL
$ kubectl apply -f - << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
namespace: fgedu-db
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
env:
- name: MYSQL_ROOT_PASSWORD
value: fgedu123
- name: MYSQL_DATABASE
value: fgedudb
- name: MYSQL_USER
value: fgedu
- name: MYSQL_PASSWORD
value: fgedu123
volumeMounts:
- name: mysql-volume
mountPath: /var/lib/mysql
volumes:
- name: mysql-volume
persistentVolumeClaim:
claimName: mysql-storage
EOF
# 5. 测试存储
$ kubectl exec -it mysql-7d75c484b5-8x8x8 -n fgedu-db -- mysql -u fgedu -pfgedu123 -e "CREATE TABLE fgedu_test (id INT, name VARCHAR(255)); INSERT INTO fgedu_test VALUES (1, 'test'); SELECT * FROM fgedu_test;"
+------+------+
| id | name |
+------+------+
| 1 | test |
+------+
4.3 本地存储配置案例
4.3.1 企业级本地存储部署
# 环境:3节点K8s集群
# 目标:部署本地存储,为Pod提供高性能存储
# 1. 安装本地存储插件
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/sig-storage-local-static-provisioner/master/deploy/kubernetes/example/default_example_storageclass.yaml
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/sig-storage-local-static-provisioner/master/deploy/kubernetes/example/provisioner_generated.yaml
# 2. 准备本地存储
$ sudo mkdir -p /mnt/disks
$ sudo mount /dev/sdb1 /mnt/disks
$ sudo chmod 777 /mnt/disks
# 3. 创建本地存储PV
$ kubectl apply -f – << EOF
apiVersion: v1
kind: PersistentVolume
metadata:
name: local-pv
labels:
type: local
spec:
capacity:
storage: 100Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /mnt/disks
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- worker1
EOF
# 4. 创建PVC
$ kubectl create namespace fgedu-cache
$ kubectl apply -f - << EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: cache-storage
namespace: fgedu-cache
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Gi
storageClassName: local-storage
EOF
# 5. 部署应用
$ kubectl apply -f - << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: fgedu-cache
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis
volumeMounts:
- name: redis-volume
mountPath: /data
volumes:
- name: redis-volume
persistentVolumeClaim:
claimName: cache-storage
EOF
# 6. 测试存储
$ kubectl exec -it redis-7d75c484b5-8x8x8 -n fgedu-cache -- redis-cli set test "Hello from local storage"
OK
$ kubectl exec -it redis-7d75c484b5-8x8x8 -n fgedu-cache -- redis-cli get test
"Hello from local storage"
Part05-风哥经验总结与分享
5.1 K8s存储最佳实践
Kubernetes存储最佳实践:
- 选择合适的存储类型:根据应用特点选择合适的存储类型
- 使用StorageClass:通过StorageClass动态创建PV,更多视频教程www.fgedu.net.cn简化管理
- 配置合适的访问模式:根据应用需求选择ReadWriteOnce、ReadWriteMany或ReadOnlyMany
- 设置合理的存储容量:根据应用需求和增长预期设置存储容量
- 配置存储监控:实时监控存储使用情况,及时发现问题
- 备份存储数据:定期备份存储数据,确保可恢复性
- 优化存储性能:根据应用特点优化存储配置,提高性能
- 使用存储快照:为重要数据创建存储快照,方便恢复
5.2 常见问题与解决方案
## 1. PV创建失败
– 原因:存储后端不可用、权限问题、配置错误
– 解决方案:检查存储后端状态、检查权限配置、检查PV配置
## 2. PVC绑定失败
– 原因:没有可用的PV、PV与PVC不匹配、存储类配置错误
– 解决方案:创建足够的PV、确保PV与PVC匹配、检查存储类配置
## 3. 存储性能下降
– 原因:存储容量不足、I/O竞争、存储后端性能问题
– 解决方案:增加存储容量、优化应用I/O模式、升级存储后端
## 4. 存储数据丢失
– 原因:存储后端故障、数据未备份、PV回收策略错误
– 解决方案:使用高可用存储、定期备份数据、配置合适的回收策略
## 5. 存储扩展失败
– 原因:存储类不支持扩展、存储后端容量不足、权限问题
– 解决方案:使用支持扩展的存储类、确保存储后端有足够容量、检查权限配置
5.3 性能调优建议
风哥针对
Kubernetes存储性能调优建议:
- 选择高性能存储:使用SSD或NVMe存储,提高I/O性能
- 优化存储配置:根据应用I/O模式调整存储参数
- 使用本地存储:对于对延迟敏感的应用,使用本地存储
- 配置适当的缓存:使用缓存减少I/O操作,提高性能
- 负载均衡:分散存储负载,避免单点瓶颈
- 使用存储池:根据性能需求划分不同存储池
- 监控与分析:使用Prometheus和Grafana监控存储性能,分析瓶颈
- 定期维护:清理无用数据,优化存储碎片,更新存储软件
风哥提示:
风哥提示:
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
