diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml b/spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml
new file mode 100644
index 00000000..4f69d13b
--- /dev/null
+++ b/spring-cloud-kubernetes-integration-tests/load-balancer/pom.xml
@@ -0,0 +1,36 @@
+
+
+
+ spring-cloud-kubernetes-integration-tests
+ org.springframework.cloud
+ 2.0.0-SNAPSHOT
+
+ 4.0.0
+
+ load-balancer
+
+
+
+ org.springframework.cloud
+ spring-cloud-starter-kubernetes-all
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ io.fabric8
+ kubernetes-server-mock
+ 4.10.2
+ test
+
+
+
+
diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/main/java/org/spring/framework/kubernetes/loadbalancer/SimpleLoadBalancerApp.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/main/java/org/spring/framework/kubernetes/loadbalancer/SimpleLoadBalancerApp.java
new file mode 100644
index 00000000..84ef41c8
--- /dev/null
+++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/main/java/org/spring/framework/kubernetes/loadbalancer/SimpleLoadBalancerApp.java
@@ -0,0 +1,31 @@
+package org.spring.framework.kubernetes.loadbalancer;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.client.RestTemplateBuilder;
+import org.springframework.cloud.client.loadbalancer.LoadBalanced;
+import org.springframework.context.annotation.Bean;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.client.RestTemplate;
+
+@SpringBootApplication
+@RestController
+public class SimpleLoadBalancerApp {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SimpleLoadBalancerApp.class, args);
+ }
+
+ @Bean
+ @LoadBalanced
+ RestTemplate restTemplate() {
+ return new RestTemplateBuilder().build();
+ }
+
+ @GetMapping("/greeting")
+ public String greeting() {
+ return "greeting";
+ }
+
+}
diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java
new file mode 100644
index 00000000..e9533cb8
--- /dev/null
+++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerAllNamespacesTest.java
@@ -0,0 +1,71 @@
+package org.springframework.kubernetes.loadbalancer;
+
+import java.util.List;
+
+import io.fabric8.kubernetes.api.model.Endpoints;
+import io.fabric8.kubernetes.api.model.ServicePortBuilder;
+import io.fabric8.kubernetes.api.model.ServiceSpecBuilder;
+import io.fabric8.kubernetes.client.Config;
+import io.fabric8.kubernetes.client.KubernetesClient;
+import io.fabric8.kubernetes.client.server.mock.KubernetesServer;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.runner.RunWith;
+import org.spring.framework.kubernetes.loadbalancer.SimpleLoadBalancerApp;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.web.client.RestTemplate;
+
+@SpringBootTest(classes = {SimpleLoadBalancerApp.class}, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT,
+ properties = {"spring.cloud.kubernetes.discovery.all-namespaces=true"})
+@RunWith(SpringRunner.class)
+public class LoadBalancerAllNamespacesTest {
+
+ @Autowired
+ RestTemplate restTemplate;
+ @ClassRule
+ public static KubernetesServer server = new KubernetesServer(true, true);
+
+ private static KubernetesClient client;
+
+ @BeforeClass
+ public static void setup() {
+ client = server.getClient();
+
+ System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, client.getConfiguration().getMasterUrl());
+ System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true");
+ System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false");
+ System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false");
+ System.setProperty(Config.KUBERNETES_HTTP2_DISABLE, "true");
+ System.setProperty(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, "test");
+ }
+
+ @Test
+ public void testLoadBalancerDifferentNamespace() {
+ createTestData("service-b", "b");
+ String response = restTemplate.getForObject("http://service-b/greeting", String.class);
+ Assertions.assertNotNull(response);
+ Assertions.assertEquals("greeting", response);
+ }
+
+ private void createTestData(String name, String namespace) {
+ client.services().inNamespace(namespace).createNew()
+ .withNewMetadata().withName(name).withNamespace(namespace).endMetadata()
+ .withSpec(new ServiceSpecBuilder()
+ .withPorts(new ServicePortBuilder().withProtocol("TCP").withPort(8080).build())
+ .build())
+ .done();
+ client.endpoints().inNamespace(namespace).createNew()
+ .withNewMetadata().withName("service-a").withNamespace(namespace).endMetadata()
+ .addNewSubset()
+ .addNewAddress().withIp("localhost").endAddress()
+ .addNewPort().withName("http").withPort(8080).endPort()
+ .endSubset()
+ .done();
+ }
+
+}
diff --git a/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerTest.java b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerTest.java
new file mode 100644
index 00000000..09f24730
--- /dev/null
+++ b/spring-cloud-kubernetes-integration-tests/load-balancer/src/test/java/org/springframework/kubernetes/loadbalancer/LoadBalancerTest.java
@@ -0,0 +1,74 @@
+package org.springframework.kubernetes.loadbalancer;
+
+import io.fabric8.kubernetes.api.model.ServicePortBuilder;
+import io.fabric8.kubernetes.api.model.ServiceSpecBuilder;
+import io.fabric8.kubernetes.client.Config;
+import io.fabric8.kubernetes.client.KubernetesClient;
+import io.fabric8.kubernetes.client.server.mock.KubernetesServer;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.runner.RunWith;
+import org.spring.framework.kubernetes.loadbalancer.SimpleLoadBalancerApp;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.web.client.RestTemplate;
+
+@SpringBootTest(classes = {SimpleLoadBalancerApp.class}, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
+@RunWith(SpringRunner.class)
+public class LoadBalancerTest {
+
+ @Autowired
+ RestTemplate restTemplate;
+ @ClassRule
+ public static KubernetesServer server = new KubernetesServer(true, true);
+
+ private static KubernetesClient client;
+
+ @BeforeClass
+ public static void setup() {
+ client = server.getClient();
+
+ System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, client.getConfiguration().getMasterUrl());
+ System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true");
+ System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false");
+ System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false");
+ System.setProperty(Config.KUBERNETES_HTTP2_DISABLE, "true");
+ System.setProperty(Config.KUBERNETES_NAMESPACE_SYSTEM_PROPERTY, "test");
+ }
+
+ @Test
+ public void testLoadBalancerSameNamespace() {
+ createTestData("service-a", "test");
+ String response = restTemplate.getForObject("http://service-a/greeting", String.class);
+ Assertions.assertNotNull(response);
+ Assertions.assertEquals("greeting", response);
+ }
+
+ @Test
+ public void testLoadBalancerDifferentNamespace() {
+ createTestData("service-b", "b");
+ Assertions.assertThrows(IllegalStateException.class, () -> restTemplate
+ .getForObject("http://service-b/greeting", String.class));
+ }
+
+ private void createTestData(String name, String namespace) {
+ client.services().inNamespace(namespace).createNew()
+ .withNewMetadata().withName(name).endMetadata()
+ .withSpec(new ServiceSpecBuilder()
+ .withPorts(new ServicePortBuilder().withProtocol("TCP").withPort(8080).build())
+ .build())
+ .done();
+ client.endpoints().inNamespace(namespace).createNew()
+ .withNewMetadata().withName("service-a").endMetadata()
+ .addNewSubset()
+ .addNewAddress().withIp("localhost").endAddress()
+ .addNewPort().withName("http").withPort(8080).endPort()
+ .endSubset()
+ .done();
+ }
+
+}
diff --git a/spring-cloud-kubernetes-integration-tests/pom.xml b/spring-cloud-kubernetes-integration-tests/pom.xml
index c666a61e..fcbd148b 100644
--- a/spring-cloud-kubernetes-integration-tests/pom.xml
+++ b/spring-cloud-kubernetes-integration-tests/pom.xml
@@ -133,6 +133,7 @@
simple-configmap
discovery
+ load-balancer
diff --git a/spring-cloud-starter-kubernetes-all/pom.xml b/spring-cloud-starter-kubernetes-all/pom.xml
index b0d46cb5..fd9567f0 100644
--- a/spring-cloud-starter-kubernetes-all/pom.xml
+++ b/spring-cloud-starter-kubernetes-all/pom.xml
@@ -46,6 +46,11 @@
spring-cloud-kubernetes-discovery
+
+ org.springframework.cloud
+ spring-cloud-starter-loadbalancer
+
+