@@ -31,6 +31,8 @@ import (
31
31
32
32
csi "github.com/container-storage-interface/spec/lib/go/csi"
33
33
34
+ "k8s.io/client-go/kubernetes"
35
+ "k8s.io/client-go/rest"
34
36
"k8s.io/klog/v2"
35
37
"k8s.io/mount-utils"
36
38
@@ -101,7 +103,12 @@ const (
101
103
// doc https://cloud.google.com/compute/docs/memory-optimized-machines#x4_disks
102
104
x4HyperdiskLimit int64 = 39
103
105
// doc https://cloud.google.com/compute/docs/accelerator-optimized-machines#a4-disks
104
- a4HyperdiskLimit int64 = 127
106
+ a4HyperdiskLimit int64 = 127
107
+ // doc https://cloud.google.com/compute/docs/storage-optimized-machines#z3_disks
108
+ // doc https://cloud.google.com/compute/docs/accelerator-optimized-machines#a3-disks
109
+ gen3HyperdiskLimit int64 = 31
110
+ // doc https://cloud.google.com/compute/docs/compute-optimized-machines#h3_disks
111
+ h3HyperdiskLimit int64 = 7 // Use limit for Hyperdisk Balanced
105
112
defaultLinuxFsType = "ext4"
106
113
defaultWindowsFsType = "ntfs"
107
114
fsTypeExt3 = "ext3"
@@ -571,7 +578,7 @@ func (ns *GCENodeServer) NodeGetInfo(ctx context.Context, req *csi.NodeGetInfoRe
571
578
572
579
nodeID := common .CreateNodeID (ns .MetadataService .GetProject (), ns .MetadataService .GetZone (), ns .MetadataService .GetName ())
573
580
574
- volumeLimits , err := ns .GetVolumeLimits ()
581
+ volumeLimits , err := ns .GetVolumeLimits (ctx )
575
582
if err != nil {
576
583
klog .Errorf ("GetVolumeLimits failed: %v" , err .Error ())
577
584
}
@@ -731,7 +738,7 @@ func (ns *GCENodeServer) NodeExpandVolume(ctx context.Context, req *csi.NodeExpa
731
738
}, nil
732
739
}
733
740
734
- func (ns * GCENodeServer ) GetVolumeLimits () (int64 , error ) {
741
+ func (ns * GCENodeServer ) GetVolumeLimits (ctx context. Context ) (int64 , error ) {
735
742
// Machine-type format: n1-type-CPUS or custom-CPUS-RAM or f1/g1-type
736
743
machineType := ns .MetadataService .GetMachineType ()
737
744
@@ -741,6 +748,22 @@ func (ns *GCENodeServer) GetVolumeLimits() (int64, error) {
741
748
return volumeLimitSmall , nil
742
749
}
743
750
}
751
+
752
+ // Get attach limit override from label
753
+ attachLimitOverride , err := GetAttachLimitsOverrideFromNodeLabel (ctx , ns .MetadataService .GetName ())
754
+ if err == nil && attachLimitOverride > 0 && attachLimitOverride < 128 {
755
+ return attachLimitOverride , nil
756
+ } else {
757
+ // If there is an error or the range is not valid, still proceed to get defaults for the machine type
758
+ if err != nil {
759
+ klog .Warningf ("using default value due to err getting node-restriction.kubernetes.io/gke-volume-attach-limit-override: %v" , err )
760
+ }
761
+ if attachLimitOverride != 0 {
762
+ klog .Warningf ("using default value due to invalid node-restriction.kubernetes.io/gke-volume-attach-limit-override: %d" , attachLimitOverride )
763
+ }
764
+ }
765
+
766
+ // Process gen4 machine attach limits
744
767
gen4MachineTypesPrefix := []string {"c4a-" , "c4-" , "n4-" }
745
768
for _ , gen4Prefix := range gen4MachineTypesPrefix {
746
769
if strings .HasPrefix (machineType , gen4Prefix ) {
@@ -760,5 +783,59 @@ func (ns *GCENodeServer) GetVolumeLimits() (int64, error) {
760
783
}
761
784
}
762
785
786
+ // Process gen3 machine attach limits
787
+ gen3MachineTypesPrefix := []string {"c3-" , "c3d-" }
788
+ for _ , gen3Prefix := range gen3MachineTypesPrefix {
789
+ if strings .HasPrefix (machineType , gen3Prefix ) {
790
+ cpus , err := common .ExtractCPUFromMachineType (machineType )
791
+ if err != nil {
792
+ return volumeLimitSmall , err
793
+ }
794
+ if cpus <= 8 || strings .Contains (machineType , "metal" ) {
795
+ return volumeLimitSmall , nil
796
+ }
797
+ return gen3HyperdiskLimit , nil
798
+
799
+ }
800
+ if strings .HasPrefix (machineType , "z3-" ) {
801
+ return gen3HyperdiskLimit , nil
802
+ }
803
+ if strings .HasPrefix (machineType , "h3-" ) {
804
+ return h3HyperdiskLimit , nil
805
+ }
806
+ if strings .HasPrefix (machineType , "a3-" ) {
807
+ if machineType == "a3-ultragpu-8g" {
808
+ return volumeLimitBig , nil
809
+ } else {
810
+ return gen3HyperdiskLimit , nil
811
+ }
812
+ }
813
+
814
+ }
815
+
763
816
return volumeLimitBig , nil
764
817
}
818
+
819
+ func GetAttachLimitsOverrideFromNodeLabel (ctx context.Context , nodeName string ) (int64 , error ) {
820
+ cfg , err := rest .InClusterConfig ()
821
+ if err != nil {
822
+ return 0 , err
823
+ }
824
+ kubeClient , err := kubernetes .NewForConfig (cfg )
825
+ if err != nil {
826
+ return 0 , err
827
+ }
828
+ node , err := getNodeWithRetry (ctx , kubeClient , nodeName )
829
+ if err != nil {
830
+ return 0 , err
831
+ }
832
+ if val , found := node .GetLabels ()[fmt .Sprintf (common .NodeRestrictionLabelPrefix , common .AttachLimitOverrideLabel )]; found {
833
+ attachLimitOverrideForNode , err := strconv .ParseInt (val , 10 , 64 )
834
+ if err != nil {
835
+ return 0 , fmt .Errorf ("error getting attach limit override from node label: %v" , err )
836
+ }
837
+ klog .V (4 ).Infof ("attach limit override for the node: %v" , attachLimitOverrideForNode )
838
+ return attachLimitOverrideForNode , nil
839
+ }
840
+ return 0 , nil
841
+ }
0 commit comments