Kubernetes数据持久化

本文主要讲解Kubernetes 数据如何持久化。如有错误请指正。

环境准备

m:192.168.8.51
w1: 192.168.8.61
w2: 192.168.8.62

nfs 服务放在m机器上

Volume

官网 : https://kubernetes.io/docs/concepts/storage/volumes/

容器里面的数据都是临时,如果容器不存在了,数据也会跟着丢失。在docker中也有volume 的概念,但是它的volume 功能比较单一,并且无法管理,无法满足Kubernetes的需求。我们知道Pod里面的container是可以共享数据的,所以pod是如何解决数据存储的?

Host 类型

需求:定义一个pod,包含两个container,互相共享volume

定义一个volumes,并且通过volumeMounts 进行绑定

#volume-pod.yml
apiVersion: v1
kind: Pod
metadata:
  name: volume-pod
spec:
  containers:
  - name: nginx-container
    image: nginx
    ports:
    - containerPort: 80
    volumeMounts:
    - name: volume-pod
      mountPath: /nginx-volume
  - name: busybox-container
    image: busybox
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']
    volumeMounts:
    - name: volume-pod
      mountPath: /busybox-volume
  volumes:
  - name: volume-pod
    hostPath:
      path: /tmp/volume-pod 
kubectl apply -f volume-pod.yml
kubectl get pods -o wide
docker ps | grep volume    # 到相应的机器查看

在这里插入图片描述
在w2上查看,docker ps | grep volume。并且验证目录/tmp/volume-pod是否是映射到两个container的目录
在这里插入图片描述

Persistent Volumes

官网: https://kubernetes.io/docs/concepts/storage/persistent-volumes/
实际上就是提供一些抽象的API ,定义了如何管理存储。然后由各种服务商去实现相关功能。这就涉及到了两个API : PersistentVolume(PV) and PersistentVolumeClaim(PVC)。

PVs are resources in the cluster. PVCs are requests for those resources and also act as claim checks to the resource.

PV 是对接存储服务,PVC 是消费这些存储服务,他们两者之间存在一个一对一的绑定关系。PV定义了如何分配和使用服务,比如存储服务的地址,多少G,访问模式等信息。而PVC 则是定义程序需要使用多少的的存储空间,相关程序就可以通过指定使用某个PVC,从而达到使用PV目的。说白了,PV就是volume 的一个插件,封装了底层的存储实现。他们之间的关系如下:在这里插入图片描述

PVC & PV 实战

1、分别创建Nginx-pod、PVC、PV

#定义一个PV
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nginx-pv
spec:
  accessModes:
    - ReadWriteMany
  capacity:
    storage: 2Gi
  nfs:
    path: /nfs/data/nginx
    server: 192.168.8.51

#定义PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nginx-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 2Gi
 #定义一个pod,并指定PVC
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        name: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - name: nginx-persistent-storage
          mountPath: /usr/share/nginx/html
      volumes:
      - name: nginx-persistent-storage
        persistentVolumeClaim:
          claimName: nginx-pvc

2、启动三个pod

kubectl apply -f nginx-pv.yml
kubectl apply -f nginx-pvc.yml
kubectl apply -f nginx-pod.yml

在这里插入图片描述
3、验证是否成功

在nfs 服务器上新建一个文件。/nfs/data/nginx/my.html
在这里插入图片描述
在第二步中我们知道Nginx 部署在第一台机器,IP=192.168.190.69。可以使用curl 192.168.190.69/1.html 访问内容,如果有会返回,则说明刚才在nfs服务器创建的文件已经同步过去了
在这里插入图片描述

StorageClass

使用PV和PVC可以很方便将我们想要持久化的资源存在一个远程服务器中。但是这个方式还是有些不方便,比如需要写很多个PV供PVC使用,这样不但重复做一样的东西,还不方便管理。

A StorageClass provides a way for administrators to describe the “classes” of storage they offer. Different classes might map to quality-of-service levels, or to backup policies, or to arbitrary policies determined by the cluster administrators. Kubernetes itself is unopinionated about what classes represent. This concept is sometimes called “profiles” in other storage systems.

Each StorageClass contains the fields provisioner, parameters, and reclaimPolicy, which are used when a PersistentVolume belonging to the class needs to be dynamically provisioned.

The name of a StorageClass object is significant, and is how users can request a particular class. Administrators set the name and other parameters of a class when first creating StorageClass objects, and the objects cannot be updated once they are created.

