Kubernetes 权威指南 4 源码:

链接

  • Kubernetes CSI

    • CSI 存储插件的挂件组件和部署架构

      • CSI Controller
      • CSI Node
    • CSI 存储插件的使用实例

Kubernetes CSI

Kubernetes 从 1.9 版本开始引入容器存储接口 Container Storage Interface(CSI)机制,用于在 Kubernetes 和外部存储系统之间建立一套标准的存储管理接口,通过该接口为容器提供存储服务。CSI 到 Kubernetes 1.10 版本升级为 Beta 版,到 Kubernetes 1.13 版本升级为 GA 版,已逐渐成熟。

Kubernetes 通过 PV、PVC、Storageclass 已经提供了一种强大的基于插件的存储管理机制,但是各种存储插件提供的存储服务都是基于一种被称为 "in-tree"(树内)的方式提供的,这要求存储插件的代码必须被放进 Kubernetes 的主干代码库中才能被 Kubernetes 调用,属于紧耦合的开发模式。这种 "in-tree" 方式会带来一些问题:

  • 存储插件的代码需要与 Kubernetes 的代码放在同一代码库中,并与 Kubernetes 的二进制文件共同发布。
  • 存储插件代码的开发者必须遵循 Kubernetes 的代码开发规范。
  • 存储插件代码的开发者必须遵循 Kubernetes 的发布流程,包括添加对 Kubernetes 存储系统的支持和错误修复。
  • Kubernetes 社区需要对存储插件的代码进行维护,包括审核、测试等工作。
  • 存储插件代码中的问题可能会影响 Kubernetes 组件的运行并且很难排查问题。
  • 存储插件代码与 Kubernetes 的核心组件(kubelet 和 kube-controller-manager)享有相同的系统特权权限,可能存在可靠性和安全性问题。

Kubernetes 已有的 Flex Volume 插件机制视图通过外部存储暴露一个基于可执行程序(exec)的 API 来解决这些问题。尽管它允许第三方存储提供商在 Kubernetes 核心代码之外开发存储驱动,但仍然有两个问题没有得到很好的解决:

  • 部署第三方驱动的可执行文件仍然需要宿主机的 root 权限,存在安全隐患。
  • 存储插件在执行 mount、attach 这些操作时,通常需要在宿主机上安装一些第三方工具包和依赖库,使得部署过程更加复杂,例如部署 Ceph 时需要安装 rbd 库,部署 GlusterFS 时需要安装 mount.glusterfs 库,等等。

基于以上这些问题和考虑,Kubernetes 逐步推出与容器对接的存储接口标准,存储提供方只需要基于标准接口进行存储插件的实现,就能使用 Kubernetes 的原生存储机制为容器提供存储服务。这套标准被称为 CSI(容器存储接口)。在 CSI 成为 Kubernetes 的存储提供标准之后,存储提供方的代码就能和 Kubernetes 代码彻底解耦,部署也与 Kubernetes 核心组件分离,显然,存储插件的开发由提供方自行维护,就能为 Kubernetes 用户提供更多的存储功能,也更加安全可靠。基于 CSI 的存储插件机制也被称为 "out-of-tree"(树外)的服务提供方式,是未来 Kubernetes 第三方存储插件的标准方案。

CSI 存储插件的挂件组件和部署架构

其中主要包括两个组件:CSI Controller 和 CSI Node。

CSI Controller

CSI Controller 的主要功能是提供存储服务视角对存储资源和存储卷进行管理和操作。在 Kubernetes 中建议将其部署为单实例 Pod,可以实验 StatefulSet 或 Deployment 控制器进行部署,设置副本数量为 1,保证为一种存储插件只运行一个控制器实例。

在这个 Pod 内部署两个容器,如下所述。

(1)与 Master(kube-controller-manager)通信的辅助 sidecar 容器。

在 sidecar 容器内由可以包含 external-attacher 和 external-provisioner 两个容器,它们的功能分别如下:

  • external-attacher:监控 VolumeAttachment 资源对象的变更,触发针对 CSI 端点的 ControllerPublish 和 ControllerUnpublish 操作。
  • external-provisioner:监控 PersistentVolumeClaim 资源对象的变更,触发针对 CSI 端点 CreateVolume 和 DeleteVolume 操作。

(2)CSI Driver 存储驱动容器,由第三方存储提供商提供,需要实现上述接口。

