diff --git a/pkg/api/validation/validation.go b/pkg/api/validation/validation.go index 0b3d433eb68..c4680784bcf 100644 --- a/pkg/api/validation/validation.go +++ b/pkg/api/validation/validation.go @@ -2406,6 +2406,9 @@ func ValidateService(service *api.Service) field.ErrorList { allErrs = append(allErrs, field.Invalid(portPath, port.Port, "may not expose port 10250 externally since it is used by kubelet")) } } + if service.Spec.ClusterIP == "None" { + allErrs = append(allErrs, field.Invalid(specPath.Child("clusterIP"), service.Spec.ClusterIP, "may not be set to 'None' for LoadBalancer services")) + } case api.ServiceTypeExternalName: if service.Spec.ClusterIP != "" { allErrs = append(allErrs, field.Invalid(specPath.Child("clusterIP"), service.Spec.ClusterIP, "must be empty for ExternalName services")) diff --git a/pkg/api/validation/validation_test.go b/pkg/api/validation/validation_test.go index efae8426103..5a4fe048020 100644 --- a/pkg/api/validation/validation_test.go +++ b/pkg/api/validation/validation_test.go @@ -5173,6 +5173,14 @@ func TestValidateService(t *testing.T) { }, numErrs: 1, }, + { + name: "LoadBalancer type cannot have None ClusterIP", + tweakSvc: func(s *api.Service) { + s.Spec.ClusterIP = "None" + s.Spec.Type = api.ServiceTypeLoadBalancer + }, + numErrs: 1, + }, } for _, tc := range testCases { @@ -6432,6 +6440,14 @@ func TestValidateServiceUpdate(t *testing.T) { }, numErrs: 1, }, + { + name: "LoadBalancer type cannot have None ClusterIP", + tweakSvc: func(oldSvc, newSvc *api.Service) { + newSvc.Spec.ClusterIP = "None" + newSvc.Spec.Type = api.ServiceTypeLoadBalancer + }, + numErrs: 1, + }, } for _, tc := range testCases {