说白了 StorageClass声明存储插件,创建PV的模板,用于自动创建PV,这个插件可以根据指定的服务器类型来创建PV。其中有两个重要部分:PV属性和创建此PV所需要的插件。这样PVC就可以按“Class”来匹配PV。可以为PV指定storageClassName属性,标识PV归属于哪一个Class。

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

有了StorageClass之后的PVC可以变成这样

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: test-claim1
spec:
accessModes:
    - ReadWriteMany
resources:
 requests:
    storage: 1Mi
  storageClassName: nfs

StorageClass之所以能够动态供给PV,是因为Provisioner,也就是Dynamic Provisioning。但是NFS这种类型,K8s中默认是没有Provisioner插件的,需要自己创建

https://github.com/kubernetes-incubator/external-storage/tree/master/nfs

实战

1、storageClass能自动帮我们创建PV,所以它需要一个APIServer访问权限。
2、创建PV是一个插件,所以需要一个插件的yml,运行在k8s中。
在这里插入图片描述

#rbac.yml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-provisioner-runner
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"]
  - apiGroups: [""]
    resources: ["services", "endpoints"]
    verbs: ["get"]
  - apiGroups: ["extensions"]
    resources: ["podsecuritypolicies"]
    resourceNames: ["nfs-provisioner"]
    verbs: ["use"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: run-nfs-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-provisioner
     # replace with namespace where provisioner is deployed
    namespace: default
roleRef:
  kind: ClusterRole
  name: nfs-provisioner-runner
  apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-provisioner
rules:
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-provisioner
    # replace with namespace where provisioner is deployed
    namespace: default
roleRef:
  kind: Role
  name: leader-locking-nfs-provisioner
  apiGroup: rbac.authorization.k8s.io
#deployment.yml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-provisioner
---
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: nfs-provisioner
spec:
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nfs-provisioner
    spec:
      serviceAccount: nfs-provisioner
      containers:
        - name: nfs-provisioner
          image: registry.cn-hangzhou.aliyuncs.com/open-ali/nfs-client-provisioner
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: example.com/nfs
            - name: NFS_SERVER
              value: 192.168.8.51
            - name: NFS_PATH
              value: /nfs/data/chihay
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.8.51
            path: /nfs/data/chihay
#storageclass
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
 name: example-nfs
provisioner: example.com/nfs

分别运行rbac.yml,deployment.yml和storageclass.yml

3、创建PVC

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Mi
  # 这个名字要和上面创建的storageclass名称一致
  storageClassName: example-nfs

4、创建一个pod使用PVC

kind: Pod
apiVersion: v1
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    volumeMounts:
      - name: my-pvc
        mountPath: "/usr/chihay"
  restartPolicy: "Never"
  volumes:
    - name: my-pvc
      persistentVolumeClaim:
        claimName: my-pvc

分别运行PVC和Nginx的yml之后,查看结果PV自动呗创建了。
在这里插入图片描述
5、验证
nfs 会自动创建一个文件夹
在这里插入图片描述
在文件夹内创建一个文件,看是否能同步到pod中
在这里插入图片描述
在这里插入图片描述

PV的状态和回收策略

PV状态

  • Available:表示当前的pv没有被绑定

  • Bound:表示已经被pvc挂载

  • Released:pvc没有在使用pv, 需要管理员手工释放pv

  • Failed:资源回收失败

PV回收策略

  • Retain:表示删除PVC的时候,PV不会一起删除,而是变成Released状态等待管理员手动清理

  • Recycle:在Kubernetes新版本就不用了,采用动态PV供给来替代

  • Delete:表示删除PVC的时候,PV也会一起删除,同时也删除PV所指向的实际存储空间

注意:目前只有NFS和HostPath支持Recycle策略。AWS EBS、GCE PD、Azure Disk和Cinder支持Delete策略

总结

至此,我们可以将一个pod的数据从主机移动到一台网络服务器上了。
hostpah->persistentVolumeClaim->storageclass
在这里插入图片描述

1、对于PV或者StorageClass只能对应一种远端的存储,NFS或者EBS
2、Pod想要使用共享存储,那就需要在创建PVC,在PVC中描述了想要什么类型的远端存储、空间等,K8s从而会去匹配对应的PV,如果没有匹配成功,Pod就会处于Pending状态。
3、pod 与PVC 是多对多关系,PV 与 PVC是一对一关系。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值