这两个容器通过本地 Socket(Unix Domain Socket,UDS),并使用 gRPC 协议进行通信。sidecar 容器通过 Socket 调用 CSO Driver 容器的 CSI 接口,CSI Driver 容器负责具体的存储操作。

CSI Node

CSI Node 的主要功能是对主机(Node)上的 Volume 进行管理和操作。在 Kubernetes 中建议将其部署为 DaemonSet,在每个 Node 上都运行一个 Pod。

在这个 Pod 中部署以下两个容器:

(1)与 Kubelet 通信的辅助 sidecar 容器 node-driver-registrar,主要功能是将存储驱动注册到 Kubelet 中;

(2)CSI Driver 存储驱动容器,由第三方存储提供商提供,主要功能是接收 kubelet 的调用,需要实现一系列与 Node 相关的 CSI 接口,例如 NodePublishVolume 接口(用于 Volume 挂载到容器内的目标路径)、NodeUnpublishVolume 接口(用于从容器中卸载 Volume),等等。

node-driver-registrar 容器与 kubelet 通过 Node 主机的一个 hostPath 目录下的 unix socket 进行通信。CSI Driver 容器与 kubelet 通过 Node 主机的另一个 hostPath 目录下的 unix socket 进行通信,同时需要将 kubelet 的工作目录(默认为 /var/lib/kubelet)挂载给 CSI Driver 容器,用于为 Pod 进行 Volume 的管理操作(包括 mount,umount 等)。

CSI 存储插件的使用实例

下面以 csi-hostpath 插件为例,对如何部署 CSI 插件、用户如何使用 CSI 插件提供的存储资源进行详细说明。

(1)设置 Kubernetes 服务启动参数。为 kube-apiserver、kube-controller-manager 和 kubelet 服务的启动参数添加:

--feature-gates=VolumeSnapshotDataSource=true,CSINodeInfo=true,CSIDriverRegistry=true

这 3 个特性开关是 Kubernetes 从 1.12 版本引入的 Alpha 版功能,CSINodeInfo 和 CSIDriverRegistry 需要手工创建其相应的 CRD 资源对象。

Kubernetes 1.10 版本所需的 CSIPersistentVolume 和 MountPropagation 特性开关已经默认启用,KubeletPluginsWatcher 特性开关也在 Kubernetes 1.12 版本中默认开启,无需在命令行参数中指定。

(2)创建 CSINodeInfo 和 CSIDriverRegistry CRD 资源对象。

csidriver.yml 展开源码

csinodeinfo 资源如下:

csinodeinfo.yml 展开源码

创建资源:

$ kubectl apply -f csidriver.yml -f csinodeinfo.yml

customresourcedefinition.apiextensions.k8s.io/csidrivers.csi.storage.k8s.io created

customresourcedefinition.apiextensions.k8s.io/csinodeinfos.csi.storage.k8s.io created

(3)创建 csi-hostpath 存储插件相关组件,包括 csi-hostpath-atttacher、csi-hostpath-provisioner 和 csi-hostpathplugin(其中包含 csi-node-driver-registrar 和 hostpathplugin)。其中为每个组件都配置了相应的 RBAC 权限控制规则,对于安全访问 Kubernetes 资源对象非常重要。

csi-hostpath-attacher.yml

apiVersion: v1

kind: ServiceAccount

metadata:

  name: csi-attacher

  # replace with non-default namespace name

  namespace: default

---

kind: ClusterRole

apiVersion: rbac.authorization.k8s.io/v1

metadata:

  name: external-attacher-runner

rules:

  - apiGroups: [""]

    resources: ["persistentvolumes"]

    verbs: ["get""list""watch""update"]

  - apiGroups: [""]

    resources: ["nodes"]

    verbs: ["get""list""watch"]

  - apiGroups: ["csi.storage.k8s.io"]

    resources: ["csinodeinfos"]

    verbs: ["get""list""watch"]

  - apiGroups: ["storage.k8s.io"]

    resources: ["volumeattachments"]

    verbs: ["get""list""watch""update"]

---

kind: ClusterRoleBinding

apiVersion: rbac.authorization.k8s.io/v1

metadata:

  name: csi-attacher-role

subjects:

  - kind: ServiceAccount

    name: csi-attacher

    # replace with non-default namespace name

    namespace: default

roleRef:

  kind: ClusterRole

  name: external-attacher-runner

  apiGroup: rbac.authorization.k8s.io

---

kind: Role

