k8s存储

nfs

理论上nfs 其实并不是存储设备,它是一种远程共享存储服务。

k8s 存储卷 volume

emptyDir:可以实现pod中的容器之间共享数据, 但是存储卷不能持久化数据,且会随着pod的生命周期一起删除。

hostpash:可以实现持久化数据,使用node节点的目录或文件挂载到容器,但是存储空间会受到node节点单机的限制,一旦node节点故障,数据会丢失,pod会跨node节点,不能共享数据。

nfs:可以实现持久化存储,使用nfs存储设备空间挂载到容器,pod可以跨节点共享数据。

pv和pvc

pv有两种创建方式,分为静态和动态。

静态指运维手动创建pv和pvc。k8s存储_第1张图片

 动态指用storageclass自动创建pv

k8s存储_第2张图片

PV和PVC之间的相互作用遵循这个生命周期:

Provisioning (配置)---> Binding (绑定) ---> Using (使用) ---> Releasing (释放) ---> Recycling (回收)

PV 的状态有以下 4 种:

●Available(可用):表示可用状态,还未被任何 PVC 绑定

●Bound(已绑定):表示 PV 已经绑定到 PVC

●Released(已释放):表示 PVC 被删掉,但是资源尚未被集群回收

●Failed(失败):表示该 PV 的自动回收失败

一个PV从创建到销毁的具体流程

1、一个PV创建完后状态会变成Available,等待被PVC绑定。

2、一旦被PVc邦定,Pv的状态会变成Bound,就可以被定义了相应PVC的Pod使用。

3、Pod使用完后会释放PV,PV的状态变成Released

4、变成Released的EV会根据定义的回收筑略做相应的回收工作。(有三种回收策略,Retain、Delete和Becycle。)

Retain策略:就是保留现场,K8S集群什么也不做,等待用户手动去处理里的数据,处理完后,再手动删除EV。

Delete策略:K8S会自动删除该pv及里面的数据。

Recycle策略:K8S会将pV里的数据删除,然后把pv的状态变成Available,又可以被新的PVC绑定使用。

pv访问模式

ReadWriteOnce #(RWO)存储可读可写,但只支持被单个 Pod 挂载

ReadOnlyMany #(ROX)存储可以以只读的方式被多个 Pod 挂载

ReadWriteMany #(RWX)存储可以以读写的方式被多个 Pod 共享

静态Pv的使用

准备存储设备和共享目录

创建pv 资源 配置 存储类型 访问模式 存储能力大小

创建pvc资源 配置请求pv 资源的访问模式和存储大小 绑定PV,PVC和PV是一对一的绑定关系。

PV访问模式必须支持PVc的请求访问模式,请求的存储空间会优先选择相等存储大小的PV资源,如果没有会选择大于请求的存储大小的PV资源。

创建Pod资源,存储类型设置成 persistentvolumeclaims,在容器配置中存储挂载。

动态storage

动态创建PV不同的设备支持的插件不一样 我们是以nfs为例

StorageClass动态创建pv的过程

StorageClass+NES+provisioner

准备NES 共享服务器和共享目录。

创建sa 服务账号 ,进行RBAC 资源操作权限的授权。

创建nfs-client-provisioner存储卷插件 (以pod的形式运行的),配置中要关联sa服务账号使得存储卷插件获得相关资源的操作权限。

创建 StorageClass资源,配置中要关联存储卷插件的名称配置。

----以上过程是一劳永逸, 以后只需要创建pvc 就可以动态生成相关的PV资源。

创建pvc在配置中要关联storageClass资源的名称,此时会在NEs服务器上生成相关的PV的共享目录。

创建pod 资源存储类型设置成persistentVolumeclaims,在容器配置中配置存储挂载。

搭建 StorageClass + NFS,实现 NFS 的动态 PV 创建

1、在stor01节点上安装nfs,并配置nfs服务
mkdir /opt/k8s
chmod 777 /opt/k8s/

vim /etc/exports
/opt/k8s 192.168.11.0/24(rw,no_root_squash,sync)

systemctl restart nfs

2、创建 Service Account,用来管理 NFS Provisioner 在 k8s 集群中运行的权限
vim nfs-client-rbac.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: nfs-client-provisioner-clusterrole
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: ["endpoints"]
    verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: nfs-client-provisioner-clusterrolebinding
subjects:
- kind: ServiceAccount
  name: nfs-client-provisioner
  namespace: default
roleRef:
  kind: ClusterRole
  name: nfs-client-provisioner-clusterrole
  apiGroup: rbac.authorization.k8s.io

kubectl apply -f nfs-client-rbac.yaml
3、使用 Deployment 来创建 NFS Provisioner
vim /etc/kubernetes/manifests/kube-apiserver.yaml
    - --feature-gates=RemoveSelfLink=false       #添加这一行

kubectl apply -f /etc/kubernetes/manifests/kube-apiserver.yaml
kubectl delete pods kube-apiserver -n kube-system 
kubectl get pods -n kube-system | grep apiserver

k8s存储_第3张图片

创建 NFS Provisioner

kind: Deployment
apiVersion: apps/v1
metadata:
  name: nfs-client-provisioner
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nfs-client-provisioner
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-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-storage
            - name: NFS_SERVER
              value: stor01
            - name: NFS_PATH
              value: /data/volumes
      volumes:
        - name: nfs-client-root
          nfs:
            server: stor01
            path: /data/volumes

kubectl apply -f nfs-client-provisioner.yaml 
kubectl get pod
4、创建 StorageClass

vim nfs-client-storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-client-storageclass
provisioner: nfs-storage
parameters:
  archiveOnDelete: "false"

kubectl apply -f nfs-client-storageclass.yaml

k8s存储_第4张图片

k8s存储_第5张图片

5、创建 PVC 和 Pod 测试

vim test-pvc.yaml 
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-nfs-pvc
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: nfs-client-storageclass
  resources:
    requests:
      storage: 1Gi

vim test-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-storageclass-pod
spec:
  containers:
  - name: nginx
    image: nginx:1.14
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: nfs-pvc
      mountPath: /usr/share/nginx/html
  volumes:
  - name: nfs-pvc
    persistentVolumeClaim:
      claimName: test-nfs-pvc

kubectl apply -f test-pvc.yaml test-pod.yaml

k8s存储_第6张图片

k8s存储_第7张图片

kubectl get pvc

去nfs查看是否生成目录

你可能感兴趣的:(kubernetes,容器,云原生)