Change:
Is this a BUG REPORT or FEATURE REQUEST? (choose one): BUG REPORT Kubernetes version (use ): Client Version: version.Info{Major:"1", Minor:"4+", GitVersion:"v1.4.0-alpha.3.317+", GitCommit:"", GitTreeState:"clean", BuildDate:"2016-09-01T05:48:36Z", GoVersion:"go1.7", Compiler:"gc", Platform:"linux/amd64"} Server Version: version.Info{Major:"1", Minor:"4+", GitVersion:"v1.4.0-alpha.3.317+", GitCommit:"", GitTreeState:"clean", BuildDate:"2016-09-01T05:48:36Z", GoVersion:"go1.7", Compiler:"gc", Platform:"linux/amd64"} What happened: Dynamic provisioned volumes in different zones with master failed to deleted What you expected to happen: Since the volume can be dynamic provisioned when the zones differs from master, then it should be deleted after delete the PVC which created them. How to reproduce it (as minimally and precisely as possible): up an all-in-one cluster. The instance is created in zone us-central1-a. several storageClass. One in zone us-central1-a. Another in zone us-central1-b. several PVC. pvc1 using storageClass1(zone us-central1-a), pvc2 using storageClass2(zone us-central1-b). PV/volume were provisioned in proper size/mode/zone. PVCs. with volume in zone us-central1-b failed with error can not find the volume. Anything else do we need to know: Name: pvc--70d1-11e6-b17e- Labels: failure- failure- Status: Failed Claim: default/pvc5 Reclaim Policy: Delete Access Modes: RWO Capacity: 4Gi Message: Delete of volume "pvc--70d1-11e6-b17e-" failed: GCE persistent disk not found: "kubernetes-dynamic-pvc--70d1-11e6-b17e-" Source: Type: GCEPersistentDisk (a Persistent Disk resource in Google Compute Engine) PDName: kubernetes-dynamic-pvc--70d1-11e6-b17e- FSType: Partition: 0 ReadOnly: false Events: FirstSeen LastSeen Count From SubobjectPath Type Reason Message 11m 11m 1 {persistentvolume-controller } Warning VolumeFailedDelete Delete of volume "pvc--70d1-11e6-b17e-" failed: GCE persistent disk not found: "kubernetes-dynamic-pvc--70d1-11e6-b17e-" creationTimestamp: '2016-09-01T22:49:26.439-07:00' description: '{"":"pvc--70d1-11e6-b17e-","":"pvc5","":"default"}' id: '' kind: compute#disk name: kubernetes-dynamic-pvc--70d1-11e6-b17e- selfLink: sizeGb: '4' status: READY type: zone:
Kubernetes can delete GCE PDs only in zones it manages. I.e. either in the same zone as the master or, when multizone is enabled in GCE config, in all zones in the same region. This should not be allowed in the first place. Kubernetes should not create disks outside zones it manages and report an error instead. So... please use following , it will be allow creation/deletion of disks in all zones in us-central1 region: And I'll fix Kubernetes to report an error when creating a disk in all other zones.

Discussion:
"k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" <ins> "k8s.io/apimachinery/pkg/util/sets" </ins> "k8s.io/apiserver/pkg/authentication/serviceaccount" "k8s.io/kubernetes/pkg/api/v1" rbacv1beta1 "k8s.io/kubernetes/pkg/apis/rbac/v1beta1"

testDynamicProvisioning(c, claim, "2Gi") } }) <ins> // NOTE: Slow!  The test will wait up to 5 minutes (framework.ClaimProvisionTimeout) when there is // no regression. It("should not provision a volume in an unmanaged GCE zone. [Slow]", func() { framework.SkipUnlessProviderIs("gce", "gke") var suffix string = "unmananged" By("Discovering an unmanaged zone") allZones := sets.NewString()     // all zones in the project managedZones := sets.NewString() // subset of allZones gceCloud, err := getGCECloud() Expect(err).NotTo(HaveOccurred()) // Get all k8s managed zones managedZones, err = gceCloud.GetAllZones() Expect(err).NotTo(HaveOccurred()) // Get a list of all zones in the project zones, err := gceCloud.GetComputeService().Zones.List(framework.TestContext.CloudConfig.ProjectID).Do() for _, z := range zones.Items { allZones.Insert(z.Name) } // Get the subset of zones not managed by k8s var unmanagedZone string var popped bool unmanagedZones := allZones.Difference(managedZones) // And select one of them at random. if unmanagedZone, popped = unmanagedZones.PopAny(); !popped { framework.Skipf("No unmanaged zones found.") } By("Creating a StorageClass for the unmanaged zone") sc := newStorageClass("kubernetes.io/gce-pd", suffix) // Set an unmanaged zone. sc.Parameters = map[string]string{"zone": unmanagedZone} sc, err = c.Storage().StorageClasses().Create(sc) defer Expect(c.Storage().StorageClasses().Delete(sc.Name, nil)).To(Succeed()) Expect(err).NotTo(HaveOccurred()) By("Creating a claim and expecting it to timeout") pvc := newClaim(ns, suffix, false) pvc, err = c.Core().PersistentVolumeClaims(ns).Create(pvc) defer Expect(c.Core().PersistentVolumeClaims(ns).Delete(pvc.Name, nil)).To(Succeed()) Expect(err).NotTo(HaveOccurred()) // The claim should timeout phase:Pending err = framework.WaitForPersistentVolumeClaimPhase(v1.ClaimBound, c, ns, pvc.Name, 2*time.Second, framework.ClaimProvisionTimeout) Expect(err).To(HaveOccurred()) framework.Logf(err.Error()) }) </ins> }) framework.KubeDescribe("DynamicProvisioner Alpha", func() {