Kubernetes hostpath和local volume
<p></p><div class="toc"><div class="toc-container-header">目录</div><ul><li>1、hostPath volume存在的问题</li><li>2、local persistent volume工作机制</li><li>3、使用local persistent volume注意事项</li><li>4、local volume manager</li><li>5、总结</li></ul></div><p></p><blockquote>
<p>很多人对hostPath volume和local persistent volume的使用场景还存在很多困惑。下面对这两种volume的使用场景、基本的工作机制进行了分析,介绍了使用时的注意事项,并简单介绍local volume manager如何帮助administrator进行local persistent volume的生命周期管理的</p>
</blockquote>
<h2 id="1hostpath-volume存在的问题">1、hostPath volume存在的问题</h2>
<p>过去我们经常会通过hostPath volume让Pod能够使用本地存储,将Node文件系统中的文件或者目录挂载到容器内,但是hostPath volume的使用是很难受的,并不适合在生产环境中使用。<br>
我们先看看hostPath Type有哪些类型:</p>
<table>
<thead>
<tr>
<th>取值</th>
<th>行为</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td>空字符串(默认)用于向后兼容,这意味着在安装 hostPath 卷之前不会执行任何检查。</td>
</tr>
<tr>
<td>DirectoryOrCreate</td>
<td>在给定路径上必须存在的目录。</td>
</tr>
<tr>
<td>FileOrCreate</td>
<td>如果在给定路径上什么都不存在,那么将在那里根据需要创建空文件,权限设置为 0644,具有与 Kubelet 相同的组和所有权。</td>
</tr>
<tr>
<td>File</td>
<td>在给定路径上必须存在的文件。</td>
</tr>
<tr>
<td>Socket</td>
<td>在给定路径上必须存在的 UNIX 套接字。</td>
</tr>
<tr>
<td>CharDevice</td>
<td>在给定路径上必须存在的字符设备。</td>
</tr>
<tr>
<td>BlockDevice</td>
<td>在给定路径上必须存在的块设备。</td>
</tr>
</tbody>
</table>
<p>看起来支持这么多type还是挺好的,但为什么说不适合在生产环境中使用呢?</p>
<ul>
<li>
<p>由于集群内每个节点的差异化,要使用<code>hostPath Volume</code>,我们需要通过<code>NodeSelector</code>等方式进行精确调度,这种事情多了,你就会不耐烦了。</p>
</li>
<li>
<p>注意<code>DirectoryOrCreate</code>和<code>FileOrCreate</code>两种类型的<code>hostPath</code>,当<code>Node</code>上没有对应的<code>File/Directory</code>时,你需要保证<code>kubelet</code>有在 <code>Node上Create File/Directory</code>的权限。</p>
</li>
<li>
<p>另外,如果<code>Node</code>上的文件或目录是由<code>root</code>创建的,挂载到容器内之后,你通常还要保证容器内进程有权限对该文件或者目录进行写入,比如你需要以<code>root</code>用户启动进程并运行于<code>privileged</code>容器,或者你需要事先修改好<code>Node</code>上的文件权限配置。</p>
</li>
<li>
<p><code>Scheduler</code>并不会考虑<code>hostPath volume</code>的大小,<code>hostPath</code>也不能申明需要的<code>storage</code>size,这样调度时存储的考虑,就需要人为检查并保证。</p>
</li>
</ul>
<h2 id="2local-persistent-volume工作机制">2、local persistent volume工作机制</h2>
<p><code>Local persistent volume</code>就是用来解决 <code>hostPath volume</code>面临的<code>portability</code>,<code>disk accounting, and scheduling</code>的缺陷。<code>PV Controller</code>和<code>Scheduler</code>会对<code>local PV</code>做特殊的逻辑处理,以实现<code>Pod</code>使用本地存储时发生<code>Pod re-schedule</code>的情况下能再次调度到<code>ocal volume</code>所在的<code>Node</code>。</p>
<p><code>local pv</code>在生产中使用,也是需要谨慎的,毕竟它本质上还是使用的是节点上的本地存储,如果没有相应的存储副本机制,那意味着一旦节点或者磁盘异常,使用该<code>volume</code>的<code>Pod</code>也会异常,甚至出现数据丢失,除非你明确知道这个风险不会对你的应用造成很大影响或者允许数据丢失。</p>
<p>那么通常什么情况会使用<code>Local PV</code>呢?</p>
<ul>
<li>
<p>比如节点上的目录数据是从远程的网络存储上挂载或者预先读取到本地的,为了能加速<code>Pod</code>读取这些数据的速度,相当于起<code>Cache</code>作用,这种情况下因为只读,不存在惧怕数据丢失。这种<code>AI</code>训练中存在需要重复利用并且训练数据巨大的时候可能会采取的方式。</p>
</li>
<li>
<p>如果本地节点上目录/磁盘实际是具有副本/分片机制的分布式存储(比如<code>gluster</code>, <code>ceph</code>等)挂载过来的,这种情况也可以使用<code>local pv</code>。</p>
</li>
</ul>
<p><code>Local volume</code>允许挂载本地的<code>disk</code>,<code>partition</code>,<code>directory</code>到容器内某个挂载点。在<code>Kuberentes 1.11</code>仍然仅支持<code>local pv</code>的<code>static provision</code>,不支持<code>dynamic provision</code>。</p>
<ul>
<li>
<p><code>Kubernetes</code>使用<code>PersistentVolume</code>的<code>.spec.nodeAffinityfield</code>来描述<code>local volume</code>与<code>Node</code>的绑定关系。</p>
</li>
<li>
<p>使用<code>volumeBindingMode: WaitForFirstConsumer</code>的<code>local-storage StorageClass</code>来实现<code>PVC</code>的延迟绑定,使得<code>PV Controller</code>并不会立刻<code>PVC</code>做<code>Bound</code>,而是等待某个需要使用该<code>local pv</code>的<code>Pod</code>完成调度后,才去做<code>Bound</code>。</p>
</li>
</ul>
<p>下面是定义local pv的Sample:</p>
<pre><code class="language-yaml">apiVersion: v1
kind: PersistentVolume
metadata:
name: example-pv
spec:
capacity:
storage: 100Gi
# volumeMode field requires BlockVolume Alpha feature gate to be enabled.
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-storage
local:
path: /mnt/disks/ssd1
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- example-node
</code></pre>
<p>对应的local-storage storageClass定义如下:</p>
<pre><code class="language-yaml">kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
</code></pre>
<h2 id="3使用local-persistent-volume注意事项">3、使用local persistent volume注意事项</h2>
<ul>
<li>
<p>使用<code>local pv</code>时必须定义<code>nodeAffinity</code>,<code>Kubernetes Scheduler</code>需要使用<code>PV</code>的 <code>nodeAffinity</code>描述信息来保证<code>Pod</code>能够调度到有对应<code>local volume</code>的<code>Node</code>上。</p>
</li>
<li>
<p><code>volumeMode</code>可以是<code>FileSystem(Default)和 Block</code>,并且需要<code>enable BlockVolume Alpha feature gate</code>。</p>
</li>
<li>
<p>创建<code>local PV</code>之前,你需要先保证有对应的 <code>storageClass</code>已经创建。并且该<code>storageClass</code>的<code>volumeBindingMode</code>必须是 <code>WaitForFirstConsumer</code>以标识延迟<code>Volume Binding</code>。<code>WaitForFirstConsumer</code>可以保证正常的<code>Pod</code>调度要求(resource requirements, node selectors, Pod affinity, and Pod anti-affinity等),又能保证<code>Pod</code>需要的<code>Local PV 的 nodeAffinity</code>得到满足,实际上,一共有以下两种<code>volumeBindingMode</code>:</p>
</li>
</ul>
<pre><code class="language-yaml">// VolumeBindingImmediate indicates that PersistentVolumeClaims should be
// immediately provisioned and bound.
VolumeBindingImmediate VolumeBindingMode = "Immediate"
// VolumeBindingWaitForFirstConsumer indicates that PersistentVolumeClaims
// should not be provisioned and bound until the first Pod is created that
// references the PeristentVolumeClaim.The volume provisioning and
// binding will occur during Pod scheduing.
VolumeBindingWaitForFirstConsumer VolumeBindingMode = "WaitForFirstConsumer"
</code></pre>
<ul>
<li>节点上<code>local volume</code>的初始化需要我们人为去完成(比如<code>local disk</code>需要<code>pre-partitioned</code>, <code>formatted</code>, <code>and mounted</code>. 共享存储对应的 <code>Directories</code>也需要<code>pre-created</code>),并且人工创建这个<code>local PV</code>,当<code>Pod</code>结束,我们还需要手动的清理<code>local volume</code>,然后手动删除该 <code>local PV</code>对象。因此,<code>persistentVolumeReclaimPolicy</code>只能是 <code>Retain</code>。</li>
</ul>
<h2 id="4local-volume-manager">4、local volume manager</h2>
<p>上面这么多事情需要人为的去做预处理的工作,我们必须要有解决方案帮我们自动完成<code>local volume</code>的 <code>create</code>和<code>cleanup</code>的工作。官方给出了一个简单的 <code>local volume manager</code>,注意它仍然只是一个 <code>static provisioner</code>,目前主要帮我们做两件事:</p>
<ul>
<li>
<p><code>local volume manager</code>监控配置好的 <code>discovery directory</code>的新的挂载点,并为每个挂载点根据对应的<code>storageClassName</code>, <code>path</code>, <code>nodeAffinity</code>,<code>and capacity</code>创建<code>PersistentVolume object</code>。</p>
</li>
<li>
<p>当<code>Pod</code>结束并删除了使用<code>local volume</code>的 <code>PVC</code>,<code>local volume manager</code>将自动清理该 <code>local mount</code>上的所有文件, 然后删除对应的 <code>PersistentVolume object</code>。</p>
</li>
</ul>
<p>因此,除了需要人为的完成<code>local volume</code>的<code>mount </code>操作,<code>local PV</code>的生命周期管理就全部交给<code>local volume manager</code>了。</p>
<h2 id="5总结">5、总结</h2>
<p>本文对<code>hostPath volume</code>不能在生产环境中很好使用的原因进行了阐述,然后对<code>local persistent volume</code>的使用场景、基本的工作机制进行了分析,介绍了使用时的注意事项,最后简单介绍了<code>local volume manager</code>如何帮助<code>administrator</code>进行<code>local persistent volume</code>的生命周期管理的。</p>
<p>转载自:http://dwz.date/c6S9</p><br><br>
来源:https://www.cnblogs.com/ssgeek/p/13690147.html
頁:
[1]