一. k8s服务种类
1. 无状态
- 没有存储, pod挂掉会被拉起来, 来保证pod实例数量
- K8S的Service后面可以挂多个Pod,实现服务的高可用, 比如常用的nginx就为无状态服务
2. 普通有状态
- k8s提供
Volume和Persistent Volume为基础的存储系统,可以实现服务的状态保存 - 常用的k8s中部署的Jenkins就是普通有状态服务
3. 有状态集群
- 在普通有状态的基础上, 通过
Headless Service(无头服务), 来将实现有状态服务的集群或高可用, 例如redis集群, mysql主从等等
二. k8s 存储
1. Volumes
- 不做过多介绍, 参考官网
2. PersistentVolume
PersistentVolume(持久卷, PV), 是集群中的一块存储, PV是集群资源,作用于所有namespace- PV 卷的供应有两种方式: 静态供应或动态供应(StorageClass)
3. PersistentVolumeClaim
PersistentVolumeClaim(持久卷声明, PVC), 是用户对存储的请求, 概念上与 Pod 类似, Pod 会耗用节点资源,而 PVC 声明会耗用 PV 资源PVC 声明请求以特定的大小和访问模式, 可以要求 PV 卷能够以
ReadWriteOnce、ReadOnlyMany或ReadWriteMany模式之一来挂载ReadWriteOnce简称
RWO, 卷可以被一个节点以读写方式挂载。 ReadWriteOnce 访问模式也允许运行在同一节点上的多个 Pod 访问卷ReadOnlyMany简称
ROX, 卷可以被多个节点以只读方式挂载ReadWriteMany简称
RWX, 卷可以被多个节点以读写方式挂载ReadWriteOncePod简称
RWOP, 卷可以被单个 Pod 以读写方式挂载。 如果你想确保整个集群中只有一个 Pod 可以读取或写入该 PVC, 请使用ReadWriteOncePod 访问模式。这只支持 CSI 卷以及需要 Kubernetes 1.22 以上版本
4. 存储回收
- 当不再使用其存储卷时,可以从 API 中将 PVC 对象删除,从而允许 该资源被回收再利用。
PersistentVolume对象的回收策略告诉集群,目前数据卷可以被Retained(保留)、Recycled(回收)或Deleted(删除)- 回收策略
Recycle已被废弃, 取而代之的建议方案是使用动态供应
- 回收策略
三. Kubernetes StorageClass

StorageClass是k8s存储类, 每个StorageClass都包含provisioner、parameters和reclaimPolicy字段, 这些字段会在StorageClass需要动态分配 PersistentVolume 时会使用到- 每个
StorageClass都有一个制备器(Provisioner),用来决定使用哪个卷插件制备 PV。 该字段必须指定 - 由 StorageClass 动态创建的 PersistentVolume 会在类的
reclaimPolicy字段中指定回收策略,可以是Delete或者Retain。如果 StorageClass 对象被创建时没有指定reclaimPolicy,它将默认为Delete
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
reclaimPolicy: Retain # 线上是用的默认的
allowVolumeExpansion: true
mountOptions:
- debug
volumeBindingMode: Immediate

1. 创建StorageClass
vim provisioner.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-es-provisioner
labels:
app: nfs-es-provisioner
namespace: logging
spec:
replicas: 1
selector:
matchLabels:
app: nfs-es-provisioner
strategy:
type: Recreate
selector:
matchLabels:
app: nfs-es-provisioner
template:
metadata:
labels:
app: nfs-es-provisioner
spec:
serviceAccountName: nfs-es-provisioner
containers:
- name: nfs-es-provisioner
image: quay.io/external_storage/nfs-client-provisioner:latest
imagePullPolicy: IfNotPresent
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: nfs-es # 和storageclass的provisioner字段必须一致才对接的上.
- name: NFS_SERVER
value: 192.168.188.225 # nfs服务端地址
- name: NFS_PATH
value: /data # 挂载的路径
volumes:
- name: nfs-client-root
nfs:
server: 192.168.188.225
path: /data
vim rbac.yaml
kind: ServiceAccount
apiVersion: v1
metadata:
name: nfs-es-provisioner
namespace: logging
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nfs-es-provisioner-runner
namespace: logging
rules:
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: run-nfs-es-provisioner
namespace: logging
subjects:
- kind: ServiceAccount
name: nfs-es-provisioner
namespace: logging
roleRef:
kind: ClusterRole
name: nfs-es-provisioner-runner
apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-es-provisioner
namespace: logging
rules:
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-es-provisioner
namespace: logging
subjects:
- kind: ServiceAccount
name: nfs-es-provisioner
namespace: logging
roleRef:
kind: Role
name: leader-locking-nfs-es-provisioner
apiGroup: rbac.authorization.k8s.io
vim storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-es
provisioner: nfs-es
2. 使用StorageClass
vim redis-sts.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis-app
namespace: logging
labels:
k8s-app: redis
spec:
serviceName: redis-service
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
replicas: 3
template:
metadata:
labels:
app: redis
appCluster: redis-cluster
spec:
terminationGracePeriodSeconds: 20
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- redis
topologyKey: kubernetes.io/hostname
containers:
- name: redis
image: redis
imagePullPolicy: IfNotPresent
command:
- "redis-server"
args:
- "/etc/redis/redis.conf"
- "--protected-mode"
- "no"
resources:
requests:
cpu: "100m"
memory: "100Mi"
ports:
- name: redis
containerPort: 6379
protocol: "TCP"
- name: cluster
containerPort: 16379
protocol: "TCP"
volumeMounts:
- name: "redis-conf"
mountPath: "/etc/redis"
- name: "redis-data"
mountPath: "/var/lib/redis"
volumes:
- name: "redis-conf"
configMap:
name: "redis-conf"
items:
- key: "redis.conf"
path: "redis.conf"
volumeClaimTemplates:
- metadata:
name: redis-data
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: nfs-es
resources:
requests:
storage: 300M
四. Volume Snapshots
1. VolumeSnapshotContent和VolumeSnapshot
- 与
PersistentVolume和PersistentVolumeClaim两个 API 资源用于提供卷类似,VolumeSnapshotContent和VolumeSnapshot两个 API 资源用于给用户和管理员创建卷快照VolumeSnapshotContent类似于PersistentVolume属于集群资源, 是一种快照VolumeSnapshot类似于PersistentVolumeClaim, 作用于namespace, 是对于卷的快照的请求
2. VolumeSnapshotClass
就像
StorageClass为提供了一种在配置卷时描述存储“类”的方法,VolumeSnapshotClass提供了一种在配置卷快照时描述存储“类”的方法。每个
VolumeSnapshotClass都包含driver、deletionPolicy和parameters字段,当需要动态配置属于该类的VolumeSnapshot时使用VolumeSnapshotClass对象的名称很重要,是用户可以请求特定类的方式。 管理员在首次创建VolumeSnapshotClass对象时设置类的名称和其他参数,对象一旦创建就无法更新
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
name: csi-hostpath-snapclass
driver: hostpath.csi.k8s.io
deletionPolicy: Delete
parameters:
卷快照类具有
deletionPolicy属性。用户可以配置当所绑定的 VolumeSnapshot 对象将被删除时,如何处理 VolumeSnapshotContent 对象。 卷快照类的这个策略可以是Retain或者Delete。这个策略字段必须指定如果删除策略是
Delete,那么底层的存储快照会和 VolumeSnapshotContent 对象 一起删除。如果删除策略是Retain,那么底层快照和 VolumeSnapshotContent 对象都会被保留