庄园的人员准备算是告一段落了。是时候考虑下餐饮问题了,厨房处理好的酒水瓜果都放在取餐台(PersistentVolume,pv),由黑奴服务员代客人拿取。为了管理规范,要求取用的时提供用户的需求表(PersistentVolumeClaim,pvc)。
部署服务时,常常需要为服务提供一些静态资源,可以使用持久卷来统一提供。此外服务运行过程中产生的日志文件以及一些其他产出都需要持久和的保持。这时候就需要使用到持久卷进行存储管理。
持久卷(PersistentVolume,PV) 是集群中的一块存储,可以由管理员事先制备, 或者使用存储类(Storage Class)来动态制备。 持久卷申领(PersistentVolumeClaim,PVC) 表达的是用户对存储的请求。申领必须位于使用它的 Pod 所在的同一名字空间内。
修改Nginx代理的网页
目标
- 为Nginx服务挂载本地持久卷
- 修改Nginx默认页面
本次实验使用本地磁盘作为持久卷是以为了降低复杂度,避免引入其他干扰因素。在生产环境中也不推荐这样操作。请使用网络磁盘(nfs、cephfs等)或者直接使用云存储作为替代。
构建
持久卷
apiVersion: v1
kind: PersistentVolume
metadata:
name: nginx-pv-volume
spec:
storageClassName: manual
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
hostPath:
path: "/mnt/nginx"
一些相似的配置就不做赘述了,主要说明有区别的配置项:
- storageClassName: 定义持久卷的类型名,申请持久卷时会匹配相同类型的持久卷
capacity.storage:持久卷大小,常用单位Gi Mi- accessModes: 访问模式,同样可以在申请中显示描述用以匹配,支持下列模式
- ReadWriteOnce:卷可以被一个节点以读写方式挂载。 ReadWriteOnce 访问模式也允许运行在同一节点上的多个 Pod 访问卷。
- ReadOnlyMany:卷可以被多个节点以只读方式挂载。
- ReadWriteMany: 卷可以被多个节点以读写方式挂载。
- ReadWriteOncePod:卷可以被单个 Pod 以读写方式挂载。
- hostPath: 指明使用本地磁盘 path为挂载路径
持久卷申请
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nginx-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
resources.requests.storage:所需存储大小,与pv中的storage对应。总是匹配storage大于等于pvc中storge值的pv。
挂载
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
volumeMounts:
- mountPath: "/usr/share/nginx/html/"
name: nginx-volume
volumes:
- name: nginx-volume
persistentVolumeClaim:
claimName: nginx-pv-claim
containers.volumeMounts: 容器内挂载地址- mountPath:容器内地址
- name:对应下方volumes中的name
- volumes:容器所挂载的卷
- persistentVolumeClaim:挂载pvc, claimName与上方申请的pvc对应
一次性构建
提示:资源间使用---分隔开即可,没有顺序要求。构建时候如果缺少对应资源k8s会主动等待其他资源构建。
# deployment-pv.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
volumeMounts:
- mountPath: "/usr/share/nginx/html/"
name: nginx-volume
volumes:
- name: nginx-volume
persistentVolumeClaim:
claimName: nginx-pv-claim
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: nginx-pv-volume
spec:
storageClassName: manual
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
hostPath:
path: "/mnt/nginx"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nginx-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
$ kubectl apply -f deployment-pv.yaml
deployment.apps/nginx-deployment created
persistentvolume/nginx-pv-volume created
persistentvolumeclaim/nginx-pv-claim created
$ kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 21s
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-7955c794c6-26ctm 1/1 Running 0 37s
nginx-deployment-7955c794c6-6bhs2 1/1 Running 0 37s
nginx-deployment-7955c794c6-zknxs 1/1 Running 0 37s
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
nginx-pv-claim Bound nginx-pv-volume 1Gi RWX manual 50s
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
nginx-pv-volume 1Gi RWX Retain Bound default/nginx-pv-claim manual 75s
可以看到相关资源都创建成功了。
修改默认页面
由于我们已经将本地磁盘通过pv pvc挂载到pod上了,只需要修改/mnt/nginx/中的index.html即可。
echo 'hello world' > /mnt/nginx/index.html
# 通过添加-o wide参数查看pod ip
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-7955c794c6-26ctm 1/1 Running 0 6m9s 10.244.0.140 debian <none> <none>
nginx-deployment-7955c794c6-6bhs2 1/1 Running 0 6m9s 10.244.0.141 debian <none> <none>
nginx-deployment-7955c794c6-zknxs 1/1 Running 0 6m9s 10.244.0.139 debian <none> <none>
# 验证修改被应用
$ curl 10.244.0.140
hello world
本节内容结束,更多PersistentVolume相关内容请参考官方文档。