Repository: traefik/traefik (language: go)

Issue:
AllowEmptyService flag is not taken into account on traefikService in kubernetes crd
### Welcome!

- [X] Yes, I've searched similar issues on [GitHub](https://github.com/traefik/traefik/issues) and didn't find any.
- [X] Yes, I've searched similar issues on the [Traefik community forum](https://community.traefik.io) and didn't find any.

### What did you do?

I was adding an empty service to a TraefikService

This parameter was setted
```
--providers.kubernetescrd.allowemptyservices=true
```

### What did you see instead?


Building a TraefikService object with empty service as source led to this error:

```
Error while building TraefikService: subset not found for web/my-app-canary","providerName":"kubernetescrd","serviceName":"my-app","time":"2022-08-05T12:34:56Z"}
```

### What version of Traefik are you using?

v2.9.1

### What is your environment & configuration?

```yaml
apiVersion: traefik.containo.us/v1alpha1
kind: TraefikService
metadata:
  name: my-app
  namespace: web
spec:
  weighted:
    services:
      - name: my-app-canary
        namespace: web
        port: 80
        weight: 0
      - name: my-app-stable
        namespace: web
        port: 80
        weight: 100

---

apiVersion: v1
kind: Service
metadata:
  name: my-app-stable
  namespace: web
spec:
  selector:
    app: my-app-stable
  type: ClusterIP
  ports:
    - name: main
      port: 80
      targetPort: 80
      protocol: TCP

---

apiVersion: v1
kind: Service
metadata:
  name: my-app-canary
  namespace: web-ui
spec:
  selector:
    app: my-app-canary
  type: ClusterIP
  ports:
    - name: main
      port: 80
      targetPort: 80
      protocol: TCP

```



### If applicable, please paste the log output in DEBUG level

_No response_


Discussion / hints:

Fix patch:
diff --git a/pkg/provider/kubernetes/crd/fixtures/with_empty_services_ts.yml b/pkg/provider/kubernetes/crd/fixtures/with_empty_services_ts.yml
new file mode 100644
index 0000000000..92500f3fd0
--- /dev/null
+++ b/pkg/provider/kubernetes/crd/fixtures/with_empty_services_ts.yml
@@ -0,0 +1,65 @@
+apiVersion: traefik.containo.us/v1alpha1
+kind: IngressRoute
+metadata:
+  name: test.route
+  namespace: default
+
+spec:
+  entryPoints:
+    - foo
+
+  routes:
+    - match: Host(`foo.com`) && PathPrefix(`/bar`)
+      kind: Rule
+      priority: 12
+      services:
+        - name: test-weighted
+          kind: TraefikService
+        - name: test-mirror
+          kind: TraefikService
+      middlewares:
+        - name: test-errorpage
+
+---
+apiVersion: traefik.containo.us/v1alpha1
+kind: TraefikService
+metadata:
+  name: test-weighted
+  namespace: default
+
+spec:
+  weighted:
+    services:
+      - name: whoami-without-endpoints-subsets
+        weight: 1
+        port: 80
+
+---
+apiVersion: traefik.containo.us/v1alpha1
+kind: TraefikService
+metadata:
+  name: test-mirror
+  namespace: default
+
+spec:
+  mirroring:
+    name: whoami-without-endpoints-subsets
+    port: 80
+    mirrors:
+      - name: whoami-without-endpoints-subsets
+        port: 80
+      - name: test-weighted
+        kind: TraefikService
+
+---
+apiVersion: traefik.containo.us/v1alpha1
+kind: Middleware
+metadata:
+  name: test-errorpage
+  namespace: default
+
+spec:
+  errors:
+    service:
+      name: whoami-without-endpoints-subsets
+      port: 80
diff --git a/pkg/provider/kubernetes/crd/kubernetes.go b/pkg/provider/kubernetes/crd/kubernetes.go
index a43345e675..67e639d39d 100644
--- a/pkg/provider/kubernetes/crd/kubernetes.go
+++ b/pkg/provider/kubernetes/crd/kubernetes.go
@@ -292,7 +292,12 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client)
 		}
 	}
 
