@@ -47,7 +47,7 @@ import (
47
47
"github.com/aws/aws-sdk-go/service/kms"
48
48
"github.com/aws/aws-sdk-go/service/sts"
49
49
"gopkg.in/gcfg.v1"
50
- "k8s.io/api/core/v1"
50
+ v1 "k8s.io/api/core/v1"
51
51
"k8s.io/klog"
52
52
53
53
"k8s.io/apimachinery/pkg/api/resource"
@@ -63,7 +63,7 @@ import (
63
63
"k8s.io/client-go/pkg/version"
64
64
"k8s.io/client-go/tools/cache"
65
65
"k8s.io/client-go/tools/record"
66
- "k8s.io/cloud-provider"
66
+ cloudprovider "k8s.io/cloud-provider"
67
67
nodehelpers "k8s.io/cloud-provider/node/helpers"
68
68
servicehelpers "k8s.io/cloud-provider/service/helpers"
69
69
cloudvolume "k8s.io/cloud-provider/volume"
@@ -1861,6 +1861,7 @@ func (c *Cloud) getMountDevice(
1861
1861
assign bool ) (assigned mountDevice , alreadyAttached bool , err error ) {
1862
1862
1863
1863
deviceMappings := map [mountDevice ]EBSVolumeID {}
1864
+ volumeStatus := map [EBSVolumeID ]string {} // for better logging of volume status
1864
1865
for _ , blockDevice := range info .BlockDeviceMappings {
1865
1866
name := aws .StringValue (blockDevice .DeviceName )
1866
1867
if strings .HasPrefix (name , "/dev/sd" ) {
@@ -1872,6 +1873,10 @@ func (c *Cloud) getMountDevice(
1872
1873
if len (name ) < 1 || len (name ) > 2 {
1873
1874
klog .Warningf ("Unexpected EBS DeviceName: %q" , aws .StringValue (blockDevice .DeviceName ))
1874
1875
}
1876
+ if blockDevice .Ebs != nil && blockDevice .Ebs .VolumeId != nil {
1877
+ volumeStatus [EBSVolumeID (* blockDevice .Ebs .VolumeId )] = aws .StringValue (blockDevice .Ebs .Status )
1878
+ }
1879
+
1875
1880
deviceMappings [mountDevice (name )] = EBSVolumeID (aws .StringValue (blockDevice .Ebs .VolumeId ))
1876
1881
}
1877
1882
@@ -1889,7 +1894,15 @@ func (c *Cloud) getMountDevice(
1889
1894
for mountDevice , mappingVolumeID := range deviceMappings {
1890
1895
if volumeID == mappingVolumeID {
1891
1896
if assign {
1892
- klog .Warningf ("Got assignment call for already-assigned volume: %s@%s" , mountDevice , mappingVolumeID )
1897
+ // DescribeInstances shows the volume as attached / detaching, while Kubernetes
1898
+ // cloud provider thinks it's detached.
1899
+ // This can happened when the volume has just been detached from the same node
1900
+ // and AWS API returns stale data in this DescribeInstances ("eventual consistency").
1901
+ // Fail the attachment and let A/D controller retry in a while, hoping that
1902
+ // AWS API returns consistent result next time (i.e. the volume is detached).
1903
+ status := volumeStatus [mappingVolumeID ]
1904
+ klog .Warningf ("Got assignment call for already-assigned volume: %s@%s, volume status: %s" , mountDevice , mappingVolumeID , status )
1905
+ return mountDevice , false , fmt .Errorf ("volume is still being detached from the node" )
1893
1906
}
1894
1907
return mountDevice , true , nil
1895
1908
}
0 commit comments