<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>volume | 伪架构师</title>
    <link>/tags/volume/</link>
      <atom:link href="/tags/volume/index.xml" rel="self" type="application/rss+xml" />
    <description>volume</description>
    <generator>Source Themes Academic (https://sourcethemes.com/academic/)</generator><language>zh</language><lastBuildDate>Fri, 24 Jan 2020 14:35:19 +0800</lastBuildDate>
    <image>
      <url>/img/logo-wide.png</url>
      <title>volume</title>
      <link>/tags/volume/</link>
    </image>
    
    <item>
      <title>CSI 的内联暂存卷</title>
      <link>/post/csi-ephemeral-inline-volumes/</link>
      <pubDate>Fri, 24 Jan 2020 14:35:19 +0800</pubDate>
      <guid>/post/csi-ephemeral-inline-volumes/</guid>
      <description>

&lt;p&gt;原文：&lt;a href=&#34;https://kubernetes.io/blog/2020/01/21/csi-ephemeral-inline-volumes/&#34; target=&#34;_blank&#34;&gt;CSI Ephemeral Inline Volumes&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;作者：&lt;a href=&#34;https://github.com/pohly&#34; target=&#34;_blank&#34;&gt;Patrick Ohly&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Kubernetes 利用外部存储驱动提供出来的存储卷一般来说都是持久化的，它的生命周期可以完全独立于 Pod，（特定情况下）也可以和第一个用到该卷的 Pod（&lt;a href=&#34;https://kubernetes.io/docs/concepts/storage/storage-classes/#volume-binding-mode&#34; target=&#34;_blank&#34;&gt;后绑定模式&lt;/a&gt;）有着宽松的耦合关系。在 Kubernetes 中使用 PVC 和 PV 对象完成了存储卷的申请和供给机制。起初，容器存储接口（CSI）支持的存储卷只能用于 PVC/PV 的场合。&lt;/p&gt;

&lt;p&gt;但有些情况下，数据卷的内容和生命周期是和 Pod 紧密相关的。例如有的驱动会使用动态的创建 Secret 生成卷，这个 Secret 是为了运行在 Pod 中的应用特意创建的。这种卷需要和 Pod 一起生成，并且作为 Pod 的一部分，和 Pod 一起终结。可以在 Pod Spec 中（用内联/inline 的方式）定义这种卷。&lt;/p&gt;

&lt;p&gt;从 Kubernetes 1.15 开始，CSI 驱动也能用于这种内联暂存卷了。这个功能还处于 Alpha 阶段，因此在 1.15 中需要打开 &lt;a href=&#34;https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/&#34; target=&#34;_blank&#34;&gt;CSIInlineVolume 特性开关&lt;/a&gt; 才能尝试使用这一新功能。而 1.16 中，该功能升级为 Beta 阶段，因此是缺省打开的。&lt;/p&gt;

&lt;p&gt;虽说这个功能用到了两个现存的 gRPC 调用（&lt;code&gt;NodePublishVolume&lt;/code&gt; 和 &lt;code&gt;NodeUnpublishVolume&lt;/code&gt;)，但是其中的用法和 CSI 规范并不一致：在暂存卷中，Kubelet 在向 CSI 驱动请求卷时，只调用了 &lt;code&gt;NodePublishVolume&lt;/code&gt;。跳过了其他的（例如 &lt;code&gt;CreateVolume&lt;/code&gt;、&lt;code&gt;NodeStageVolume&lt;/code&gt;）调用，所以要对 CSI 驱动进行一些改变。Pod Spec 中写明了卷参数，这个参数会被拷贝给 &lt;code&gt;NodePublishVolumeRequest.volume_context&lt;/code&gt;。目前没有标准化的参数，即使是容量这种参数也是定义在 CSI 驱动之中的。类似地，在 Pod 结束需要释放存储卷时，只调用了 &lt;code&gt;NodeUnpublishVolume&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;起初有考虑分别为持久化和暂存卷编写不同的 CSI 驱动。但是有些驱动提供的存储在两种模式下都可以使用，例如 &lt;a href=&#34;https://github.com/intel/pmem-csi&#34; target=&#34;_blank&#34;&gt;PMEM-CSI&lt;/a&gt; 管理的是由 Intel Optane 技术提供的持久化内存方式的本地存储。这种类型的存储既可以用作一种比普通 SSD 更快的持久化存储，也可以用作比 DRAM 更大容量的暂时性存储。&lt;/p&gt;

