Change:
kind feature What happened: Currently there is no mechanism to report metrics as the flex plugins are not enabled to collect metrics. All flex volumes lack this feature as compared to in-tree/built-in drivers even though it is possible to collect such metrics for most of the plugins. What you expected to happen: Depending on the availability of the metrics from the mounted FS, flex plugins should allow to report metrics for the FS. How to reproduce it (as minimally and precisely as possible): The default behavior that can be proved easily by just running a command similar to the following command on a node that is running a flex volume. This will show that there are no metrics collected for flex volumes. kubectl proxy $curl 127.0.0.1:8001/api/v1/nodes/<IP/proxy/stats/summary Environment**: Kubernetes version (use ): 1.12 Cloud provider or hardware configuration: local x86 OS (e.g. from /etc/os-release): Ubuntu 16.04 Kernel (e.g. ): Linux KubeStorage 4.4.0-130-generic -Ubuntu SMP Thu Jun 14 08:53:28 UTC 2018 x8664 x8664 x86_64 GNU/Linux Install tools: Others: /sig storage
+1 Yes, it will be good, if flex volume can support atleast the default metrics( i.e ), which most of the volume plugins support now. Based upon flex plugin "capabilities" parameters, it can be decided, whether the plugin supports "default metrics" or "nil metrics".

Discussion:
} type DriverCapabilities struct { <del> Attach         bool `json:"attach"` SELinuxRelabel bool `json:"selinuxRelabel"` </del> <ins> Attach          bool `json:"attach"` SELinuxRelabel  bool `json:"selinuxRelabel"` SupportsMetrics bool `json:"supportsMetrics"` </ins> } func defaultCapabilities() *DriverCapabilities { return &DriverCapabilities{ <del> Attach:         true, SELinuxRelabel: true, </del> <ins> Attach:          true, SELinuxRelabel:  true, SupportsMetrics: false, </ins> } }

// the considered volume spec spec     *volume.Spec readOnly bool <del> volume.MetricsNil </del> } var _ volume.Mounter = &flexVolumeMounter{}

return nil, err } <ins> var metricsProvider volume.MetricsProvider if plugin.capabilities.SupportsMetrics { metricsProvider = volume.NewMetricsStatFS(plugin.host.GetPodVolumeDir( pod.UID, utilstrings.EscapeQualifiedNameForDisk(sourceDriver), spec.Name())) } else { metricsProvider = &volume.MetricsNil{} } </ins> return &flexVolumeMounter{ flexVolume: &flexVolume{ driverName:            sourceDriver,

podNamespace:          pod.Namespace, podServiceAccountName: pod.Spec.ServiceAccountName, volName:               spec.Name(), <ins> MetricsProvider:       metricsProvider, </ins> }, runner:   runner, spec:     spec,

// newUnmounterInternal is the internal unmounter routine to clean the volume. func (plugin *flexVolumePlugin) newUnmounterInternal(volName string, podUID types.UID, mounter mount.Interface, runner exec.Interface) (volume.Unmounter, error) { <ins> var metricsProvider volume.MetricsProvider if plugin.capabilities.SupportsMetrics { metricsProvider = volume.NewMetricsStatFS(plugin.host.GetPodVolumeDir( podUID, utilstrings.EscapeQualifiedNameForDisk(plugin.driverName), volName)) } else { metricsProvider = &volume.MetricsNil{} } </ins> return &flexVolumeUnmounter{ flexVolume: &flexVolume{ <del> driverName: plugin.driverName, execPath:   plugin.getExecutable(), mounter:    mounter, plugin:     plugin, podUID:     podUID, volName:    volName, </del> <ins> driverName:      plugin.driverName, execPath:        plugin.getExecutable(), mounter:         mounter, plugin:          plugin, podUID:          podUID, volName:         volName, MetricsProvider: metricsProvider, </ins> }, runner: runner, }, nil

*flexVolume // Runner used to teardown the volume. runner exec.Interface <del> volume.MetricsNil </del> } var _ volume.Unmounter = &flexVolumeUnmounter{}

"k8s.io/apimachinery/pkg/types" "k8s.io/kubernetes/pkg/util/mount" utilstrings "k8s.io/kubernetes/pkg/util/strings" <ins> "k8s.io/kubernetes/pkg/volume" </ins> ) type flexVolume struct {

volName string // the underlying plugin plugin *flexVolumePlugin <ins> // the metric plugin volume.MetricsProvider </ins> } // volume.Volume interface