apiVersion: rbac.authorization.k8s.io/v1

metadata:

  # replace with non-default namespace name

  namespace: default

  name: external-attacher-cfg

rules:

- apiGroups: [""]

  resources: ["configmaps"]

  verbs: ["get""watch""list""delete""update""create"]

---

kind: RoleBinding

apiVersion: rbac.authorization.k8s.io/v1

metadata:

  name: csi-attacher-role-cfg

  # replace with non-default namespace name

  namespace: default

subjects:

  - kind: ServiceAccount

    name: csi-attacher

    # replace with non-default namespace name

    namespace: default

roleRef:

  kind: Role

  name: external-attacher-cfg

  apiGroup: rbac.authorization.k8s.io

---

kind: Service

apiVersion: v1

metadata:

  name: csi-hostpath-attacher

  labels:

    app: csi-hostpath-attacher

spec:

  selector:

    app: csi-hostpath-attacher

  ports:

    - name: dummy

      port: 12345

---

kind: StatefulSet

apiVersion: apps/v1

metadata:

  name: csi-hostpath-attacher

spec:

  serviceName: "csi-hostpath-attacher"

  replicas: 1

  selector:

    matchLabels:

      app: csi-hostpath-attacher

  template:

    metadata:

      labels:

        app: csi-hostpath-attacher

    spec:

      serviceAccountName: csi-attacher

      containers:

        - name: csi-attacher

          image: quay.io/k8scsi/csi-attacher:v1.0.1

          imagePullPolicy: IfNotPresent

          args:

            - --v=5

            - --csi-address=$(ADDRESS)

          env:

            - name: ADDRESS

              value: /csi/csi.sock

          volumeMounts:

          - mountPath: /csi

            name: socket-dir

      volumes:

        - hostPath:

            path: /var/lib/kubelet/plugins/csi-hostpath

            type: DirectoryOrCreate

          name: socket-dir

csi-hostpath-provisioner.yml 展开源码

大家都知道,香港的服务器作为网站的空间的选择具有独特的优势。从网络运营的专业角度来说,香港服务器首先是没有像国内服务器需要备案的步骤,这可省掉了一部分时间,其次,香港服务器的速度相对于国内的服务器来说快的多。当然,了解服务器的大神们都知道,欧美地区的主流还是以美国服务器为主的市场导向。不过萝卜青菜各有所爱。今天,我想帮助您分析怎么去选择香港服务器。

  香港服务器的选择在核心性能上与海外独立服务器的差别具体细节如下:

  第一,服务与技术支持。

  作为空间是我们需要需要长期存放网站重要数据的地方。只要外贸企业做一天,香港服务器就要运行一天!因此,在选择服务器时,外贸企业参考目标更多的是 24 小时不间断技术支持的香港服务器!

  第二,带宽。

  很多企业使用香港服务器比较看中的就是它的带宽,这也是访问速度的先决条件。这里推荐3A网络香港服务器,它采用的是BGP线路,国际带宽。对于企业用户来说,访问速度、数据安全都有非常大的保障,直接连接国际主干网。

  第二,机房。

  在选择香港机房时,良好的服务不仅为我们提供了非常可靠的技术支持和保证,而且其配套设施,包括带宽、机房环境、温度和数据安全,也决定了我们看中它的原因。

  第三,存储空间及相关设施

  在选择服务器的时候我们需要判断网站的数据资料存放要多少存储空间,如何选择中央处理器也即是cpu的大小。这块可以联系网站客服为您量身定制

我相信香港服务器是我们经常接触的海外服务器之一,大家在选择的时候也会是通过以上几个方面选择的,不过还是在这友情提醒下业界大佬们还是刚接触这个的新人,在选择时可以通过服务器的价格,服务态度和直观的测试速度上多做对比,这样选择的产品服务才是比较满意的嘛!

csi-hostpathplugin.yml 展开源码

创建服务:

$ kubectl apply -f csi-hostpath-attacher.yml -f csi-hostpath-provisioner.yml -f csi-hostpathplugin.yml

serviceaccount/csi-attacher created

clusterrole.rbac.authorization.k8s.io/external-attacher-runner created

clusterrolebinding.rbac.authorization.k8s.io/csi-attacher-role created

role.rbac.authorization.k8s.io/external-attacher-cfg created

rolebinding.rbac.authorization.k8s.io/csi-attacher-role-cfg created

service/csi-hostpath-attacher created