&lt;p&gt;因此在 Kubernetes 1.16 中产生了变化：用户可以使用 &lt;a href=&#34;https://kubernetes-csi.github.io/docs/csi-driver-object.html#what-fields-does-the-csidriver-object-have&#34; target=&#34;_blank&#34;&gt;&lt;code&gt;CSIDriver&lt;/code&gt;&lt;/a&gt; 的 &lt;code&gt;volumeLifecycleModes&lt;/code&gt; 字段来确定该驱动支持的卷类型。启用&lt;a href=&#34;https://kubernetes-csi.github.io/docs/pod-info.html&#34; target=&#34;_blank&#34;&gt;加载时 Pod 信息&lt;/a&gt;功能之后，驱动程序能够获取卷模式的信息，并在 &lt;code&gt;NodePublishRequest.volume_context&lt;/code&gt; 加入 &lt;code&gt;csi.storage.k8s.io/ephemeral&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;关于 CSI 驱动支持内联暂存卷的更多信息，可以浏览 &lt;a href=&#34;https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html&#34; target=&#34;_blank&#34;&gt;Kubernetes CSI 文档&lt;/a&gt; 及其&lt;a href=&#34;https://github.com/kubernetes/enhancements/blob/master/keps/sig-storage/20190122-csi-inline-volumes.md&#34; target=&#34;_blank&#34;&gt;原始设计文档&lt;/a&gt;。&lt;/p&gt;

&lt;p&gt;后续内容中包含了真实的示例以及内容总结。&lt;/p&gt;

&lt;h2 id=&#34;示例&#34;&gt;示例&lt;/h2&gt;

&lt;h3 id=&#34;pmem-csi&#34;&gt;PMEM-CSI&lt;/h3&gt;

&lt;p&gt;在 &lt;a href=&#34;https://github.com/intel/pmem-csi/releases/tag/v0.6.0&#34; target=&#34;_blank&#34;&gt;v0.6.0&lt;/a&gt; 中加入了内联暂存的支持。在使用 Intel Optane 技术的主机上可以使用这种驱动，&lt;a href=&#34;https://github.com/intel/pmem-csi/blob/v0.6.0/examples/gce.md&#34; target=&#34;_blank&#34;&gt;GCE 的特定类型服务器&lt;/a&gt;或者 QEMU 的硬件模拟上都是可用的。&lt;a href=&#34;https://github.com/intel/pmem-csi/tree/v0.6.0#qemu-and-kubernetes&#34; target=&#34;_blank&#34;&gt;QEMU 方式已经集成到了 Makefile&lt;/a&gt;，只需要 Go、Docker 和 KVM 即可，所以示例中用了这种方式：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-plaintext&#34;&gt;git clone --branch release-0.6 https://github.com/intel/pmem-csi
cd pmem-csi
TEST_DISTRO=clear TEST_DISTRO_VERSION=32080 TEST_PMEM_REGISTRY=intel make start
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;启动四节点集群需要一些时间：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-plaintext&#34;&gt;The test cluster is ready. Log in with /work/pmem-csi/_work/pmem-govm/ssh-pmem-govm, run kubectl once logged in.
Alternatively, KUBECONFIG=/work/pmem-csi/_work/pmem-govm/kube.config can also be used directly.

To try out the pmem-csi driver persistent volumes:
...

To try out the pmem-csi driver ephemeral volumes:
   cat deploy/kubernetes-1.17/pmem-app-ephemeral.yaml | /work/pmem-csi/_work/pmem-govm/ssh-pmem-govm kubectl create -f -
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;deploy/kubernetes-1.17/pmem-app-ephemeral.yaml&lt;/code&gt; 定义了一个卷：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;kind: Pod
apiVersion: v1
metadata:
  name: my-csi-app-inline-volume
spec:
  containers:
    - name: my-frontend
      image: busybox
      command: [ &amp;quot;sleep&amp;quot;, &amp;quot;100000&amp;quot; ]
      volumeMounts:
      - mountPath: &amp;quot;/data&amp;quot;
        name: my-csi-volume
  volumes:
  - name: my-csi-volume
    csi:
      driver: pmem-csi.intel.com
      fsType: &amp;quot;xfs&amp;quot;
      volumeAttributes:
        size: &amp;quot;2Gi&amp;quot;
        nsmode: &amp;quot;fsdax&amp;quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Pod 启动之后，可以观察一下：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;$ kubectl describe pods/my-csi-app-inline-volume
Name:         my-csi-app-inline-volume
...
Volumes:
  my-csi-volume:
    Type:              CSI (a Container Storage Interface (CSI) volume source)
    Driver:            pmem-csi.intel.com
    FSType:            xfs
    ReadOnly:          false
    VolumeAttributes:      nsmode=fsdax
                           size=2Gi
$ kubectl exec my-csi-app-inline-volume -- df -h /data
Filesystem                Size      Used Available Use% Mounted on
/dev/ndbus0region0fsdax/d7eb073f2ab1937b88531fce28e19aa385e93696
                          1.9G     34.2M      1.8G   2% /data
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;image-populator&#34;&gt;Image Populator&lt;/h3&gt;

