@@ -34,6 +34,7 @@ import (
34
34
"k8s.io/kubernetes/cmd/kubeadm/app/phases/certs"
35
35
staticpodutil "k8s.io/kubernetes/cmd/kubeadm/app/util/staticpod"
36
36
testutil "k8s.io/kubernetes/cmd/kubeadm/test"
37
+ "k8s.io/kubernetes/pkg/features"
37
38
)
38
39
39
40
const (
@@ -719,6 +720,73 @@ func TestGetControllerManagerCommand(t *testing.T) {
719
720
"--service-cluster-ip-range=fd03::/112" ,
720
721
},
721
722
},
723
+ {
724
+ name : "dual-stack networking for " + cpVersion ,
725
+ cfg : & kubeadmapi.ClusterConfiguration {
726
+ Networking : kubeadmapi.Networking {
727
+ PodSubnet : "2001:db8::/64,10.1.0.0/16" ,
728
+ ServiceSubnet : "fd03::/112,192.168.0.0/16" ,
729
+ },
730
+ CertificatesDir : testCertsDir ,
731
+ KubernetesVersion : cpVersion ,
732
+ FeatureGates : map [string ]bool {string (features .IPv6DualStack ): true },
733
+ },
734
+ expected : []string {
735
+ "kube-controller-manager" ,
736
+ "--bind-address=127.0.0.1" ,
737
+ "--leader-elect=true" ,
738
+ "--kubeconfig=" + kubeadmconstants .KubernetesDir + "/controller-manager.conf" ,
739
+ "--root-ca-file=" + testCertsDir + "/ca.crt" ,
740
+ "--service-account-private-key-file=" + testCertsDir + "/sa.key" ,
741
+ "--cluster-signing-cert-file=" + testCertsDir + "/ca.crt" ,
742
+ "--cluster-signing-key-file=" + testCertsDir + "/ca.key" ,
743
+ "--use-service-account-credentials=true" ,
744
+ "--controllers=*,bootstrapsigner,tokencleaner" ,
745
+ "--authentication-kubeconfig=" + kubeadmconstants .KubernetesDir + "/controller-manager.conf" ,
746
+ "--authorization-kubeconfig=" + kubeadmconstants .KubernetesDir + "/controller-manager.conf" ,
747
+ "--client-ca-file=" + testCertsDir + "/ca.crt" ,
748
+ "--requestheader-client-ca-file=" + testCertsDir + "/front-proxy-ca.crt" ,
749
+ "--feature-gates=IPv6DualStack=true" ,
750
+ "--allocate-node-cidrs=true" ,
751
+ "--cluster-cidr=2001:db8::/64,10.1.0.0/16" ,
752
+ "--node-cidr-mask-size-ipv4=24" ,
753
+ "--node-cidr-mask-size-ipv6=80" ,
754
+ "--service-cluster-ip-range=fd03::/112,192.168.0.0/16" ,
755
+ },
756
+ },
757
+ {
758
+ name : "dual-stack networking custom extra-args for " + cpVersion ,
759
+ cfg : & kubeadmapi.ClusterConfiguration {
760
+ Networking : kubeadmapi.Networking {PodSubnet : "10.0.1.15/16,2001:db8::/64" },
761
+ ControllerManager : kubeadmapi.ControlPlaneComponent {
762
+ ExtraArgs : map [string ]string {"node-cidr-mask-size-ipv4" : "20" , "node-cidr-mask-size-ipv6" : "96" },
763
+ },
764
+ CertificatesDir : testCertsDir ,
765
+ KubernetesVersion : cpVersion ,
766
+ FeatureGates : map [string ]bool {string (features .IPv6DualStack ): true },
767
+ },
768
+ expected : []string {
769
+ "kube-controller-manager" ,
770
+ "--bind-address=127.0.0.1" ,
771
+ "--leader-elect=true" ,
772
+ "--kubeconfig=" + kubeadmconstants .KubernetesDir + "/controller-manager.conf" ,
773
+ "--root-ca-file=" + testCertsDir + "/ca.crt" ,
774
+ "--service-account-private-key-file=" + testCertsDir + "/sa.key" ,
775
+ "--cluster-signing-cert-file=" + testCertsDir + "/ca.crt" ,
776
+ "--cluster-signing-key-file=" + testCertsDir + "/ca.key" ,
777
+ "--use-service-account-credentials=true" ,
778
+ "--controllers=*,bootstrapsigner,tokencleaner" ,
779
+ "--authentication-kubeconfig=" + kubeadmconstants .KubernetesDir + "/controller-manager.conf" ,
780
+ "--authorization-kubeconfig=" + kubeadmconstants .KubernetesDir + "/controller-manager.conf" ,
781
+ "--client-ca-file=" + testCertsDir + "/ca.crt" ,
782
+ "--requestheader-client-ca-file=" + testCertsDir + "/front-proxy-ca.crt" ,
783
+ "--feature-gates=IPv6DualStack=true" ,
784
+ "--allocate-node-cidrs=true" ,
785
+ "--cluster-cidr=10.0.1.15/16,2001:db8::/64" ,
786
+ "--node-cidr-mask-size-ipv4=20" ,
787
+ "--node-cidr-mask-size-ipv6=96" ,
788
+ },
789
+ },
722
790
}
723
791
724
792
for _ , rt := range tests {
@@ -738,75 +806,92 @@ func TestCalcNodeCidrSize(t *testing.T) {
738
806
name string
739
807
podSubnet string
740
808
expectedPrefix string
809
+ expectedIPv6 bool
741
810
}{
742
811
{
743
812
name : "Malformed pod subnet" ,
744
813
podSubnet : "10.10.10/160" ,
745
814
expectedPrefix : "24" ,
815
+ expectedIPv6 : false ,
746
816
},
747
817
{
748
818
name : "V4: Always uses 24" ,
749
819
podSubnet : "10.10.10.10/16" ,
750
820
expectedPrefix : "24" ,
821
+ expectedIPv6 : false ,
751
822
},
752
823
{
753
824
name : "V6: Use pod subnet size, when not enough space" ,
754
825
podSubnet : "2001:db8::/128" ,
755
826
expectedPrefix : "128" ,
827
+ expectedIPv6 : true ,
756
828
},
757
829
{
758
830
name : "V6: Use pod subnet size, when not enough space" ,
759
831
podSubnet : "2001:db8::/113" ,
760
832
expectedPrefix : "113" ,
833
+ expectedIPv6 : true ,
761
834
},
762
835
{
763
836
name : "V6: Special case with 256 nodes" ,
764
837
podSubnet : "2001:db8::/112" ,
765
838
expectedPrefix : "120" ,
839
+ expectedIPv6 : true ,
766
840
},
767
841
{
768
842
name : "V6: Using /120 for node CIDR" ,
769
843
podSubnet : "2001:db8::/104" ,
770
844
expectedPrefix : "120" ,
845
+ expectedIPv6 : true ,
771
846
},
772
847
{
773
848
name : "V6: Using /112 for node CIDR" ,
774
849
podSubnet : "2001:db8::/103" ,
775
850
expectedPrefix : "112" ,
851
+ expectedIPv6 : true ,
776
852
},
777
853
{
778
854
name : "V6: Using /112 for node CIDR" ,
779
855
podSubnet : "2001:db8::/96" ,
780
856
expectedPrefix : "112" ,
857
+ expectedIPv6 : true ,
781
858
},
782
859
{
783
860
name : "V6: Using /104 for node CIDR" ,
784
861
podSubnet : "2001:db8::/95" ,
785
862
expectedPrefix : "104" ,
863
+ expectedIPv6 : true ,
786
864
},
787
865
{
788
866
name : "V6: For /64 pod net, use /80" ,
789
867
podSubnet : "2001:db8::/64" ,
790
868
expectedPrefix : "80" ,
869
+ expectedIPv6 : true ,
791
870
},
792
871
{
793
872
name : "V6: For /48 pod net, use /64" ,
794
873
podSubnet : "2001:db8::/48" ,
795
874
expectedPrefix : "64" ,
875
+ expectedIPv6 : true ,
796
876
},
797
877
{
798
878
name : "V6: For /32 pod net, use /48" ,
799
879
podSubnet : "2001:db8::/32" ,
800
880
expectedPrefix : "48" ,
881
+ expectedIPv6 : true ,
801
882
},
802
883
}
803
884
for _ , test := range tests {
804
885
t .Run (test .name , func (t * testing.T ) {
805
- actualPrefix := calcNodeCidrSize (test .podSubnet )
886
+ actualPrefix , actualIPv6 := calcNodeCidrSize (test .podSubnet )
806
887
if actualPrefix != test .expectedPrefix {
807
888
t .Errorf ("Case [%s]\n Calc of node CIDR size for pod subnet %q failed: Expected %q, saw %q" ,
808
889
test .name , test .podSubnet , test .expectedPrefix , actualPrefix )
809
890
}
891
+ if actualIPv6 != test .expectedIPv6 {
892
+ t .Errorf ("Case [%s]\n Calc of node CIDR size for pod subnet %q failed: Expected isIPv6=%v, saw isIPv6=%v" ,
893
+ test .name , test .podSubnet , test .expectedIPv6 , actualIPv6 )
894
+ }
810
895
})
811
896
}
812
897
0 commit comments