Kubernetes-StorageClass
<h2 id="1-简介">1. 简介</h2><p>StorageClass 为管理员提供了描述存储 "类" 的方法。</p>
<p>通过StorageClass的定义,管理员可以将存储资源定义为某种类别(Class),正如存储设备对于自身的配置描述(Profile),例如 "快速存储" "慢速存储" "有数据冗余" "无数据冗余"等。用户根据StorageClass的描述就能够直观得知各种存储资源的特性,就可以根据应用对存储资源的需求去申请存储资源了。</p>
<p><strong>StorageClass作为对存储资源的抽象定义,对用户设置的PVC申请屏蔽后端的细节,一方面减轻用户对于存储资源细节的关注,另一方面也减轻了管理员手工管理PV的工作,由系统自动完成PV的创建和绑定,实现了动态的资源供应。</strong></p>
<p>每个 StorageClass 都包含 <code>provisioner</code>、<code>parameters</code> 和 <code>reclaimPolicy</code> 字段, 这些字段会在 StorageClass 需要动态分配 PersistentVolume 时会使用到。</p>
<p>StorageClass 对象的命名很重要,用户使用这个命名来请求生成一个特定的类。 当创建 StorageClass 对象时,管理员设置 StorageClass 对象的命名和其他参数,一旦创建了对象就不能再对其更新。</p>
<h2 id="2-创建provisioner">2. 创建Provisioner</h2>
<p>如果需要使用StorageClass,我们就需要安装对应的自动配置程序,比如我们这里后端采用的是nfs,那么我们就需要使用到一个nfs-client的自动配置程序,我们也叫它Provisioner,这个程序使用我们已经配置好的nfs服务器,来自动创建持久卷,也就是自动帮我们创建PV。</p>
<p>这里也可以直接参考nfs-client的官方文档</p>
<p>https://github.com/kubernetes-incubator/external-storage/tree/master/nfs-client/deploy</p>
<blockquote>
<p>自动创建的PV以<code>{namespace}-${pvcname}-${pvname}</code>进行命名到服务器上</p>
</blockquote>
<blockquote>
<p>如果开启了<code>archiveOnDelete</code>功能,则当pv被回收后会以<code>archieved-${namespace}-${pvcname}-${pvname}</code>格式存在服务器上</p>
</blockquote>
<h3 id="21-创建deployment">2.1 创建deployment</h3>
<pre><code class="language-yaml">apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-client-provisioner
labels:
app: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: nfs-client-provisioner
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccountName: nfs-client-provisioner
containers:
- name: nfs-client-provisioner
image: quay.io/external_storage/nfs-client-provisioner:latest
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: fuseim.pri/ifs
- name: NFS_SERVER
# nfs server 地址
value: 192.168.0.201
- name: NFS_PATH
# nfs 挂载点
value: /nfs/data
volumes:
- name: nfs-client-root
nfs:
# nfs server 地址
server: 192.168.0.201
# nfs 挂载点
path: /nfs/data
</code></pre>
<h3 id="22-rbac">2.2 rbac</h3>
<p>接下来我们还需要创建一个serveraccount,用于将nfs-client-provisioner中的ServiceAccount绑定到一个nfs-client-provisioner-runner的ClusterRole。而该ClusterRole声明了一些权限,其中就包括了对persistentvolumes的增删改查,所以我们就可以利用ServiceAccount来自动创建PV</p>
<pre><code class="language-yaml">apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nfs-client-provisioner-runner
rules:
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: run-nfs-client-provisioner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
roleRef:
kind: ClusterRole
name: nfs-client-provisioner-runner
apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
rules:
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
roleRef:
kind: Role
name: leader-locking-nfs-client-provisioner
apiGroup: rbac.authorization.k8s.io
</code></pre>
<h3 id="23-storage-class">2.3 storage-class</h3>
<blockquote>
<p>provisioner值可以自定义但需要和deployment的 template.spec.containers.envPROVISIONER_NAME 保持一致</p>
</blockquote>
<blockquote>
<p>这里我们声明了一个名为managed-nfs-storage的Storageclass对象</p>
</blockquote>
<pre><code class="language-yaml">apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
annotations:
# 设置为default StorageClass,如果创建pvc时不指定StorageClass,则会使用当前的StorageClass
storageclass.kubernetes.io/is-default-class: "true"
name: managed-nfs-storage
provisioner: fuseim.pri/ifs # or choose another name, must match deployment's env PROVISIONER_NAME'
parameters:
# 删除PVC时不会保留数据
archiveOnDelete: "false"
# 回收策略:删除
reclaimPolicy: Delete
#允许pvc创建后扩容
allowVolumeExpansion: true
</code></pre>
<h4 id="回收策略">回收策略</h4>
<p>由 StorageClass 动态创建的 PersistentVolume 会在类的 <code>reclaimPolicy</code> 字段中指定回收策略,可以是 <code>Delete</code> 或者 <code>Retain</code>。如果 StorageClass 对象被创建时没有指定 <code>reclaimPolicy</code>,它将默认为 <code>Delete</code>。</p>
<p>通过 StorageClass 手动创建并管理的 PersistentVolume 会使用它们被创建时指定的回收政策。</p>
<h4 id="卷绑定模式">卷绑定模式</h4>
<p><code>volumeBindingMode</code> 字段控制了<code>卷绑定和动态制备</code> 应该发生在什么时候。</p>
<p>默认情况下,<code>Immediate</code> 模式表示一旦创建了 PersistentVolumeClaim 也就完成了卷绑定和动态制备。 对于由于拓扑限制而非集群所有节点可达的存储后端,PersistentVolume 会在不知道 Pod 调度要求的情况下绑定或者制备。</p>
<p>集群管理员可以通过指定 <code>WaitForFirstConsumer</code> 模式来解决此问题。 该模式将延迟 PersistentVolume 的绑定和制备,直到使用该 PersistentVolumeClaim 的 Pod 被创建。 PersistentVolume 会根据 Pod 调度约束指定的拓扑来选择或制备。这些包括但不限于 <code>资源需求</code>、 <code>节点筛选器</code>、 <code>pod 亲和性和互斥性</code>、 以及<code>污点和容忍度</code>。</p>
<p><strong>说明:</strong></p>
<p>如果选择使用 <code>WaitForFirstConsumer</code>,请不要在 Pod 规约中使用 <code>nodeName</code> 来指定节点亲和性。 如果在这种情况下使用 <code>nodeName</code>,Pod 将会绕过调度程序,PVC 将停留在 <code>pending</code> 状态。</p>
<p>相反,在这种情况下,可以使用节点选择器作为主机名,如下所示</p>
<pre><code class="language-yaml">apiVersion: v1
kind: Pod
metadata:
name: task-pv-pod
spec:
nodeSelector:
kubernetes.io/hostname: kube-01
volumes:
- name: task-pv-storage
persistentVolumeClaim:
claimName: task-pv-claim
containers:
- name: task-pv-container
image: nginx
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: task-pv-storage
</code></pre>
<h3 id="24-创建资源">2.4 创建资源</h3>
<p>创建信息如下</p>
<p><img src="https://img2022.cnblogs.com/blog/1759273/202201/1759273-20220119233020941-596433326.png" alt="" loading="lazy"></p>
<p>资源信息如下</p>
<p><img src="https://img2022.cnblogs.com/blog/1759273/202201/1759273-20220119233039168-206207496.png" alt="" loading="lazy"></p>
<h2 id="3-验证动态创建pv">3. 验证动态创建pv</h2>
<p>首先创建个pvc,看下是否会动态的创建pv</p>
<pre><code class="language-yaml">kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: test-claim
annotations:
#storageclass 名称
volume.beta.kubernetes.io/storage-class: "managed-nfs-storage"
spec:
#访问模式
accessModes:
- ReadWriteMany
resources:
requests:
#请求数据大小
storage: 1024Mi
</code></pre>
<p><img src="https://img2022.cnblogs.com/blog/1759273/202201/1759273-20220119233104867-847178148.png" alt="" loading="lazy"></p>
<p>从图中可以看出,我们不需要的手动创建pv,只需要创建一个pvc,storageclass会自动将pv给创建并且关联,就很nice</p>
<p><strong>使用pvc</strong></p>
<p>我们这里创建一个deployment,使用下刚创建的pvc: <code>test-claim</code></p>
<pre><code class="language-yaml">apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-pv-demo
name: nginx-pv-demo
spec:
replicas: 2
selector:
matchLabels:
app: nginx-pv-demo
template:
metadata:
labels:
app: nginx-pv-demo
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: nginx
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
volumes:
- name: html
persistentVolumeClaim:
claimName: test-claim
</code></pre>
<p>测试演示步骤如下:</p>
<p><img src="https://img2022.cnblogs.com/blog/1759273/202201/1759273-20220119233121899-1856818171.png" alt="" loading="lazy"></p><br><br>
来源:https://www.cnblogs.com/ludangxin/p/15824672.html
頁:
[1]