k8s快速入门教程-----7 数据管理

   首先我们会学习Volume, 以及Kubernetes如何通过Volume 为集群中的容器提供存储;然后我们会实践几种常用的Volume 类型并理解它们各自的应用场景;最后,我们会讨论Kubernetes如何通过Persistent Volume和Persistent Volume Claim分离集群管理员与集群用户的职责,并实践Volume的静态供给和动态供给。

7.1 volume

7.1.1 emptyDir

    emptyDir是最基础的Volume类型。正如其名字所示,一个emptyDir Volume是Host上的一个空目录。emptyDir Volume 对于容器来说是持久的,对于Pod则不是。当Pod从节点删除时,Volume的内容也会被删除。但如果只是容器被销毁而Pod还在,则Volume不受影响。也就是说: emptyDir Volume的生命周期与Pod-致。
    Pod中的所有容器都可以共享Volume, 它们可以指定各自的mount 路径。
apiVersion: v1
kind: Pod
metadata:
  name: producer-consumer
spec:
  containers:
  - name: producer
    image: wangjinxiong/nginx:tools
    volumeMounts:
    - name: shared-volume
      mountPath: /usr/share/nginx/html   # (2)
  volumes:
  - name: shared-volume   # (1)
    emptyDir: {}

(1) 文件最底部volumes 定义了一个emptyDir 类型的Volume shared-volume
(2 ) 将volume shared-volume 挂载到容器producer的/usr/share/nginx/html

通过docker命令可以查看,可以看到shared-volume的保存目录。

