Persistent Volume(PV)是集群之中的一块网络存储。跟 Node 一样,也是集群的资源。PV 跟 Volume (卷) 类似,不过会有独立于 Pod 的生命周期。它包含了存储的实现细节,例如 NFS、iSCSI 或者其他的云提供商的存储系统。
Persistent Volume Claim (PVC) 是用户的一个请求。跟 Pod 消费 Node 的资源,PVC 消费 PV 的资源。Pod 能够申请特定的资源(CPU 和内存);Claim 能够请求特定的尺寸和访问模式(例如可以加载一个读写,以及多个只读实例)的存储空间。
PV 是集群的资源,PVC 是对这一资源的请求,也是对资源的所有权的检验。PV 和 PVC 生命周期如下:
创建: 集群管理员会创建一系列的 PV。这些 PV 包含了为集群用户提供的真实存储存储资源,它们可利用 Kubernetes API 来申请消费。
绑定: 用户创建一个包含了容量和访问模式的持久卷申请(PVC)。Master节点 会监听 PVC 的产生,并尝试根据请求内容查找匹配的 PV,并把 PV 和 PVC 进行绑定。如果找不到合适的卷,这一申请就会持续处于非绑定状态,一直到出现合适的 PV。例如一个集群准备了很多的 50G 大小的持久卷,就无法响应 100G 的PVC申请,除非把 100G 的 PV 加入集群。
使用: Pod 把申请作为卷来使用。集群会通过 PVC 查找绑定的 PV,并 Mount 给 Pod。用户在使用 PVC 作为卷的时候,可以指定需要的访问方式。一旦用户拥有了一个已经绑定的 PVC,被绑定的 PV 就归该用户所有了。用户的 Pods 能够通过在 Pod 的卷中包含的 PVC 来访问他们占有的 PV。
释放: 当用户完成对卷的使用时,就可以利用 API 删除 PVC 对象了,而且他还可以重新申请。删除 PVC 后,对应的PV视为 “被释放”,但是这时被释放的PV还不能给其他的 PVC 使用。之前的 PVC 数据还保存在卷中,要根据策略来进行后续处理。
回收: PV 的回收策略规定了在 PVC 释放卷的时候,应如何进行处理。目前可以采用三种策略:保留,回收或者删除。
保留策略:允许重新申请这一资源。
删除策略:会同时删除持久卷以及 AWS EBS/GCE PD 或者 Cinder 卷中的存储内容。个人理解 会删除 PV及里边的数据。
回收策略:会执行基础的擦除操作(rm -rf /thevolume/*),这一卷就能被重新申请了。 PV还在 只是删除了里边的数据,
一个PV卷会处于如下状态之一:
Available:可用资源,尚未被绑定到 PVC 上
Bound:该卷已经被绑定
Released:PVC 已经被删除,但该资源尚未被集群回收
Failed:该卷的自动回收过程失败
创建pv
定义配置文件 musql-pv.yml内容如下:
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv-mysql
spec:
# 设置容量
capacity:
storage: 5Gi
# 访问模式
accessModes:
# 该卷能够以读写模式被多个节点同时加载
- ReadWriteMany
# 回收策略,这里是基础擦除 `rm-rf/thevolume/*`
persistentVolumeReclaimPolicy: Recycle
nfs:
# NFS 服务端配置的路径
path: "/usr/local/kubernetes/volumes"
# NFS 服务端地址
server: 192.168.90.37
readOnly: false
创建并查看pv
eric@server1:/usr/local/kubernetes/cluster$ kubectl create -f mysql-pv.yml
persistentvolume/nfs-pv-mysql created
eric@server1:/usr/local/kubernetes/cluster$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
nfs-pv-mysql 5Gi RWX Recycle Available 21s
配置说明
Capacity(容量)
一般来说,PV 会指定存储容量。这里需要使用 PV 的 capcity 属性。目前存储大小是唯一一个能够被申请的指标,后续可能会加入更多属性,例如 IOPS,吞吐能力等。
AccessModes(访问模式)
持久卷能够被以任何资源提供者支持的访问方式加载到主机上。例如 NFS 能够支持多个读写客户端,但是某个 NFS PV 可能会在服务器上以只读方式使用。每个 PV 都有自己的一系列的访问模式,这些访问模式取决于 PV 的能力。访问模式的可选范围如下:
ReadWriteOnce:该卷能够以读写模式被加载到一个节点上
ReadOnlyMany:该卷能够以只读模式加载到多个节点上
ReadWriteMany:该卷能够以读写模式被多个节点同时加载
在 CLI 下,访问模式缩写为:
RWO:ReadWriteOnce
ROX:ReadOnlyMany
RWX:ReadWriteMany
一个卷不论支持多少种访问模式,同时只能以一种访问模式加载
#RecyclingPolicy(回收策略)
当前的回收策略可选值包括:
Retain:人工重新申请
Recycle:基础擦除(rm-rf/thevolume/*)
Delete:相关的存储资产例如 AWS EBS,GCE PD 或者 OpenStack Cinder 卷一并删除
目前,只有 NFS 和 HostPath 支持 Recycle 策略,AWS EBS、GCE PD 以及 Cinder 卷支持 Delete 策略。
配置文件mysql-pvc.yml 内容如下:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc-mysql-myshop
spec:
accessModes:
# 需要使用和 PV 一致的访问模式
- ReadWriteMany
# 按需分配资源
resources:
requests:
storage: 1Gi
创建并查看PVC
eric@server1:/usr/local/kubernetes/cluster$ kubectl create -f mysql-pvc.yml
persistentvolumeclaim/nfs-pvc-mysql-myshop created
eric@server1:/usr/local/kubernetes/cluster$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
nfs-pvc-mysql-myshop Bound nfs-pv-mysql 5Gi RWX 9s
ConfigMap
ConfigMap 是用来存储配置文件的 Kubernetes 资源对象,所有的配置内容都存储在 etcd 中。它可以被用来保存单个属性,也可以用来保存整个配置文件或者 JSON 二进制对象。ConfigMap API 资源提供了将配置数据注入容器的方式,同时保证该机制对容器来说是透明的。配置从 Image 内容中解耦,以此来保持容器化应用程序的可移植性。
创建配置文件 mysql.yml
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-myshop-config
data:
# 这里是键值对数据 对mysql服务进行配置
mysqld.cnf: |
[client]
port=3306
[mysql]
no-auto-rehash
[mysqld]
skip-host-cache
skip-name-resolve
default-authentication-plugin=mysql_native_password
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
explicit_defaults_for_timestamp=true
lower_case_table_names=1
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: mysql-myshop
spec:
replicas: 1
template:
metadata:
labels:
name: mysql-myshop
spec:
containers:
- name: mysql-myshop
image: mysql
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: "123456"
volumeMounts:
# 以数据卷的形式挂载 MySQL 配置文件目录 两个数据卷
- name: cm-vol-myshop
mountPath: /etc/mysql/conf.d
- name: nfs-vol-myshop
mountPath: /var/lib/mysql
volumes:
# 将 ConfigMap 中的内容以文件形式挂载进数据卷 cm-vol-myshop
- name: cm-vol-myshop
configMap:
name: mysql-myshop-config
items:
# ConfigMap 中的 Key
- key: mysqld.cnf
# ConfigMap Key 匹配的 Value 写入名为 mysqld.cnf 的文件中
path: mysqld.cnf
- name: nfs-vol-myshop # nfs-vol-myshop 则使用pvc nfs-pvc-mysql-myshop 来存储
persistentVolumeClaim:
claimName: nfs-pvc-mysql-myshop
---
apiVersion: v1
kind: Service
metadata:
name: mysql-myshop
spec:
ports:
- port: 3306
targetPort: 3306
nodePort: 32036
type: LoadBalancer
selector:
name: mysql-myshop
部署mysql 并查看cm内容
eric@server1:/usr/local/kubernetes/cluster$ kubectl create -f mysql.yml
configmap/mysql-myshop-config created
deployment.extensions/mysql-myshop created
service/mysql-myshop created
eric@server1:/usr/local/kubernetes/cluster$ kubectl get cm
NAME DATA AGE
mysql-myshop-config 1 9s
eric@server1:/usr/local/kubernetes/cluster$ kubectl describe cm mysql-myshop-config
Name: mysql-myshop-config
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
mysqld.cnf:
----
[client]
port=3306
[mysql]
no-auto-rehash
[mysqld]
skip-host-cache
skip-name-resolve
default-authentication-plugin=mysql_native_password
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
explicit_defaults_for_timestamp=true
lower_case_table_names=1
查看mysql服务
eric@server1:/usr/local/kubernetes/cluster$ kubectl get service -A
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d15h
default mysql-myshop LoadBalancer 10.104.140.183 <pending> 3306:32036/TCP 109m
default tomcat-http LoadBalancer 10.98.183.59 <pending> 8080:32168/TCP 7d3h
kube-system kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 7d15h
kubernetes-dashboard dashboard-metrics-scraper ClusterIP 10.98.128.165 <none> 8000/TCP 67m
kubernetes-dashboard kubernetes-dashboard NodePort 10.109.217.122 <none> 443:30423/TCP 67m
链接测试:
这里使用 集群中的 master点和slave节点ip 都可以成功连接。
nfs 上可以看到MySQL数据库的相关数据
drwxr-xr-x 4 root root 4096 Aug 22 12:23 ../
eric@server7:/usr/local/kubernetes/volumes$ ll
total 198076
drwxrwxrwx 7 999 eric 4096 Aug 22 15:58 ./
drwxr-xr-x 4 root root 4096 Aug 22 12:23 ../
-rw-r----- 1 999 docker 56 Aug 22 15:03 auto.cnf
-rw-r----- 1 999 docker 3118706 Aug 22 15:03 binlog.000001
-rw-r----- 1 999 docker 786 Aug 22 15:58 binlog.000002
-rw-r----- 1 999 docker 32 Aug 22 15:04 binlog.index
-rw------- 1 999 docker 1680 Aug 22 15:03 ca-key.pem
-rw-r--r-- 1 999 docker 1112 Aug 22 15:03 ca.pem
-rw-r--r-- 1 999 docker 1112 Aug 22 15:03 client-cert.pem
-rw------- 1 999 docker 1680 Aug 22 15:03 client-key.pem
-rw-r----- 1 999 docker 196608 Aug 22 16:00 '#ib_16384_0.dblwr'
-rw-r----- 1 999 docker 8585216 Aug 22 15:03 '#ib_16384_1.dblwr'
-rw-r----- 1 999 docker 5717 Aug 22 15:03 ib_buffer_pool
-rw-r----- 1 999 docker 12582912 Aug 22 15:58 ibdata1
-rw-r----- 1 999 docker 50331648 Aug 22 16:00 ib_logfile0
-rw-r----- 1 999 docker 50331648 Aug 22 15:03 ib_logfile1
-rw-r----- 1 999 docker 12582912 Aug 22 15:04 ibtmp1
drwxr-x--- 2 999 docker 4096 Aug 22 15:04 '#innodb_temp'/
drwxr-x--- 2 999 docker 4096 Aug 22 15:03 mysql/
-rw-r----- 1 999 docker 31457280 Aug 22 15:58 mysql.ibd
drwxr-x--- 2 999 docker 4096 Aug 22 15:03 performance_schema/
-rw------- 1 999 docker 1676 Aug 22 15:03 private_key.pem
-rw-r--r-- 1 999 docker 452 Aug 22 15:03 public_key.pem
-rw-r--r-- 1 999 docker 1112 Aug 22 15:03 server-cert.pem
-rw------- 1 999 docker 1680 Aug 22 15:03 server-key.pem
drwxr-x--- 2 999 docker 4096 Aug 22 15:03 sys/
drwxr-x--- 2 999 docker 4096 Aug 22 15:58 test/
-rw-r----- 1 999 docker 16777216 Aug 22 16:00 undo_001
-rw-r----- 1 999 docker 16777216 Aug 22 15:58 undo_002