statefulset.apps/csi-hostpath-attacher created

serviceaccount/csi-provisioner created

clusterrole.rbac.authorization.k8s.io/external-provisioner-runner created

clusterrolebinding.rbac.authorization.k8s.io/csi-provisioner-role created

role.rbac.authorization.k8s.io/external-provisioner-cfg created

rolebinding.rbac.authorization.k8s.io/csi-provisioner-role-cfg created

service/csi-hostpath-provisioner created

statefulset.apps/csi-hostpath-provisioner created

serviceaccount/csi-node-sa created

clusterrole.rbac.authorization.k8s.io/driver-registrar-runner created

clusterrolebinding.rbac.authorization.k8s.io/csi-driver-registrar-role created

daemonset.apps/csi-hostpathplugin created

确保 3 个 Pod 都运行正常:

$ kubectl get pod

NAME                                READY   STATUS    RESTARTS   AGE

csi-hostpath-attacher-0             1/1     Running   0          109s

csi-hostpath-provisioner-0          1/1     Running   0          109s

csi-hostpathplugin-44s8n            2/2     Running   0          109s

csi-hostpathplugin-qdfht            2/2     Running   0          109s

至此就完成了 CSI 存储插件的部署。

(4)应用容器使用 CSI 存储。应用程序如果希望使用 CSI 存储插件提供的存储服务,则仍然使用 Kubernetes 动态存储管理机制。首先通过创建 StorageClass 和 PVC 为应用容器准备存储资源,然后容器就可以挂载 PVC 到容器内的目录进行使用了。

创建一个 StorageClass,provisioner 为 CSI 存储插件的类型,

csi-storageclass.yml

apiVersion: storage.k8s.io/v1

kind: StorageClass

metadata:

  name: csi-hostpath-sc

provisioner: csi-hostpath

reclaimPolicy: Delete

volumeBindingMode: Immediate

创建一个 PV,引用刚刚创建的 StorageClass,申请存储空间为 1GiB:

csi-pvc.yml

apiVersion: v1

kind: PersistentVolumeClaim

metadata:

  name: csi-pvc

spec:

  accessModes:

  - ReadWriteOnce

  resources:

    requests:

      storage: 1Gi

  storageClassName: csi-hostpath-sc

创建服务:

$ kubectl apply -f csi-storageclass.yml -f csi-pvc.yml

storageclass.storage.k8s.io/csi-hostpath-sc created

persistentvolumeclaim/csi-pvc created

查看 PVC 和系统自动创建的 PV,状态为 Bound,说明创建成功:

$ kubectl get pv,pvc

NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM             STORAGECLASS      REASON   AGE

persistentvolume/pvc-8882d70e-92a4-11e9-81cd-42010aae0008   1Gi        RWO            Delete           Bound    default/csi-pvc   csi-hostpath-sc            30s

NAME                            STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE

persistentvolumeclaim/csi-pvc   Bound    pvc-8882d70e-92a4-11e9-81cd-42010aae0008   1Gi        RWO            csi-hostpath-sc   32s

最后,在应用容器的配置使用该 PVC:

pod.yml

kind: Pod

apiVersion: v1

metadata:

  name: my-csi-app

spec:

  containers:

    - name: my-csi-app

      image: busybox

      imagePullPolicy: IfNotPresent

      command: [ "sleep""1000000" ]

      volumeMounts:

      - mountPath: "/data"

        name: my-csi-volume

  volumes:

    - name: my-csi-volume

      persistentVolumeClaim:

        claimName: csi-pvc

在创建 Pod 成功之后,应用容器中的 /data 目录使用的就是 CSI 存储插件提供的存储。通过 kubelet 的日志可以查看到 Volume 挂载的详细过程:

pod.yml

$ kubectl apply -f pod.yml

pod/my-csi-app created

