kubernetesサードパーティストレージの追加(一)


kubernetesは1.7に発展した後、プラットフォームに向かって開発されました.前の議論の点はkubernetesがmetricsを単独で出て、kubernetesの監視基準になったことです.これは後でゆっくり話して、まずこの孵化を保存するプロジェクトを見てみましょう.github.com/kubernetes-incubator/external-storageサードパーティストレージドッキング.前回紹介したcustom-metrics-apiserverプロジェクトと同じように孵化したプロジェクトで、まず彼がどのように働いているかを見てみましょう.コアはlib/controller/controller.go
// pvc listwatch
controller.claimSource = &cache.ListWatch{
        ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
            return client.Core().PersistentVolumeClaims(v1.NamespaceAll).List(options)
        },
        WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
            return client.Core().PersistentVolumeClaims(v1.NamespaceAll).Watch(options)
        },
    }
    controller.claims, controller.claimController = cache.NewInformer(
        controller.claimSource,
        &v1.PersistentVolumeClaim{},
        controller.resyncPeriod,
        cache.ResourceEventHandlerFuncs{
            AddFunc:    controller.addClaim,
            UpdateFunc: controller.updateClaim,
            DeleteFunc: nil,
        },
    )
// pv listwatch
    controller.volumeSource = &cache.ListWatch{
        ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
            return client.Core().PersistentVolumes().List(options)
        },
        WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
            return client.Core().PersistentVolumes().Watch(options)
        },
    }
    controller.volumes, controller.volumeController = cache.NewInformer(
        controller.volumeSource,
        &v1.PersistentVolume{},
        controller.resyncPeriod,
        cache.ResourceEventHandlerFuncs{
            AddFunc:    nil,
            UpdateFunc: controller.updateVolume,
            DeleteFunc: nil,
        },
    )
// storageclass listwatch
controller.classSource = &cache.ListWatch{
            ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
                return client.StorageV1().StorageClasses().List(options)
            },
            WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
                return client.StorageV1().StorageClasses().Watch(options)
            },
        }
        controller.classReflector = cache.NewReflector(
            controller.classSource,
            &storage.StorageClass{},
            controller.classes,
            controller.resyncPeriod,
        )

上の起動サービスは主にwatch k 8 sがストレージ管理する様々なイベントであり、pvc、pv、storageclassのイベントの傍受である限りである.
まずpvcが作成されたらどうするか見てみましょう
func (ctrl *ProvisionController) addClaim(obj interface{}) {
    claim, ok := obj.(*v1.PersistentVolumeClaim)
    if !ok {
        glog.Errorf("Expected PersistentVolumeClaim but addClaim received %+v", obj)
        return
    }

    if ctrl.shouldProvision(claim) {
        ctrl.leaderElectorsMutex.Lock()
        le, ok := ctrl.leaderElectors[claim.UID]
        ctrl.leaderElectorsMutex.Unlock()
        if ok && le.IsLeader() {
            opName := fmt.Sprintf("provision-%s[%s]", claimToClaimKey(claim), string(claim.UID))
            ctrl.scheduleOperation(opName, func() error {
                err := ctrl.provisionClaimOperation(claim)
                ctrl.updateProvisionStats(claim, err)
                return err
            })
        } else {
            opName := fmt.Sprintf("lock-provision-%s[%s]", claimToClaimKey(claim), string(claim.UID))
            ctrl.scheduleOperation(opName, func() error {
                ctrl.lockProvisionClaimOperation(claim)
                return nil
            })
        }
    }
}

主を選ぶ方法についてはここでスキップして、主にどのように実行するかを見てみましょう.
err := ctrl.provisionClaimOperation(claim)
ctrl.updateProvisionStats(claim, err)

まずprovisionClaimOperationという方法を見て、この方法は比較的に長くて、核心を選んで紹介します
 pv pvc+pvc uid 
pvName := ctrl.getProvisionedVolumeNameForClaim(claim)
 pv , 
volume, err := ctrl.client.Core().PersistentVolumes().Get(pvName, metav1.GetOptions{})
 Provision, pv 
volume, err = ctrl.provisioner.Provision(options)
 k8s pv
ctrl.client.Core().PersistentVolumes().Create(volume)

コアは上のProvisionで、pvcを介してpvを作成するエントリです.インタフェースです
type Provisioner interface {
    // pv 
    Provision(VolumeOptions) (*v1.PersistentVolume, error)
    //  pv
    Delete(*v1.PersistentVolume) error
}

これがサードパーティに実現させるインタフェースであり,自分のpvオブジェクトを作成する.これでストレージが作成されます.pvが削除されたら?もちろん最初はlistwatch方式でもこのメッセージを傍受し、実行します.
func (ctrl *ProvisionController) updateVolume(oldObj, newObj interface{}) {
    volume, ok := newObj.(*v1.PersistentVolume)
    if !ok {
        glog.Errorf("Expected PersistentVolume but handler received %#v", newObj)
        return
    }

    if ctrl.shouldDelete(volume) {
        opName := fmt.Sprintf("delete-%s[%s]", volume.Name, string(volume.UID))
        ctrl.scheduleOperation(opName, func() error {
            err := ctrl.deleteVolumeOperation(volume)
            ctrl.updateDeleteStats(volume, err)
            return err
        })
    }
}

deleteVolumeOperationこのメソッドの原理は、以前と同様に削除インタフェースを呼び出す
err = ctrl.provisioner.Delete(volume)

ストレージを解放します.