docker inspect d30522745908  # 通过docker ps | grep  producer-consumer查看ID 
........
"Mounts": [
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/02c1e853-e863-4dc6-8b5a-91e08a8592f4/volumes/kubernetes.io~empty-dir/shared-volume",
                "Destination": "/usr/share/nginx/html",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
   emptyDir是Host上创建的临时目录,其优点是能够方便地为Pod中的容器提供共享存储,不需要额外的配置。它不具备持久性,如果Pod 不存在了,emptyDir 也就没有了。根据这个特性,emptyDir特别适合Pod中的容器需要临时共享存储空间的场景,比如前面的生产者消费者用例。

7.1.2 hostpath

   hostPathVolume的作用是将DockerHost文件系统中已经存在的目录mount给Pod的容器。大部分应用都不会使用hostPath Volume,因为这实际上增加了Pod 与节点的耦合,限制了Pod 的使用。不过那些需要访问Kubernetes 或Docker 内部数据(配置文件和二进制库)的应用则需要使用hostPath。比如kube- apiserver和kube- controller-manager就是这样的应用,通过kubectl edit --namespace=kube -system pod kube- apiserver- k8s-master查看kube-apiserver Pod的配置,Volume的相关部分如图9-5所示。
 volumeMounts:
    - mountPath: /etc/ssl/certs
      name: ca-certs
      readOnly: true
    - mountPath: /etc/pki
      name: etc-pki
      readOnly: true
    - mountPath: /etc/kubernetes/pki
      name: k8s-certs
      readOnly: true
  dnsPolicy: ClusterFirst
  enableServiceLinks: true
  hostNetwork: true
  nodeName: k8s-master
  preemptionPolicy: PreemptLowerPriority
  priority: 2000001000
  priorityClassName: system-node-critical
  restartPolicy: Always
  schedulerName: default-scheduler
  securityContext: {}
  terminationGracePeriodSeconds: 30
  tolerations:
  - effect: NoExecute
    operator: Exists
  volumes:
  - hostPath:
      path: /etc/ssl/certs
      type: DirectoryOrCreate
    name: ca-certs
  - hostPath:
      path: /etc/pki
      type: DirectoryOrCreate
    name: etc-pki
  - hostPath:
      path: /etc/kubernetes/pki
      type: DirectoryOrCreate
    name: k8s-certs

这里定义了三个hostPath: volume k8s、 certs 和pki, 分别对应Host目录/etc/kubermetes、/etc/ssl/certs和/etc/pki. 如果Pod被销毁了,hostPath 对应的目录还是会被保留,从这一.点来看,hostPath 的持久性比emptyDir 强。不过- -旦Host 崩溃,hostPath 也就无法访问了。

   hostpath 宿主机本地目录保存,pod删除时不会删除数据,但宿主机故障不能迁移到其他nodes节点。
apiVersion: v1
kind: Pod
metadata:
  name: producer-consumer
spec:
  containers:
  - name: producer
    image: wangjinxiong/nginx:tools
    volumeMounts:
    - name: shared-volume
      mountPath: /usr/share/nginx/html   # (2)
  volumes:
  - name: shared-volume
    hostPath:
      path: /tmp    #(1)
      type: Directory

(1) 文件最底部volumes 定义了一个hostpath 类型的Volume shared-volume
(2 ) 将volume shared-volume 挂载到容器producer的/usr/share/nginx/html

通过docker命令可以查看,可以看到shared-volume的保存目录。

docker inspect 8ab46de51ba2   # 通过docker ps | grep  producer-consumer查看ID 
"Mounts": [
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/03aa0d37-c68f-46a6-8353-f275b0101a57/etc-hosts",
                "Destination": "/etc/hosts",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/03aa0d37-c68f-46a6-8353-f275b0101a57/containers/producer/95e21b36",
                "Destination": "/dev/termination-log",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Type": "bind",
                "Source": "/tmp",
                "Destination": "/usr/share/nginx/html",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            },

7.2 PV && PVC

   PersistentVolumeClaim (PVC) 是对 PV的申请(Claim) 。PVC通常由普通用户创建和维护。需要为Pod分配存储资源时,用户可以创建一个PVC,指明存储资源的容量大小和访问模式(比如只读)等信息,Kubernetes 会查找并提供满足条件的PV。有了PersistentVolumeClaim, 用户只需要告诉Kubernetes 需要什么样的存储资源,而不

必关心真正的空间从哪里分配、如何访问等底层细节信息。这些Storage Provider的底层信息交给管理员来处理,只有管理员才应该关心创建PersistentVolume 的细节信息。

7.2.1 PV/PVC静态供给

作为准备工作,我们已经在k8s-master 节点上搭建了一个NFS服务器,目录为/nfsdata。

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv0908
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteMany
  nfs:
    path: /nfsdata
    server: 10.0.12.16

7.2.1.1 创建pv

# kubectl apply -f pv0908.yaml 
persistentvolume/pv0908 created
# kubectl get pv
NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv0908   5Gi        RWX            Retain           Available                                   7s

STATUS为Available, 表示pv0908就绪,可以被PVC申请。
pvc的yaml文件:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc0908
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 5Gi

7.2.1.2 创建pvc

[root@k8s-master ~]# kubectl apply -f pvc0908.yaml 
persistentvolumeclaim/pvc0908 created
[root@k8s-master ~]# kubectl apply -f pvc0908.yaml ^C
[root@k8s-master ~]# kubectl get pvc
NAME      STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
pvc0908   Bound    pv0908   5Gi        RWX                           5s
[root@k8s-master ~]# kubectl get pv
NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM             STORAGECLASS   REASON   AGE
pv0908   5Gi        RWX            Retain           Bound    default/pvc0908                           7m18s

从kubectl get pvc和kubectl get pv的输出可以看到pv0908已经Bound到pv0908,申请成功。

7.2.1.3 pvc应用到pod

apiVersion: v1
kind: Pod
metadata:
  name: nginx0908
spec:
  containers: 
  - name: nginx
    image: wangjinxiong/nginx:tools
    ports:
    - containerPort: 80
    volumeMounts:
    - name: www
      mountPath: /usr/share/nginx/html
  volumes:
  - name: www
    persistentVolumeClaim:
      claimName: pvc0908

进入容器:

# kubectl exec -it nginx0908 -- /bin/bash
root@nginx0908:/# cd /usr/share/nginx/html/
root@nginx0908:/usr/share/nginx/html# echo "wangjinxiong" > index.html

访问pod的主页:

# kubectl get pod -o wide | grep nginx0908
nginx0908                        1/1     Running   0          5m53s   172.18.235.197   k8s-master   <none>           <none>
# curl 172.18.235.197
wangjinxiong

查看后端存储:

# kubectl describe pv pv0908
Name:            pv0908
Labels:          <none>
Annotations:     pv.kubernetes.io/bound-by-controller: yes
Finalizers:      [kubernetes.io/pv-protection]
StorageClass:    
Status:          Bound
Claim:           default/pvc0908
Reclaim Policy:  Retain
Access Modes:    RWX
VolumeMode:      Filesystem
Capacity:        5Gi
Node Affinity:   <none>
Message:         
Source:
    Type:      NFS (an NFS mount that lasts the lifetime of a pod)
    Server:    10.0.12.16
    Path:      /nfsdata
    ReadOnly:  false
Events:        <none>
# 查看nfs文件
# cd /nfsdata/
[root@k8s-master nfsdata]# ls
index.html

7.2.2 PV生命周期

**AccessModes(访问模式): **
AccessModes 是用来对 PV 进行访问模式的设置,用于描述用户应用对存储资源的访问权限,访问权限包括下面几种方式:
• ReadWriteOnce(RWO):读写权限,但是只能被单个节点挂载
• ReadOnlyMany(ROX):只读权限,可以被多个节点挂载
• ReadWriteMany(RWX):读写权限,可以被多个节点挂载
*RECLAIM POLICY(回收策略): **
目前 PV 支持的策略有三种:
• Retain(保留): 保留数据,需要管理员手工清理数据 , 默认。
• Recycle(回收):清除 PV 中的数据,效果相当于执行 rm -rf /ifs/kuberneres/

• Delete(删除):与 PV 相连的后端存储同时删除
**STATUS(状态): **
一个 PV 的生命周期中,可能会处于4中不同的阶段:
• Available(可用):表示可用状态,还未被任何 PVC 绑定
• Bound(已绑定):表示 PV 已经被 PVC 绑定
• Released(已释放):PVC 被删除,但是资源还未被集群重新声明
• Failed(失败): 表示该 PV 的自动回收失败

7.2.3 PV 动态供给(StorageClass)

在前面的例子中,我们提前创建了PV, 然后通过PVC申请PV并在Pod中使用,这种方式叫作静态供给( Static Provision)。与之对应的是动态供给(Dynamical Provision),即如果没有满足PVC 条件的PV,会动态创建PV。 相比静态供给,动态供给有明显的优势:不需要提前创建PV,减少了管理员的工作量,效率高。动态供给是通过StorageClass 实现的,StorageClass 定义了如何创建PV,下面给出两个例子。

7.2.3.1 创建pvc

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: pvc0908-nfs
  annotations:
    volume.beta.kubernetes.io/storage-provisioner: nfs-provisioner-01
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 2Gi
  storageClassName: nfs-server

7.2.3.2 pvc应用到deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx0908
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx0908
  template:
    metadata:
      labels:
        app: nginx0908
    spec:
      volumes:
        - name: host-time
          hostPath:
            path: /etc/localtime
            type: ''
        - name: pvc0908-nfs
          persistentVolumeClaim:
            claimName: pvc0908-nfs
      containers:
      - image: wangjinxiong/nginx:tools
        name: nginx
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
          name: web80
        volumeMounts:
        - mountPath: /etc/localtime
          name: host-time
          readOnly: true
        - name: pvc0908-nfs
          mountPath: /usr/share/nginx/html

查看pvc相关情况:

# kubectl get pvc
NAME          STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
pvc0908-nfs   Bound    pvc-fab208e9-ca70-4129-8d67-78d89011e726   2Gi        RWX            nfs-server     18m
# kubectl describe pv pvc-fab208e9-ca70-4129-8d67-78d89011e726
Name:            pvc-fab208e9-ca70-4129-8d67-78d89011e726
Labels:          <none>
Annotations:     pv.kubernetes.io/provisioned-by: nfs-provisioner-01
Finalizers:      [kubernetes.io/pv-protection]
StorageClass:    nfs-server
Status:          Bound
Claim:           default/pvc0908-nfs
Reclaim Policy:  Delete
Access Modes:    RWX
VolumeMode:      Filesystem
Capacity:        2Gi
Node Affinity:   <none>
Message:         
Source:
    Type:      NFS (an NFS mount that lasts the lifetime of a pod)
    Server:    10.0.12.16
    Path:      /nfsdata/default-pvc0908-nfs-pvc-fab208e9-ca70-4129-8d67-78d89011e726
    ReadOnly:  false
Events:        <none>

nfs server情况:

# cd /nfsdata/
# ls 
default-pvc0908-nfs-pvc-fab208e9-ca70-4129-8d67-78d89011e726
# 

下一篇:8 secret and configmap

你可能感兴趣的:(kubernetes入门教程,kubernetes,docker,PVC,PV,storageclass)