Kubernetes CSI相关推荐

  1. 阿里云Kubernetes CSI实践—NAS动态存储卷使用

    1. 前言 NAS存储盘能将nfs(网络文件系统)挂载到你的Pod中,阿里云Kubernetes CSI支持静态存储卷挂载和动态存储卷挂载2种方式, 在静态存储卷挂载的方式中,通常需要手动编辑和创建一 ...

  2. kubernetes CSI(中)

    在<kubernetes CSI(上)>一文中,我们对kubernetes存储的发展有了简单的了解,并且在文中提到了CSI中负责注册的组件node-driver-registrar,本文我 ...

  3. kubernetes CSI(下)

    前面几篇文章分别介绍了dynamic provisioning.CSI接口定义和CSI插件的注册等内容,这篇文章基于这些内容,尝试实现一个NFS的CSI,这个CSI主要包含注册.dynamic pro ...

  4. Kubernetes CSI 介绍及使用

    CSI 介绍及使用 和 Flexvolume 类似,CSI 也是为第三方存储提供数据卷实现的抽象接口. 有了 Flexvolume,为何还要 CSI 呢? Flexvolume 只是给 kuberne ...

  5. Kubernetes CSI(一):介绍

    容器存储接口(CSI)是用于将任意块和文件存储系统暴露给诸如Kubernetes之类的容器编排系统(CO)上的容器化工作负载的标准.使用CSI的第三方存储提供商可以编写和部署在Kubernetes中公 ...

  6. kubernetes CSI(上)

    随着应用容器化的趋势,越来越多的应用部署到了kubernetes平台,同时日益复杂的业务场景,也使得kubernetes需要支持越来越多类别的存储.kubernete对存储的支持,大致可以分为三个历程 ...

  7. Kubernetes的安全性怎么解?从4个方面为你列出方案清单

    导语 Kubernetes中的安全性是一个多维问题,必须从各个不同的角度来解决才算完善,这篇文章将从4个方面为读者列出安全清单. 正文 Kubernetes,经过更快的采用和社区的更多贡献,正日益攀登 ...

  8. Kubernetes学习总结(5)——Kubernetes 常见面试题汇总

    简述etcd及其特点 etcd是CoreOS团队发起的开源项目,是一个管理配置信息和服务发现(service discovery)的项目,它的目标是构建一个高可用的分布式键值(key-value)数据 ...

  9. IT运维面试问题总结-LVS、Keepalived、HAProxy、Kubernetes、OpenShift

    文章目录 1.简述ETCD及其特点 2.简述ETCD适应的场景? 3.简述HAProxy及其特性 4.简述HAProxy常见的负载均衡策略? 5.简述负载均衡四层和七层的区别? 6.简述LVS.Ngi ...

  10. kubernetes存储:local,openEBS,rook ceph

    文章目录 Local 存储(PV) 概念 hostPath Local PV storageClassName指定延迟绑定动作 pv的删除流程 OpenEBS存储 控制平面 OpenEBS PV Pr ...

最新文章

  1. 【Qt】ubuntu14.04.5 qt5.6中使用opencv3.4报错:Using GTK+ 2.x and GTK+ 3 in the same process is not supported
  2. 最强的Attention函数诞生啦,带给你意想不到的巨大提升!
  3. 如何设置eclipse下查看java源码
  4. 《集体智慧编程》——第一章导读
  5. 机器学习之工程师入门路线
  6. python 大智慧股池_大智慧的一般设置及股票池的安装步骤、使用方法
  7. App版本更新接口的设计
  8. pic单片机流水灯循环右移c语言,PIC单片机流水灯程序
  9. bypass-wts-waf
  10. undi是什么意思_undefined什么意思?
  11. 腾讯云“黑石”真相——“物理私服”
  12. 大型网站的架构技术-学习自李智慧的书
  13. iOS判断当前设备机型 (包含至iPhone XS Max)
  14. 习题6 3.6.2 典型题例解析 3.6.3 自测训练
  15. 单片机串口连接电脑,USB转TTL线的使用
  16. 澳门SEO优化:名词诠释大全以及新站上线后,seo优化应该如何做?
  17. 《利用python进行数据分析》第二版 第14章-数据分析示例 学习笔记1
  18. 7-1 过河 (15 分)java版
  19. SqlServer邮件
  20. C#像素鸟(独自一鸟闯天下)

热门文章

  1. java swap_Java中swap()方法的实现
  2. Java实现生产者消费者的PV操作信号量操作
  3. 新居住时代是什么样的?一岁的贝壳给出了最佳答案
  4. 条形图的几种处理方式
  5. 史上最全的 SQL 注入资料,收藏不谢
  6. 如何清除电脑桌面图标蓝底
  7. 新晋流量操盘手(一行) 探索百度贴吧高阶引流玩法
  8. cf1675 F.Vlad and Unfinished Business
  9. tt作曲家简谱打谱软件_每个人的本地作曲家! 会议友好的满意设置
  10. 股权-公司治理的至高点,如何合理运用股权(融人、融资、融市场) 张明若