<blockquote>
<p> PersistentVolumeClaim(PVC)是用户存储的请求。 它类似于pod。Pod消耗节点资源,PVC消耗存储资源</p>
<p> StorageClass 提供了一种描述他们提供的存储的“类”的方法。 不同的类可能映射到服务质量级别,或备份策略,或者由群集管理员确定的任意策略。 </p>
</blockquote>
<h2> </h2>
<p>pv.kubernetes.io/bind-completed::yes 已经完成了 pvc 绑定</p>
<p>pv.kubernetes.io/bound-by-controller:</p>
<p> </p>
<h1 id="lifecycle-of-a-volume-and-claim">Lifecycle of a volume and claim</h1>
<p> PV是源,PVC是对这些资源的请求,生命周期:</p>
<p> Provisioning ——-> Binding ——–>Using——>Releasing——>Recycling</p>
<p> </p>
<p><strong>Provisioning:静态或者动态</strong></p>
<ul><li> <p>Static: 创建多个PV</p> </li><li> <p>Dynamic:当创建的静态PV都不匹配用户的PersistentVolumeClaim时,集群可能会尝试为PVC动态配置卷。 StorageClasses:PVC必须请求一个类</p> </li></ul>
<p> </p>
<p><strong>B</strong>inding 需要两个步骤</p>
<ul><li>首先修改 PV.Spec.ClaimRef</li><li>其次修改 PVC.Spec.VolumeName</li></ul>
<p> pv<em>c controller watch pvc资源,进行更新操作,本文章将分析这块内容</em></p>
<p> </p>
<p><em><strong> 定义 nfs-pv.yaml</strong></em></p>
<blockquote>
<p>apiVersion: v1<br> kind: PersistentVolume<br> metadata:<br> name: nfs-pv<br> namespace: default<br> spec:<br> capacity:<br> storage: 500Mi<br> accessModes:<br> - ReadWriteMany<br> nfs:<br> server: 192.168.73.184<br> path: /nfs/data</p>
</blockquote>
<p> </p>
<p><strong><em> 定义pvc.yaml</em></strong></p>
<blockquote>
<p>apiVersion: v1<br> kind: PersistentVolumeClaim<br> metadata:<br> name: mysql-pv-claim<br> labels:<br> app: wordpress<br> spec:<br> storageClassName: rook-ceph-block<br> accessModes:<br> - ReadWriteOnce<br> resources:<br> requests:<br> storage: 20Gi</p>
</blockquote>
<p> </p>
<h1><strong>0. 入口NewControllerInitializers函数</strong></h1>
<p> 注册persistentvolume-binder,controllers["persistentvolume-binder"] = startPersistentVolumeBinderController</p>
<pre class="blockcode"><code>// NewControllerInitializers is a public map of named controller groups (you can start more than one in an init func)
// paired to their InitFunc. This allows for structured downstream composition and subdivision.
func NewControllerInitializers(loopMode ControllerLoopMode) map[string]InitFunc {
controllers["persistentvolume-binder"] = startPersistentVolumeBinderController
controllers["attachdetach"] = startAttachDetachController
controllers["persistentvolume-expander"] = startVolumeExpandController
controllers["clusterrole-aggregation"] = startClusterRoleAggregrationController
controllers["pvc-protection"] = startPVCProtectionController
controllers["pv-protection"] = startPVProtectionController
controllers["ttl-after-finished"] = startTTLAfterFinishedController
controllers["root-ca-cert-publisher"] = startRootCACertPublisher
return controllers
}</code></pre>
<p> </p>
<h1>1. NewController函数</h1>
<p> 创建 pv controller,关注的资源包括 volume pvc pod node storageclass等</p>
<h3> 1.1 实例化PersistentVolumeController</h3>
<p> 包括cache,pvc volume队列等。其他忽略</p>
<pre class="blockcode"><code class="language-Go">controller := &PersistentVolumeController{
volumes: newPersistentVolumeOrderedIndex(),
claims: cache.NewStore(cache.DeletionHandlingMetaNamespaceKeyFunc),
kubeClient: p.KubeClient,
eventRecorder: eventRecorder,
runningOperations: goroutinemap.NewGoRoutineMap(true /* exponentialBackOffOnError */),
cloud: p.Cloud,
enableDynamicProvisioning: p.EnableDynamicProvisioning,
clusterName: p.ClusterName,
createProvisionedPVRetryCount: createProvisionedPVRetryCount,
createProvisionedPVInterval: createProvisionedPVInterval,
claimQueue: workqueue.NewNamed("claims"),
volumeQueue: workqueue.NewNamed("volumes"),
resyncPeriod: p.SyncPeriod,
}</code></pre>
<h3> 1.2 初始化一大堆volume 插件,包括hostpath nfs csi等等</h3>
<pre class="blockcode"><code class="language-Go">// Prober is nil because PV is not aware of Flexvolume.
if err := controller.volumePluginMgr.InitPlugins(p.VolumePlugins, nil /* prober */, controller); err != nil {
return nil, fmt.Errorf("Could not initialize volume plugins for PersistentVolume Controller: %v", err)
}</code></pre>
<h3> 1.3 添加volume informer机制</h3>
<pre class="blockcode"><code class="language-Go">p.VolumeInformer.Informer().AddEventHandler(
cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) { controller.enqueueWork(controller.volumeQueue, obj) },
UpdateFunc: func(oldObj, newObj interface{}) { controller.enqueueWork(controller.volumeQueue, newObj) },
DeleteFunc: func(obj interface{}) { controller.enqueueWork(controlle |
|