(1)将数据和镜像解耦,以及容器间相互共享数据。也减小了镜像包的大小
(2)k8s抽象出一个对象,用来保存数据
常用的卷有:
emptyDir:本地临时卷,容器删除数据就跟着删除了(卷是保存在容器上的)
hostPath:本地卷,容器的数据保存在本地磁盘上,容器删除数据不会删除(但是pod重启调度到另外节点就无法使用原先的数据了)
nfs:nfs共享卷,容器删除共享卷不会被删除
configmap:配置文件
当pod被创建时,会先创建emptyDir卷.只要该pod在该节点上运行,这个卷就会一直存在.被创建的时候这个卷是空的.pod中的容器可以读写该emptyDir卷中的文件.当pod被删除时,emptyDir将被永久删除.可以放一些缓存或日志等不重要的文件.
root@master1:~/yaml/volume# cat pod-emptydir.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 1
selector:
matchLabels:
app: ng-deploy
template:
metadata:
labels:
app: ng-deploy
spec:
containers:
- name: ng-deploy
image: nginx
ports:
- containerPort: 80
volumeMounts:
- mountPath: /cache
name: empty-volume #卷的名称要和volumes声明的一致
volumes:
- name: empty-volume
emptyDir: {}
pod创建后写入文件到/cache/1.txt
刚创建的时候目录是空的,写入文件后可以在node节点上读取到该文件内容.
和docker的-v效果比较类似,即使容器被删除,该路径下的数据任然会被保存下来.但发生节点切换就会造成数据丢失.
root@master1:~/yaml/volume# cat pod-hostpath.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx-deploy
template:
metadata:
labels:
app: nginx-deploy
spec:
nodeName: 172.17.1.103
containers:
- name: deploy-nginx
image: nginx
ports:
- containerPort: 80
volumeMounts:
- mountPath: /data
name: cache-volume
volumes:
- name: cache-volume
hostPath:
path: /tmp/cache
root@master1:~ apt update
root@master1:~ apt install nfs-server
root@master1:~ mkdir /data/k8s/ -p
root@master1:~/yaml/volume# cat /etc/exports
/data/nfs 172.17.0.0/16(rw,no_root_squash,no_subtree_check)
/data/pv1 172.17.0.0/16(rw,no_root_squash,no_subtree_check)
/data/pv2 172.17.0.0/16(rw,no_root_squash,no_subtree_check)
root@master1:~ systemctl enable --now nfs-server
root@master1:~ systemctl restart nfs-server
# node节点验证nfs的共享目录
root@node2:~# showmount -e 172.17.1.101
Export list for 172.17.1.101:
/data/pv2 172.17.0.0/16
/data/pv1 172.17.0.0/16
/data/nfs 172.17.0.0/16
#单个nfs
root@master1:~/yaml/volume# cat pod-nfs.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
spec:
replicas: 1
selector:
matchLabels: #标签选择集
app: nginx-deploy
template:
metadata:
labels:
app: nginx-deploy
spec:
containers:
- name: nginx-deploy
image: nginx
ports:
- containerPort: 80
volumeMounts:
- mountPath: /usr/share/nginx/html/mysite
name: nfs-volume
volumes:
- name: nfs-volume
nfs:
server: 172.17.1.101
path: /data/nfs
---
apiVersion: v1
kind: Service
metadata:
name: ng-deploy
spec:
ports:
- name: http
port: 81
targetPort: 80
nodePort: 30016
protocol: TCP
type: NodePort
selector:
app: nginx-deploy
# 多个nfs
root@master1:~/yaml/volume# cat pod-nfss.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx-80
spec:
replicas: 1
selector:
matchLabels:
app: nginx-deploy
template:
metadata:
labels:
app: nginx-deploy
spec:
containers:
- name: nginx-deploy
image: nginx
ports:
- containerPort: 80
volumeMounts:
- mountPath: /usr/share/nginx/html/html
name: nginx-nfs-html
- mountPath: /usr/share/nginx/html/photo
name: nginx-nfs-photo
volumes:
- name: nginx-nfs-photo
nfs:
server: 172.17.1.102
path: /data/photo
- name: nginx-nfs-html
nfs:
server: 172.17.1.101
path: /data/nfs
---
apiVersion: v1
kind: Service
metadata:
name: ng-deploy-80
spec:
ports:
- name: http
port: 82
targetPort: 80
nodePort: 30017
protocol: TCP
type: NodePort
selector:
app: nginx-deploy
存在的意义:使得镜像和配置解耦,将配置信息放入configmap,在pod的对象中导入configmap,实现配置导入
root@master1:~/yaml/volume# cat pod-cm.yaml
# 声明一个configmap的卷
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config #卷的名称
data:
mysite.cnf: | #创建mysite.cnf文件
server { #mysite.cnf文件的内容
listen 80;
server_name www.mysite.com;
index index.html;
location / {
root /data/nginx/html;
if (!-e $request_filename) {
rewrite ^/(.*) /index.html last;
}
}
}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-configmap
spec:
replicas: 1
selector:
matchLabels:
app: nginx-configmap
template:
metadata:
labels:
app: nginx-configmap
spec:
containers:
- name: ng-configmap
image: nginx
ports:
- containerPort: 80
volumeMounts:
- mountPath: /data/nginx/html
name: my-nfs-volume
- mountPath: /etc/nginx/conf.d
name: nginx-config
volumes:
- name: nginx-config
configMap:
name: nginx-config
- name: my-nfs-volume
nfs:
server: 172.17.1.101
path: /data/nfs
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
ports:
- name: http
port: 81 #service的端口
targetPort: 80 #容器的端口
nodePort: 30019 #映射node节点的port端口
protocol: TCP
type: NodePort
selector:
app: nginx-configmap
configMap的data中创建key:username,val:user1通过env将来源就是来源名为nginx-config的configMap,key为username的值至传递给容器的MY_USERNAME变量。
root@master1:~/yaml/volume# cat pod-cm-env.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
data:
username: user1
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
spec:
replicas: 1
selector:
matchLabels:
app: nginx-deploy
template:
metadata:
labels:
app: nginx-deploy
spec:
containers:
- name: nginx-deploy
image: nginx
env:
- name: "mykey"
value: "myvalue"
- name: MY_USERNAME
valueFrom:
configMapKeyRef:
name: nginx-config
key: username
ports:
- containerPort: 80
pv:集群资源
pvc:命名空间资源
持久卷(PersistentVolume,PV) 是集群中的一块存储,可以由管理员事先制备, 或者使用存储类(Storage Class)来动态制备。 持久卷是集群资源,就像节点也是集群资源一样。PV 持久卷和普通的 Volume 一样, 也是使用卷插件来实现的,只是它们拥有独立于任何使用 PV 的 Pod 的生命周期。 此 API 对象中记述了存储的实现细节,无论其背后是 NFS、iSCSI 还是特定于云平台的存储系统。
持久卷申领(PersistentVolumeClaim,PVC) 表达的是用户对存储的请求。概念上与 Pod 类似。 Pod 会耗用节点资源,而 PVC 申领会耗用 PV 资源。Pod 可以请求特定数量的资源(CPU 和内存);同样 PVC 申领也可以请求特定的大小和访问模式 (例如,可以要求 PV 卷能够以 ReadWriteOnce、ReadOnlyMany 或 ReadWriteMany 模式之一来挂载,参见访问模式)。
pv是对底层网络存储的抽象,将存储定义为一种资源,将一个整体的存储资源拆分成多份后给不同的业务使用.
pvc是对pv资源的申请调用.就像POD消费NODE节点一样,POD通过PVC将数据保存至PV,PV在保存数据至存储.
PV 持久卷是用插件的形式来实现的。Kubernetes 目前支持以下插件 :
PersistentVolume 卷可以用资源提供者所支持的任何方式挂载到宿主系统上。 如下表所示,提供者(驱动)的能力不同,每个 PV 卷的访问模式都会设置为对应卷所支持的模式值。 例如,NFS 可以支持多个读写客户,但是某个特定的 NFS PV 卷可能在服务器上以只读的方式导出。 每个 PV 卷都会获得自身的访问模式集合,描述的是特定 PV 卷的能力。
访问模式:
在命令行接口(CLI)中,访问模式也使用一下缩写形式:
(1)自动创建
1.1 管理员创建存储类(StorageClass)
1.2 用户创建持久化存储卷声明
1.3 调用存储类,通知系统使用存储类创建PV
1.4 获取存储类信息
1.5 基于存储类创建PV
1.6 用户创建使用PVC的POD
1.7 指定POD使用哪个PVC
1.8 PVC使用PV存储数据
(2)手动创建
Capacity: 当前pv空间大小
accessModes: 访问模式
ReadWriteOnce PV可以被一个节点以读写方式挂载
ReadOnlyMany PV可以被多个节点以只读方式挂载
ReadWriteMany PV可以被多个节点以读写方式挂载
persistentVolumeReclaimPolicy 删除机制删除数据存储的时候,已经创建好的卷由以下删除操作.
Retain -- 手动回收
Recycle -- 基本擦除 (`rm -rf /thevolume/*`) 仅支持NFS和HostPath
Delete -- 诸如 AWS EBS、GCE PD、Azure Disk 或 OpenStack Cinder 卷这类关联存储资产也被删除
volumeMode #卷类型
定义存储卷使用的文件系统是块设备还是文件系统,默认文件系统
mountOptions 附加的挂载选项列表,实现更精细的权限控制ro 等
当用户不再使用其存储卷时,他们可以从 API 中将 PVC 对象删除, 从而允许该资源被回收再利用。PersistentVolume 对象的回收策略告诉集群, 当其被从申领中释放时如何处理该数据卷。 目前,数据卷可以被 Retained(保留)、Recycled(回收)或 Deleted(删除)。
目前的回收策略有:
Retain – 手动回收
Recycle – 基本擦除 (rm -rf /thevolume/*) 仅支持NFS和HostPath
Delete – 诸如 AWS EBS、GCE PD、Azure Disk 或 OpenStack Cinder 卷这类关联存储资产也被删除
每个卷会处于以下阶段(Phase)之一:
Available(可用)-- 卷是一个空闲资源,尚未绑定到任何申领;
Bound(已绑定)-- 该卷已经绑定到某申领;
Released(已释放)-- 所绑定的申领已被删除,但是资源尚未被集群回收;
Failed(失败)-- 卷的自动回收操作失败。
pvc的访问模式:
pvc创建参数
accessModes:
ReadWriteOnce PVC可以被一个节点以读写方式挂载
ReadOnlyMany PVC可以被多个节点以只读方式挂载
ReadWriteMany PVC可以被多个节点以读写方式挂载
resources: 定义pvc创建存储卷的空间大小
selector: 标签选择器,选择要绑定的pv
matchLables 匹配标签名称
matchExpressions 基于正则匹配
volumeName 要绑定的pv名称
volumeMode 卷类型
定义pvc使用文件系统是块设备还是文件系统,默认是文件系统
root@master1:~/yaml/volume# cat pod-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv1
spec:
capacity: #存储能力,目前只支持存储空间的设置
storage: 2Gi
accessModes: #访问模式
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain #回收策略
nfs:
server: 172.17.1.101
path: /data/pv1
绑定pv卷
root@master1:~/yaml/volume# cat pod-pvc1.yaml
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc1
spec:
accessModes: #访问模式
- ReadWriteMany
resources: #请求资源
requests:
storage: 1Gi
pod挂载卷
root@master1:~/yaml/volume# cat pod-nginx-pvc.yaml
# 声明一个configmap的卷
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config #卷的名称
data:
mysite.conf: |
server {
listen 80;
server_name www.mysite.com;
index index.html;
location / {
root /data/nginx/html;
if (!-e $request_filename) {
rewrite ^/(.*) /index.html last;
}
}
}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx-pv
spec:
replicas: 1
selector:
matchLabels:
app: nginx-pvc
template:
metadata:
labels:
app: nginx-pvc
spec:
containers:
- name: nginx-deploy-pvc
image: nginx
ports:
- containerPort: 80
volumeMounts:
# 挂载configMap卷
- name: nginx-config
mountPath: /etc/nginx/conf.d
# 挂载pvc卷
- name: nginx-pvc1
mountPath: /data/nginx/html
volumes:
# configMap卷
- name: nginx-config
configMap:
name: nginx-config
# pvc卷
- name: nginx-pvc1
persistentVolumeClaim:
claimName: pvc1
readOnly: false
---
apiVersion: v1
kind: Service
metadata:
name: service-nginx
spec:
selector:
app: nginx-pvc
ports:
- name: http
port: 81 #service的端口
targetPort: 80 #容器的端口
nodePort: 30019 #映射node节点的port端口
protocol: TCP
type: NodePort