&lt;p&gt;自动解包容器镜像，并以暂存卷的方式访问内容。这个驱动还在开发之中，但是可以用下面的方式安装试用镜像：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-plaintext&#34;&gt;kubectl create -f https://github.com/kubernetes-csi/csi-driver-image-populator/raw/master/deploy/kubernetes-1.16/csi-image-csidriverinfo.yaml
kubectl create -f https://github.com/kubernetes-csi/csi-driver-image-populator/raw/master/deploy/kubernetes-1.16/csi-image-daemonset.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;下面这个 Pod 会运行一个 Nginx，并从 &lt;code&gt;kfox1111/misc:test&lt;/code&gt; 镜像中获取数据提供服务：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;$ kubectl create -f - &amp;lt;&amp;lt;EOF
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.13-alpine
    ports:
    - containerPort: 80
    volumeMounts:
    - name: data
      mountPath: /usr/share/nginx/html
  volumes:
  - name: data
    csi:
      driver: image.csi.k8s.io
      volumeAttributes:
          image: kfox1111/misc:test
EOF
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;测试一下读取数据：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;$ kubectl exec nginx -- cat /usr/share/nginx/html/test
testing
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;cert-manager-csi&#34;&gt;cert-manager-csi&lt;/h3&gt;

&lt;p&gt;这个驱动和 &lt;a href=&#34;https://github.com/jetstack/cert-manager&#34; target=&#34;_blank&#34;&gt;cert-manager&lt;/a&gt; 协同工作，其目的是无缝地为 Pod 完成证书的请求和加载。这对于 mTLS 或者其它需要使用可信、有效证书的 Pod 间安全连接的工作是很有意义的。这个项目还在实验之中。&lt;/p&gt;

&lt;h2 id=&#34;下一步&#34;&gt;下一步&lt;/h2&gt;

&lt;p&gt;提出这个功能的原因之一就是，Kubernetes 把一个 Pod 调度到节点上时，对节点的存储情况是无知的。Pod 被调度之后，CSI 必须在该节点上创建卷。如果失败，Pod 无法启动，这个过程会一直持续到存储卷可用。&lt;a href=&#34;https://github.com/kubernetes/enhancements/pull/1353&#34; target=&#34;_blank&#34;&gt;存储能力跟踪的 KEP&lt;/a&gt; 是一个解决问题的尝试。&lt;/p&gt;

&lt;p&gt;另外还有一个相关的 &lt;a href=&#34;https://github.com/kubernetes/enhancements/pull/1409&#34; target=&#34;_blank&#34;&gt;用于标准化容量参数的 KEP&lt;/a&gt;。&lt;/p&gt;

&lt;h2 id=&#34;相关链接&#34;&gt;相关链接&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;CSI Ephemeral Inline Volumes：&lt;code&gt;https://kubernetes.io/blog/2020/01/21/csi-ephemeral-inline-volumes/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Patrick Ohly：&lt;code&gt;https://github.com/pohly&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;后绑定模式：&lt;code&gt;https://kubernetes.io/docs/concepts/storage/storage-classes/#volume-binding-mode&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;CSIInlineVolume 特性开关：&lt;code&gt;https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;PMEM-CSI：&lt;code&gt;https://github.com/intel/pmem-csi&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CSIDriver&lt;/code&gt;：&lt;code&gt;https://kubernetes-csi.github.io/docs/csi-driver-object.html#what-fields-does-the-csidriver-object-have&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;加载时 Pod 信息：&lt;code&gt;https://kubernetes-csi.github.io/docs/pod-info.html&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Kubernetes CSI 文档：&lt;code&gt;https://kubernetes-csi.github.io/docs/ephemeral-local-volumes.html&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;原始设计文档：&lt;code&gt;https://github.com/kubernetes/enhancements/blob/master/keps/sig-storage/20190122-csi-inline-volumes.md&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;v0.6.0：&lt;code&gt;https://github.com/intel/pmem-csi/releases/tag/v0.6.0&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;GCE 的特定类型服务器：&lt;code&gt;https://github.com/intel/pmem-csi/blob/v0.6.0/examples/gce.md&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;QEMU 方式已经集成到了 Makefile：&lt;code&gt;https://github.com/intel/pmem-csi/tree/v0.6.0#qemu-and-kubernetes&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;cert-manager：&lt;code&gt;https://github.com/jetstack/cert-manager&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;存储能力跟踪的 KEP：&lt;code&gt;https://github.com/kubernetes/enhancements/pull/1353&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;用于标准化容量参数的 KEP：&lt;code&gt;https://github.com/kubernetes/enhancements/pull/1409&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
  </channel>
</rss>
