zoukankan      html  css  js  c++  java
  • 深入剖析Kubernetes学习笔记:StatefulSet(19)

    一、如果你并不知道有哪些 Volume 类型可以用,要怎么办呢?

    1、如果你并不知道有哪些 Volume 类型可以用,要怎么办呢?

    1、一窍不通

    2、暴露公司基础设施秘密的风险

    比如,下面这个例子,就是一个声明了 Ceph RBD 类型 Volume 的 Pod:

    apiVersion: v1
    kind: Pod
    metadata:
      name: rbd
    spec:
      containers:
        - image: kubernetes/pause
          name: rbd-rw
          volumeMounts:
          - name: rbdpd
            mountPath: /mnt/rbd
      volumes:
        - name: rbdpd
          rbd:
            monitors:
            - '10.16.154.78:6789'
            - '10.16.154.82:6789'
            - '10.16.154.83:6789'
            pool: kube
            image: foo
            fsType: ext4
            readOnly: true
            user: admin
            keyring: /etc/ceph/keyring
            imageformat: "2"
            imagefeatures: "layering"
    

    这也是为什么,在后来的演化中,Kubernetes 项目引入了一组叫作 Persistent Volume Claim(PVC)和 Persistent Volume(PV)的 API 对象,大大降低了用户声明和使用持久化 Volume 的门槛。

    二、有了 PVC 之后,一个开发人员想要使用一个 Volume,只需要简单的两步即可

    1、第一步:定义一个 PVC,声明想要的 Volume 的属性:

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: pv-claim
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi

    在这个 PVC 对象里,不需要任何关于 Volume 细节的字段,只有描述性的属性和定义。

    2、第二步:在应用的 Pod 中,声明使用这个 PVC:

    apiVersion: v1
    kind: Pod
    metadata:
      name: pv-pod
    spec:
      containers:
        - name: pv-container
          image: nginx
          ports:
            - containerPort: 80
              name: "http-server"
          volumeMounts:
            - mountPath: "/usr/share/nginx/html"
              name: pv-storage
      volumes:
        - name: pv-storage
          persistentVolumeClaim:
            claimName: pv-claim
    

    3、这些符合条件的 Volume 又是从哪里来的呢?

     答案是,它们来自于由运维人员维护的 PV(Persistent Volume)对象。接下来,我们一起看一个常见的 PV 对象的 YAML 文件:

    kind: PersistentVolume
    apiVersion: v1
    metadata:
      name: pv-volume
      labels:
        type: local
    spec:
      capacity:
        storage: 10Gi
      rbd:
        monitors:
        - '10.16.154.78:6789'
        - '10.16.154.82:6789'
        - '10.16.154.83:6789'
        pool: kube
        image: foo
        fsType: ext4
        readOnly: true
        user: admin
        keyring: /etc/ceph/keyring
        imageformat: "2"
        imagefeatures: "layering"

    4、“接口”和“实现

     PVC 和 PV 的设计

     避免“扯皮”

    5、volumeClaimTemplates

    而 PVC、PV 的设计,也使得 StatefulSet 对存储状态的管理成为了可能。我们还是以上一篇文章中用到的 StatefulSet 为例(你也可以借此再回顾一下《深入理解 StatefulSet(一):拓扑状态》中的相关内容):

    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: web
    spec:
      serviceName: "nginx"
      replicas: 2
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.9.1
            ports:
            - containerPort: 80
              name: web
            volumeMounts:
            - name: www
              mountPath: /usr/share/nginx/html
      volumeClaimTemplates:
      - metadata:
          name: www
        spec:
          accessModes:
          - ReadWriteOnce
          resources:
            requests:
              storage: 1Gi

     字段

    PVC和POD编号一致

     PVC 与 PV 的绑定

    所以,我们在使用 kubectl create 创建了 StatefulSet 之后,就会看到 Kubernetes 集群里出现了两个 PVC:

    $ kubectl create -f statefulset.yaml
    $ kubectl get pvc -l app=nginx
    NAME        STATUS    VOLUME                                     CAPACITY   ACCESSMODES   AGE
    www-web-0   Bound     pvc-15c268c7-b507-11e6-932f-42010a800002   1Gi        RWO           48s
    www-web-1   Bound     pvc-15c79307-b507-11e6-932f-42010a800002   1Gi        RWO           48s

    <PVC 名字 >-<StatefulSet 名字 >-< 编号 >

    三、验证一下上述 Volume 的分配情况:

    我们前面已经讲到过,这个 StatefulSet 创建出来的所有 Pod,都会声明使用编号的 PVC。比如,在名叫 web-0 的 Pod 的 volumes 字段,它会声明使用名叫 www-web-0 的 PVC,从而挂载到这个 PVC 所绑定的 PV。

    所以,我们就可以使用如下所示的指令,在 Pod 的 Volume 目录里写入一个文件,来验证一下上述 Volume 的分配情况:

    $ for i in 0 1; do kubectl exec web-$i -- sh -c 'echo hello $(hostname) > /usr/share/nginx/html/index.html'; done

    如上所示,通过 kubectl exec 指令,我们在每个 Pod 的 Volume 目录里,写入了一个 index.html 文件。这个文件的内容,正是 Pod 的 hostname。比如,我们在 web-0 的 index.html 里写入的内容就是 "hello web-0"。

    此时,如果你在这个 Pod 容器里访问“http://localhost”,你实际访问到的就是 Pod 里 Nginx 服务器进程,而它会为你返回 /usr/share/nginx/html/index.html 里的内容。这个操作的执行方法如下所示:

    如上所示,通过 kubectl exec 指令,我们在每个 Pod 的 Volume 目录里,写入了一个 index.html 文件。这个文件的内容,正是 Pod 的 hostname。比如,我们在 web-0 的 index.html 里写入的内容就是 "hello web-0"。

    此时,如果你在这个 Pod 容器里访问“http://localhost”,你实际访问到的就是 Pod 里 Nginx 服务器进程,而它会为你返回 /usr/share/nginx/html/index.html 里的内容。这个操作的执行方法如下所示:

    $ for i in 0 1; do kubectl exec -it web-$i -- curl localhost; done
    hello web-0
    hello web-1
    

    现在,关键来了。

    如果你使用 kubectl delete 命令删除这两个 Pod,这些 Volume 里的文件会不会丢失呢?

    $ kubectl delete pod -l app=nginx
    pod "web-0" deleted
    pod "web-1" deleted
    

    # 在被重新创建出来的 Pod 容器里访问 http://localhost
    $ kubectl exec -it web-0 -- curl localhost
    hello web-0
    

     这是怎么做到的呢?

    1、恢复这个 Pod 的过程

    2、需要注意的是

    3、StatefulSet 创建 Pod 的标准流程。

     通过这种方式,Kubernetes 的 StatefulSet 就实现了对应用存储状态的管理。

    详细梳理一下

    1、首先

    2、其次

    3、最后

    四、小结

    1、StatefulSet 的设计思想

    2、编号

    实际上,在下一篇文章的“有状态应用”实践环节,以及后续的讲解中,你就会逐渐意识到,StatefulSet 可以说是 Kubernetes 中作业编排的“集大成者”。

    因为,几乎每一种 Kubernetes 的编排功能,都可以在编写 StatefulSet 的 YAML 文件时被用到。

  • 相关阅读:
    随笔:判断一个范围内有多少质数,分别是多少
    随笔:判断一个整数是否是质数,如果不是质数,那么因数表达式是什么
    随笔:Python发送SMTP邮件方法封装
    Python基础学习:打印九九乘法表
    随笔:docker学习笔记(包括了基础学习和制作运行jar包的docker镜像,还有centos7防火墙这个坑)
    随笔:测试心得
    随笔:docker安装
    Python基础:Python连接MySQL数据库方法封装2
    随笔:Python打印临时日志、清空临时日志
    radio点击一下选中,再点击恢复未选状态
  • 原文地址:https://www.cnblogs.com/luoahong/p/12425761.html
Copyright © 2011-2022 走看看