mirror of https://github.com/k3s-io/k3s
Merge pull request #64386 from andyzhangx/azuredisk-sizegrow
Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Add azuredisk PV size grow feature **What this PR does / why we need it**: According to kubernetes/features#284, add size grow feature for azure disk **Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*: Fixes #56463 **Special notes for your reviewer**: - This feature is ony for azure managed disk, and if that disk is already attached to a running VM, disk resize will fail as following: ``` $ kubectl describe pvc pvc-azuredisk Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning VolumeResizeFailed 51s (x3 over 3m) volume_expand Error expanding volume "default/pvc-azuredisk" of plugin kubernetes.io/azure-disk : disk.DisksClient#CreateOrUpdate: Failure responding to request: StatusCode=409 -- Original Error: autorest/azure: Service returned an error. Status=409 Code="OperationNotAllowed" Message="Cannot resize disk andy-mg1102-dynamic-pvc-d2d00dd9-6185-11e8-a6c3-000d3a0643a8 while it is attached to running VM /subscriptions/.../resourceGroups/.../providers/Microsoft.Compute/virtualMachines/k8s-agentpool-17607330-0." ``` **How to use this feature** - `kubectl edit pvc pvc-azuredisk` to change azuredisk PVC size from 6GB to 10GB ``` # Please edit the object below. Lines beginning with a '#' will be ignored, # and an empty file will abort the edit. If an error occurs while saving this file will be # reopened with the relevant failures. # apiVersion: v1 kind: PersistentVolumeClaim metadata: annotations: ... volume.beta.kubernetes.io/storage-provisioner: kubernetes.io/azure-disk creationTimestamp: 2018-05-27T08:13:23Z finalizers: - kubernetes.io/pvc-protection name: pvc-azuredisk ... spec: accessModes: - ReadWriteOnce resources: requests: storage: 6Gi storageClassName: hdd volumeMode: Filesystem volumeName: pvc-d2d00dd9-6185-11e8-a6c3-000d3a0643a8 status: accessModes: - ReadWriteOnce capacity: storage: 6Gi conditions: - lastProbeTime: null lastTransitionTime: 2018-05-27T08:14:34Z message: Waiting for user to (re-)start a pod to finish file system resize of volume on node. status: "True" type: FileSystemResizePending phase: Bound ``` - After resized, `/mnt/disk` is still 6GB ``` $ kubectl exec -it nginx-azuredisk -- bash # df -h Filesystem Size Used Avail Use% Mounted on ... /dev/sdf 5.8G 15M 5.5G 1% /mnt/disk ... ``` - After user run `sudo resize2fs /dev/sdf` in agent node, `/mnt/disk` becomes 10GB now: ``` $ kubectl exec -it nginx-azuredisk -- bash # df -h Filesystem Size Used Avail Use% Mounted on ... /dev/sdf 9.8G 16M 9.3G 1% /mnt/disk ... ``` **Release note**: ``` Add azuredisk size grow feature ``` /sig azure /assign @feiskyer @karataliu @gnufied cc @khenidakpull/8/head
commit
0647cff9ff
|
@ -42,6 +42,7 @@ go_library(
|
|||
"//pkg/controller:go_default_library",
|
||||
"//pkg/version:go_default_library",
|
||||
"//pkg/volume:go_default_library",
|
||||
"//pkg/volume/util:go_default_library",
|
||||
"//vendor/github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2017-12-01/compute:go_default_library",
|
||||
"//vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network:go_default_library",
|
||||
"//vendor/github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2017-10-01/storage:go_default_library",
|
||||
|
@ -55,6 +56,7 @@ go_library(
|
|||
"//vendor/github.com/prometheus/client_golang/prometheus:go_default_library",
|
||||
"//vendor/github.com/rubiojr/go-vhd/vhd:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
|
|
|
@ -17,13 +17,17 @@ limitations under the License.
|
|||
package azure
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2017-12-01/compute"
|
||||
"github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2017-10-01/storage"
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
kwait "k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/kubernetes/pkg/volume/util"
|
||||
)
|
||||
|
||||
//ManagedDiskController : managed disk controller struct
|
||||
|
@ -131,3 +135,41 @@ func (c *ManagedDiskController) getDisk(diskName string) (string, string, error)
|
|||
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
// ResizeDisk Expand the disk to new size
|
||||
func (c *ManagedDiskController) ResizeDisk(diskName string, oldSize resource.Quantity, newSize resource.Quantity) (resource.Quantity, error) {
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
|
||||
result, err := c.common.cloud.DisksClient.Get(ctx, c.common.resourceGroup, diskName)
|
||||
if err != nil {
|
||||
return oldSize, err
|
||||
}
|
||||
|
||||
if result.DiskProperties == nil || result.DiskProperties.DiskSizeGB == nil {
|
||||
return oldSize, fmt.Errorf("DiskProperties of disk(%s) is nil", diskName)
|
||||
}
|
||||
|
||||
requestBytes := newSize.Value()
|
||||
// Azure resizes in chunks of GiB (not GB)
|
||||
requestGiB := int32(util.RoundUpSize(requestBytes, 1024*1024*1024))
|
||||
newSizeQuant := resource.MustParse(fmt.Sprintf("%dGi", requestGiB))
|
||||
|
||||
glog.V(2).Infof("azureDisk - begin to resize disk(%s) with new size(%d), old size(%v)", diskName, requestGiB, oldSize)
|
||||
// If disk already of greater or equal size than requested we return
|
||||
if *result.DiskProperties.DiskSizeGB >= requestGiB {
|
||||
return newSizeQuant, nil
|
||||
}
|
||||
|
||||
result.DiskProperties.DiskSizeGB = &requestGiB
|
||||
|
||||
ctx, cancel = getContextWithCancel()
|
||||
defer cancel()
|
||||
if _, err := c.common.cloud.DisksClient.CreateOrUpdate(ctx, c.common.resourceGroup, diskName, result); err != nil {
|
||||
return oldSize, err
|
||||
}
|
||||
|
||||
glog.V(2).Infof("azureDisk - resize disk(%s) with new size(%d) completed", diskName, requestGiB)
|
||||
|
||||
return newSizeQuant, nil
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
"github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2017-10-01/storage"
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/kubernetes/pkg/cloudprovider/providers/azure"
|
||||
"k8s.io/kubernetes/pkg/util/mount"
|
||||
|
@ -55,6 +56,9 @@ type DiskController interface {
|
|||
CreateVolume(name, storageAccount, storageAccountType, location string, requestGB int) (string, string, int, error)
|
||||
// Delete a VHD blob
|
||||
DeleteVolume(diskURI string) error
|
||||
|
||||
// Expand the disk to new size
|
||||
ResizeDisk(diskName string, oldSize resource.Quantity, newSize resource.Quantity) (resource.Quantity, error)
|
||||
}
|
||||
|
||||
type azureDataDiskPlugin struct {
|
||||
|
@ -67,6 +71,7 @@ var _ volume.DeletableVolumePlugin = &azureDataDiskPlugin{}
|
|||
var _ volume.ProvisionableVolumePlugin = &azureDataDiskPlugin{}
|
||||
var _ volume.AttachableVolumePlugin = &azureDataDiskPlugin{}
|
||||
var _ volume.VolumePluginWithAttachLimits = &azureDataDiskPlugin{}
|
||||
var _ volume.ExpandableVolumePlugin = &azureDataDiskPlugin{}
|
||||
|
||||
const (
|
||||
azureDataDiskPluginName = "kubernetes.io/azure-disk"
|
||||
|
@ -210,6 +215,26 @@ func (plugin *azureDataDiskPlugin) NewUnmounter(volName string, podUID types.UID
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (plugin *azureDataDiskPlugin) RequiresFSResize() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (plugin *azureDataDiskPlugin) ExpandVolumeDevice(
|
||||
spec *volume.Spec,
|
||||
newSize resource.Quantity,
|
||||
oldSize resource.Quantity) (resource.Quantity, error) {
|
||||
if spec.PersistentVolume == nil || spec.PersistentVolume.Spec.AzureDisk == nil {
|
||||
return oldSize, fmt.Errorf("invalid PV spec")
|
||||
}
|
||||
|
||||
diskController, err := getDiskController(plugin.host)
|
||||
if err != nil {
|
||||
return oldSize, err
|
||||
}
|
||||
|
||||
return diskController.ResizeDisk(spec.PersistentVolume.Spec.AzureDisk.DiskName, oldSize, newSize)
|
||||
}
|
||||
|
||||
func (plugin *azureDataDiskPlugin) ConstructVolumeSpec(volumeName, mountPath string) (*volume.Spec, error) {
|
||||
mounter := plugin.host.GetMounter(plugin.GetPluginName())
|
||||
pluginDir := plugin.host.GetPluginDir(plugin.GetPluginName())
|
||||
|
|
|
@ -164,5 +164,9 @@ func (pvcr *persistentVolumeClaimResize) checkVolumePlugin(pv *api.PersistentVol
|
|||
if pv.Spec.AzureFile != nil {
|
||||
return true
|
||||
}
|
||||
|
||||
if pv.Spec.AzureDisk != nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue