Spring boot kubernetes discovery client does not find instance by service name from kubernetes

2/10/2022

I am trying to get a response through the kubernetes service name. I address him by the name of the service from deployment.yaml connection timeout occurs when connecting. In this case, the GetAll method from the controller returns the correct list of service names, but the /getInfo/{nameService} method returns a void for the services service-with-kubernetes-service and discovery-service-with-kubernetes-service. What could it be because of? I attach the code below

deployment.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: namespace-reader
rules:
  - apiGroups: ["", "extensions", "apps"]
    resources: ["configmaps", "pods", "services", "endpoints", "secrets"]
    verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: namespace-reader-binding
  namespace: default
subjects:
  - kind: ServiceAccount
    name: default
    apiGroup: ""
roleRef:
  kind: Role
  name: namespace-reader
  apiGroup: ""
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: service-with-kubernetes-config
data:
  math_max: "10"
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: provider-service-with-kubernetes-config
data:
  application.yml: |-
    math:
      max: 10000
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: service-with-kubernetes-deployment
spec:
  selector:
    matchLabels:
      name: service-with-kubernetes
  template:
    metadata:
      labels:
        name: service-with-kubernetes
    spec:
      containers:
        - name: service-with-kubernetes
          image: lionchi/service-with-kubernetes:latest
          ports:
            - containerPort: 8080
          env:
            - name: MATH_MAX
              valueFrom:
                configMapKeyRef:
                  name: service-with-kubernetes-config
                  key: math_max
          livenessProbe:
            httpGet:
              port: 8080
              path: /actuator/health/liveness
          readinessProbe:
            httpGet:
              port: 8080
              path: /actuator/health/readiness
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: discovery-service-with-kubernetes-deployment
spec:
  selector:
    matchLabels:
      name: discovery-service-with-kubernetes
  template:
    metadata:
      labels:
        name: discovery-service-with-kubernetes
    spec:
      containers:
        - name: discovery-service-with-kubernetes
          image: lionchi/discovery-service-with-kubernetes:latest
          ports:
            - containerPort: 9090
          livenessProbe:
            httpGet:
              port: 9090
              path: /actuator/health/liveness
          readinessProbe:
            httpGet:
              port: 9090
              path: /actuator/health/readiness
---
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  name: service-with-kubernetes-autoscaling
spec:
  scaleTargetRef: # что конкретно автоскейлим
    apiVersion: apps/v2beta1v1
    kind: Deployment
    name: service-with-kubernetes-deployment
  minReplicas: 1
  maxReplicas: 2
  metrics:
    - type: Resource
      resource:
        name: cpu
        targetAverageUtilization: 70
    - type: Resource
      resource:
        name: memory
        targetAverageUtilization: 80
---
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  name: discovery-service-with-kubernetes-deployment
spec:
  scaleTargetRef: # что конкретно автоскейлим
    apiVersion: apps/v2beta1v1
    kind: Deployment
    name: service-with-kubernetes-deployment
  minReplicas: 1
  maxReplicas: 2
  metrics:
    - type: Resource
      resource:
        name: cpu
        targetAverageUtilization: 70
    - type: Resource
      resource:
        name: memory
        targetAverageUtilization: 80
---
apiVersion: v1
kind: Service
metadata:
  name: service-with-kubernetes-service
spec:
  selector: # на какие ПОДЫ будет действовать правило
    project: service-with-kubernetes
  ports:
    - name: service-with-kubernetes-listener
      protocol: TCP
      # Port on ClusterIp
      port: 8080
      # Port on POD
      targetPort: 8080
  type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
  name: discovery-service-with-kubernetes-service
spec:
  selector: # на какие ПОДЫ будет действовать правило
    project: discovery-service-with-kubernetes
  ports:
    - name: discvovery-service-with-kubernetes-listener
      protocol: TCP
      # Port on Load Balancer
      port: 9090
      # Port on POD
      targetPort: 9090
  type: NodePort

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>ru.jpixel</groupId>
    <artifactId>discovery-service-with-kubernetes</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>discovery-service-with-kubernetes</name>
    <description>discovery-service-with-kubernetes</description>
    <properties>
        <java.version>17</java.version>
        <org.springframework.kubernetes>2.1.0</org.springframework.kubernetes>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-kubernetes-client</artifactId>
            <version>${org.springframework.kubernetes}</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

java

@Configuration
public class RestTemplateConfiguration {
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
        return restTemplateBuilder.build();
    }
}

@RestController
@RequestMapping("/api/v1/web/services")
@RequiredArgsConstructor
public class DiscoveryServiceController {

    private final RestTemplate restTemplate;
    private final DiscoveryClient discoveryClient;

    @GetMapping(value = "/getAll")
    public List<String> getAll() {
        return discoveryClient.getServices();
    }

    @GetMapping(value = "/getInfo/{nameService}")
    public List<ServiceInstanceDto> getInfoInstances(@PathVariable String nameService) {
        return discoveryClient.getInstances(nameService).stream()
                .map(serviceInstance -> new ServiceInstanceDto(serviceInstance.getServiceId(), serviceInstance.getHost(), serviceInstance.getPort(), serviceInstance.getUri().toString()))
                .collect(Collectors.toList());
    }

    @GetMapping(value = "/getUserAll/{nameService}")
    public List<UserDto> getUserAll(@PathVariable String nameService) {
        try {
            var restTemplateForObject = restTemplate.getForObject("http://" + nameService + "/api/v1/web/users/getAll", UserDto[].class);
            return Arrays.stream(restTemplateForObject != null ? restTemplateForObject : new UserDto[0]).toList();
        } catch (Exception e) {
            return Collections.emptyList();
        }
    }
}
-- Иван Гаврилов
java
kubernetes
spring-boot

0 Answers