Volume常用的几个存储卷
emptyDir: 本地临时卷
hostPath: 本地存储卷
configMap: 配置文件
secret: 敏感配置信息所用的配置
nfs: 网络存储卷
pv/pvc/storageclass
不同类型存储卷yaml文件示例
1、emptyDir临时卷
pod删除,存储卷内的数据也随之删除
emptyDir有两种类型,default(默认不需要指定)和Memory,使用Memory需设置sizeLimit参数限制内存使用大小,以防内存泄漏
默认default类型的emptyDir
示例1:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 1
selector:
matchLabels:
app: ng-deploy-80
template:
metadata:
labels:
app: ng-deploy-80
spec:
containers:
- name: ng-deploy-80
image: nginx
ports:
- containerPort: 80
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
Memory类型的emptyDir,pod内量容器共享emptyDir存储空间
示例2:
apiVersion: v1
kind: Pod
metadata:
name: pods-with-emptydir-vol
spec:
containers:
- image: ikubernetes/admin-box:v1.2
name: admin
command: ["/bin/sh", "-c"]
args: ["sleep 99999"]
resources: {}
volumeMounts:
- name: data
mountPath: /data
- image: ikubernetes/demoapp:v1.0
name: demoapp
resources: {}
volumeMounts:
- name: data
mountPath: /var/www/html
volumes:
- name: data
emptyDir:
medium: Memory
sizeLimit: 16Mi
restartPolicy: Always
2、hostPath存储卷
hostPath将主机节点的文件系统中的文件或目录挂载到集群中,pod删除,卷不会被删除
示例1:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 1
selector:
matchLabels:
app: ng-deploy-80
template:
metadata:
labels:
app: ng-deploy-80
spec:
containers:
- name: ng-deploy-80
image: nginx
ports:
- containerPort: 80
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
hostPath:
path: /tmp/hostDir
hostPath的类型,如果没目录会自动创建的示例,并绑定了pod可以调度的节点
示例2:
apiVersion: v1
kind: Pod
metadata:
name: redis
spec:
nodeName:k8s-node01
containers:
- name: redis
image: redis:7-alpine
imagePullPolicy: IfNotPresent
volumeMounts:
- name: redisdata
mountPath: /data
volumes:
- name: redisdata
hostPath:
type: DirectoryOrCreate
path: /data/redis
3、nfs共享存储
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 1
selector:
matchLabels:
app: ng-deploy-80
template:
metadata:
labels:
app: ng-deploy-80
spec:
containers:
- name: ng-deploy-80
image: nginx
ports:
- containerPort: 80
volumeMounts:
- mountPath: /usr/share/nginx/html/mysite
name: my-nfs-volume
volumes:
- name: my-nfs-volume
nfs:
server: 172.31.7.109
path: /data/nfsdir
4、configMap
命令方式创建ConfigMap
字面量:kubectl create cm <name> --from-literal=key1=value1
从文件加载: kubectl create cm <name> --from-file=[key=]/Path/file
从目录加载: kubectl create cm <name> --from-file=/Path/DIR/
配置文件类型的configmap
# vim nginx-config-cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
data:
default: |
server {
listen 80;
server_name www.mysite.com;
index index.html index.php index.htm;
location / {
root /data/nginx/html;
if (!-e $request_filename) {
rewrite ^/(.*) /index.html last;
}
}
}
# vim deploy-cm.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 1
selector:
matchLabels:
app: ng-deploy-80
template:
metadata:
labels:
app: ng-deploy-80
spec:
containers:
- name: ng-deploy-80
image: nginx:1.20.0
ports:
- containerPort: 80
volumeMounts:
- name: nginx-config
mountPath: /etc/nginx/conf.d/mysite
volumes:
- name: nginx-config
configMap:
name: nginx-config
items:
- key: default
path: mysite.conf
变量类型的configmap,配置值无法动态变更
# vim nginx-config-env-cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
data:
username: "user1"
password: "12345678"
# vim vim deploy-env-cm.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 1
selector:
matchLabels:
app: ng-deploy-80
template:
metadata:
labels:
app: ng-deploy-80
spec:
containers:
- name: ng-deploy-80
image: nginx
env:
- name: city
value: hangzhou
- name: MY_USERNAME
valueFrom:
configMapKeyRef:
name: nginx-config
key: username
optional: true # 是否可选
- name: MY_PASSWORD
valueFrom:
configMapKeyRef:
name: nginx-config
key: password
ports:
- containerPort: 80
5、secret
1、数据需要base64编码的secret
# secret对象定义,数据需要base64转码
# echo admin|base64;echo 123456 |base64
# vim secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret-data
type: Opaque
data:
user: YWRtaW4K
password: MTIzNDU2Cg==
# deploy使用sectet
# vim deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myserver-myapp-app1-deployment
spec:
replicas: 1
selector:
matchLabels:
app: myserver-myapp-app1
template:
metadata:
labels:
app: myserver-myapp-app1
spec:
containers:
- name: myserver-myapp-app1
image: tomcat:7.0.94-alpine
ports:
- containerPort: 8080
volumeMounts:
- mountPath: /data/myserver/auth
name: myserver-auth-secret
volumes:
- name: myserver-auth-secret
secret:
secretName: mysecret-data
2、数据不需要base64编码的secret
apiVersion: v1
kind: Secret
metadata:
name: mysecret-stringdata
namespace: myserver
type: Opaque
stringData:
user: 'admin'
password: '123456'
3、docker-register类型的secret
# 创建secret
kubectl create secret docker-registry keyName --docker-server=registry.myserver.com --docker-username=USER --docker-password=PASSWORD
# deploy内使用该证书
...
spec:
containers:
- name: myserver-myapp-frontend
image: registry.myserver.com/library/nginx:1.28.0
ports:
- containerPort: 80
imagePullSecrets:
- name: aliyun-registry-image-pull-key
...
pv/pvc存储卷
用于实现pod和后端存储的解耦,与nfs的区别在于,pv和pvc层面实现了对存储服务器的空间分配,存储的访问权限管理
Volume静态存储示例
1、pv资源定义
pv是集群级别的资源,无需定义namespace
apiVersion: v1
kind: PersistentVolume
metadata:
name: myserver-myapp-static-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
nfs:
path: /data/k8sdata
server: 192.168.139.24
2、pvc资源定义
pvc为卷申请,后端需要跟pv绑定,pod通过挂载pvc并将数据存储在pvc关联的pv,pod需要与pvc在同一个namespace
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myserver-myapp-static-pvc
spec:
volumeName: myserver-myapp-static-pv
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
3、deploy内使用pvc
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
app: myserver-myapp
name: myserver-myapp-deployment-name
spec:
replicas: 3
selector:
matchLabels:
app: myserver-myapp-frontend
template:
metadata:
labels:
app: myserver-myapp-frontend
spec:
containers:
- name: myserver-myapp-container
image: nginx:1.20.0
volumeMounts:
- mountPath: "/usr/share/nginx/html/statics"
name: statics-datadir
volumes:
- name: statics-datadir
persistentVolumeClaim:
claimName: myserver-myapp-static-pvc
Volume动态存储示例
通过storageClass动态创建pv来实现动态储存卷的定义,可参考如下项目(本文示例)
https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner
或者该项目
https://github.com/kubernetes-csi/csi-driver-nfs
部署步骤
1、提前准备好nfs服务
2、创建账号和NFS provisioner
3、创建storageclass
4、创建pvc
5、创建web服务挂载pvc
1、部署nfs服务
apt install nfs-common nfs-kernel-server
vim /etc/exports
/data/nfs *(rw,sync,no_root_squash,no_subtree_check)
exportfs -r
exportfs -v # 查看是否生效
# 可以到其他节点执行挂载命令,看是否可以正常挂载
mount -t nfs 192.168.139.24:/data/nfs /data/nfs
生效即可取消挂载
umount /data/nfs
2、创建rbac权限账号与nfs-provisioner
# 下载权限账号文件
wget https://ghfast.top/https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/blob/master/deploy/rbac.yaml
# 下载部署nfs
wget https://ghfast.top/https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/blob/master/deploy/deployment.yaml
# 替换名称空间为nfs
NAMESPACE=nfs
sed -i'' "s/namespace:.*/namespace: $NAMESPACE/g" ./deploy/rbac.yaml ./deploy/deployment.yaml
# 将deployment.yaml文件内的nfs地址修改为真实的地址,示例如下
env:
- name: PROVISIONER_NAME
value: k8s-sigs.io/nfs-subdir-external-provisioner
- name: NFS_SERVER
value: 192.168.139.24
- name: NFS_PATH
value: /data/nfs
volumes:
- name: nfs-client-root
nfs:
server: 192.168.139.24
path: /data/nfs
# 部署rbac以及nfs-provisioner
kubectl create ns nfs
kubectl create -f rbac.yaml
kubectl create -f deployment.yaml
3、创建storageclass
# vim storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: managed-nfs-storage
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner # or choose another name, must match deployment's env PROVISIONER_NAME'
reclaimPolicy: Retain #PV的删除策略,默认为delete,删除PV后立即删除NFS server的数据
mountOptions:
- noresvport #告知NFS客户端在重新建立网络连接时,使用新的传输控制协议源端口
- noatime #访问文件时不更新文件inode中的时间戳,高并发环境可提高性能
parameters:
mountOptions: "noresvport,noatime"
archiveOnDelete: "true" #删除pod时保留pod数据,默认为false时为不保留数据
# 部署storageclass
kubectl apply -f storageclass.yaml
kubectl get storageclass
4、创建pvc
# vim mypvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: myserver-myapp-dynamic-pvc
spec:
storageClassName: managed-nfs-storage #调用的storageclass 名称
accessModes:
- ReadWriteMany #访问权限
resources:
requests:
storage: 500Mi #空间大小
# 部署pvc
kubectl apply -f mypvc.yaml
kubectl get pvc # status字段为Bound即为正常状态
5、创建web服务挂载pvc
# vim deploy-nfs.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
app: myserver-myapp
name: myserver-myapp-deployment-name
spec:
replicas: 1
selector:
matchLabels:
app: myserver-myapp-frontend
template:
metadata:
labels:
app: myserver-myapp-frontend
spec:
containers:
- name: myserver-myapp-container
image: nginx:1.28.0
volumeMounts:
- mountPath: "/usr/share/nginx/html/statics"
name: statics-datadir
volumes:
- name: statics-datadir
persistentVolumeClaim:
claimName: myserver-myapp-dynamic-pvc
---
kind: Service
apiVersion: v1
metadata:
labels:
app: myserver-myapp-service
name: myserver-myapp-service-name
namespace: myserver
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: 80
nodePort: 30080
selector:
app: myserver-myapp-frontend
# 部署应用
Kubectl apply -f deploy-nfs.yaml
# 此时可以将文件上传到容器内的/usr/share/nginx/html/statics/目录下测试是否可以访问了
作者:于浩 创建时间:2025-06-05 14:00
最后编辑:于浩 更新时间:2025-06-10 18:08
最后编辑:于浩 更新时间:2025-06-10 18:08