-	cb := configBuilder{client: client, allowCrossNamespace: p.AllowCrossNamespace, allowExternalNameServices: p.AllowExternalNameServices}
+	cb := configBuilder{
+		client:                    client,
+		allowCrossNamespace:       p.AllowCrossNamespace,
+		allowExternalNameServices: p.AllowExternalNameServices,
+		allowEmptyServices:        p.AllowEmptyServices,
+	}
 
 	for _, service := range client.GetTraefikServices() {
 		err := cb.buildTraefikService(ctx, service, conf.HTTP.Services)
@@ -578,7 +583,14 @@ func (p *Provider) createErrorPageMiddleware(client Client, namespace string, er
 		Query:  errorPage.Query,
 	}
 
-	balancerServerHTTP, err := configBuilder{client: client, allowCrossNamespace: p.AllowCrossNamespace, allowExternalNameServices: p.AllowExternalNameServices}.buildServersLB(namespace, errorPage.Service.LoadBalancerSpec)
+	cb := configBuilder{
+		client:                    client,
+		allowCrossNamespace:       p.AllowCrossNamespace,
+		allowExternalNameServices: p.AllowExternalNameServices,
+		allowEmptyServices:        p.AllowEmptyServices,
+	}
+
+	balancerServerHTTP, err := cb.buildServersLB(namespace, errorPage.Service.LoadBalancerSpec)
 	if err != nil {
 		return nil, nil, err
 	}


Test patch:
diff --git a/pkg/provider/kubernetes/crd/kubernetes_test.go b/pkg/provider/kubernetes/crd/kubernetes_test.go
index 7465c8faef..52cdae1e0c 100644
--- a/pkg/provider/kubernetes/crd/kubernetes_test.go
+++ b/pkg/provider/kubernetes/crd/kubernetes_test.go
@@ -4037,6 +4037,91 @@ func TestLoadIngressRoutes(t *testing.T) {
 				TLS: &dynamic.TLSConfiguration{},
 			},
 		},
+		{
+			desc:               "TraefikService, empty service allowed",
+			allowEmptyServices: true,
+			paths:              []string{"services.yml", "with_empty_services_ts.yml"},
+			expected: &dynamic.Configuration{
+				UDP: &dynamic.UDPConfiguration{
+					Routers:  map[string]*dynamic.UDPRouter{},
+					Services: map[string]*dynamic.UDPService{},
+				},
+				TCP: &dynamic.TCPConfiguration{
+					Routers:     map[string]*dynamic.TCPRouter{},
+					Middlewares: map[string]*dynamic.TCPMiddleware{},
+					Services:    map[string]*dynamic.TCPService{},
+				},
+				HTTP: &dynamic.HTTPConfiguration{
+					Routers: map[string]*dynamic.Router{
+						"default-test-route-6b204d94623b3df4370c": {
+							EntryPoints: []string{"foo"},
+							Middlewares: []string{"default-test-errorpage"},
+							Service:     "default-test-route-6b204d94623b3df4370c",
+							Rule:        "Host(`foo.com`) && PathPrefix(`/bar`)",
+							Priority:    12,
+						},
+					},
+					Middlewares: map[string]*dynamic.Middleware{
+						"default-test-errorpage": {
+							Errors: &dynamic.ErrorPage{
+								Service: "default-test-errorpage-errorpage-service",
+							},
+						},
+					},
+					Services: map[string]*dynamic.Service{
+						"default-test-route-6b204d94623b3df4370c": {
+							Weighted: &dynamic.WeightedRoundRobin{
+								Services: []dynamic.WRRService{
+									{
+										Name:   "default-test-weighted",
+										Weight: func(i int) *int { return &i }(1),
+									},
+									{
+										Name:   "default-test-mirror",
+										Weight: func(i int) *int { return &i }(1),
+									},
+								},
+							},
+						},
+						"default-test-errorpage-errorpage-service": {
+							LoadBalancer: &dynamic.ServersLoadBalancer{
+								PassHostHeader: Bool(true),
+							},
+						},
+						"default-test-weighted": {
+							Weighted: &dynamic.WeightedRoundRobin{
+								Services: []dynamic.WRRService{
+									{
+										Name:   "default-whoami-without-endpoints-subsets-80",
+										Weight: func(i int) *int { return &i }(1),
+									},
+								},
+							},
+						},
+						"default-test-mirror": {
+							Mirroring: &dynamic.Mirroring{
+								Service: "default-whoami-without-endpoints-subsets-80",
+								Mirrors: []dynamic.MirrorService{
+									{
+										Name: "default-whoami-without-endpoints-subsets-80",
+									},
+									{
+										Name: "default-test-weighted",
+									},
+								},
+							},
+						},
+						"default-whoami-without-endpoints-subsets-80": {
+							LoadBalancer: &dynamic.ServersLoadBalancer{
+								PassHostHeader: Bool(true),
+							},
+						},
+					},
+					ServersTransports: map[string]*dynamic.ServersTransport{},
+				},
+				TLS: &dynamic.TLSConfiguration{},
+			},
+		},
 	}
 
 	for _, test := range testCases {