当前位置: 首页 > 知识库问答 >
问题:

Spring Sidecar如何与Docker合作

慕承恩
2023-03-14

我们有一个sidecar应用程序,它使我们能够注册节点。js应用程序与Eureka一起支持服务发现。

我们的sidecar应用程序配置如下所示:

server:
  port: 9000

spring:
  application:
    name: session-service

sidecar:
  port: 3000
  health-url: http://sessionServiceNode:${sidecar.port}/health.json

eureka:
  client:
    serviceUrl:
      defaultZone: http://discoveryService:8761/eureka/
  instance:
    lease-renewal-interval-in-seconds: 5
    prefer-ip-address: true

根据配置,我们的节点应用程序正在sidecar定义的端口3000上运行。port属性,我们的sidecar应用程序应该按照服务器在port9000上运行。端口

我们向节点应用程序添加了一个endpoint,以允许sidecar检查应用程序的运行状况(sidecar.health url)。hostname是我们为运行节点应用程序的容器指定的别名。

我们的Eureka服务运行在一个单独的容器中,该容器还通过alias discoveryService链接到sidecar应用程序容器。

我们有一个单独的测试Spring引导应用程序,它在一个单独的容器中运行,该容器是会话服务的使用者。该容器仅链接到发现服务容器。

Sidecar应用程序按预期在Eureka注册

测试服务对会话服务使用两种形式的查找。一个使用外国客户机:

@FeignClient(value = "session-service") // name of our registered service in eureka
interface SessionServiceClient {

    @RequestMapping(value = "/document/get/24324", method = GET)
    String documentGetTest();

}

另一种方法使用更具程序性的查找:

@Autowired
private DiscoveryClient discoveryClient;

...
discoveryClient.getInstances("session-service");

当我们向测试服务发出请求时,测试服务会查找会话服务,但是eureka返回的实例信息的URI为:<代码>http://172.17.0.5:3000这是不正确的172.17.0.5是sidecar应用程序容器的IP地址,但端口是节点应用程序运行的端口?

应该期望看到eureka返回带有会话服务端口(http://172.17.0.5:9000)的会话服务容器的位置,然后sidecar通过zuul代理为我们“转发”到节点应用程序(http://172.17.0.6:3000)?还是Eureka直接给我们节点应用程序的位置?

我在下面包含了来自Eureka的会话服务实例信息:

<?xml version="1.0" encoding="UTF-8"?>
<application>
   <name>SESSION-SERVICE</name>
   <instance>
      <hostName>172.17.0.5</hostName>
      <app>SESSION-SERVICE</app>
      <ipAddr>172.17.0.5</ipAddr>
      <status>UP</status>
      <overriddenstatus>UNKNOWN</overriddenstatus>
      <port enabled="true">3000</port>
      <securePort enabled="false">443</securePort>
      <countryId>1</countryId>
      <dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo">
         <name>MyOwn</name>
      </dataCenterInfo>
      <leaseInfo>
         <renewalIntervalInSecs>5</renewalIntervalInSecs>
         <durationInSecs>90</durationInSecs>
         <registrationTimestamp>1461223810081</registrationTimestamp>
         <lastRenewalTimestamp>1461224812429</lastRenewalTimestamp>
         <evictionTimestamp>0</evictionTimestamp>
         <serviceUpTimestamp>1461223810081</serviceUpTimestamp>
      </leaseInfo>
      <metadata class="java.util.Collections$EmptyMap" />
      <homePageUrl>http://c892e0c03cf4:3000/</homePageUrl>
      <statusPageUrl>http://c892e0c03cf4:9000/info</statusPageUrl>
      <healthCheckUrl>http://c892e0c03cf4:9000/health</healthCheckUrl>
      <vipAddress>session-service</vipAddress>
      <isCoordinatingDiscoveryServer>false</isCoordinatingDiscoveryServer>
      <lastUpdatedTimestamp>1461223810081</lastUpdatedTimestamp>
      <lastDirtyTimestamp>1461223033045</lastDirtyTimestamp>
      <actionType>ADDED</actionType>
   </instance>
</application>

编辑:

查看代码后,Eureka使用InetAddress.getLocalHost(). getHostAddress()InetAddress.getLocalHost(). getHostName()分别返回的主机信息来确定实例的地址。这就是为什么我们要获取sidecar容器的IP地址。有什么方法可以覆盖这种行为吗?


共有2个答案

微生雨泽
2023-03-14

Spring Cloud正在选择第一个非环回IP地址。您可以做几件事之一。

一:忽略你不想选择的网络接口。文档在这里。

spring:
  cloud:
    inetutils:
      ignoredInterfaces:
        - docker0
        - veth.*

或者两个:显式设置eureka注册的ip地址或主机名(如果您在任何地方都使用相同的docker别名。对于主机名设置eureka.instance.hostname=sesionServiceNode并删除predive-ip-Address=true选项。对于ip addr,eureka.instance.ip地址=

白昊东
2023-03-14

因此,根据it Sidecar的外观,我们假设spring boot Sidecar应用程序和非jvm应用程序运行在同一台主机上。在我们的场景中,我们在单独的容器中运行所有内容。一个容器用于sidecar jvm应用程序,一个容器用于节点。js应用程序。理论上,我们可以让两个应用程序在同一个容器中运行,但这违反了Docker的最佳实践,即每个容器有一个unix进程。

为了使其工作,我们重写了EurekaInstanceConfigBean,它允许我们控制为实例选择的主机名和IP地址。在这种情况下,我们委托给inetUtils类并从主机名(这是通过docker链接的非jvm应用程序的别名)中查找IP地址。我们使用Spring@ConfigurationPropertiesapplication.yml配置文件控制主机名/端口。

SessionServiceSidecar。JAVA

@Component
@ConfigurationProperties
public class SessionServiceSidecarProperties {

    @Value("${sidecar.hostname}")
    private String hostname;

    @Value("${sidecar.port}")
    private Integer port;

    public String getHostname() {
        return hostname;
    }

    public Integer getPort() {
        return port;
    }

}

SessionServiceApp。JAVA

@SpringBootApplication
@EnableSidecar
@EnableDiscoveryClient
@Configuration
@ComponentScan
@EnableConfigurationProperties
public class SessionServiceApp {

    private @Autowired SessionServiceSidecarProperties properties;

    public static void main(String[] args) {
        SpringApplication.run(SessionServiceApp.class, args);
    }

    @Bean
    public EurekaInstanceConfigBean eurekaInstanceConfigBean(InetUtils inetUtils) {

        final String sidecarHostname = properties.getHostname();
        final Integer sidecarPort = properties.getPort();

        try {

            final EurekaInstanceConfigBean instance = new EurekaInstanceConfigBean(inetUtils);
            instance.setHostname(sidecarHostname);
            instance.setIpAddress(inetUtils.convertAddress(InetAddress.getByName(sidecarHostname)).getIpAddress());
            instance.setNonSecurePort(sidecarPort);
            return instance;

        } catch(UnknownHostException e) {
            throw new IllegalStateException("Could not resolve IP address of sidecar application using hostname: " + sidecarHostname);
        }

    }

}

应用yml公司

spring:
  application:
    name: session-service

server:
  port: 9000

sidecar:
  hostname: sessionServiceNode
  port: 3000
  health-url: http://sessionServiceNode:${sidecar.port}/health.json

eureka:
  client:
    serviceUrl:
      defaultZone: http://discoveryService:8761/eureka/
  instance:
    lease-renewal-interval-in-seconds: 5
    prefer-ip-address: true

希望Spring能够让我们通过sidecar控制sidecar应用程序的主机名和端口。将来的主机名属性。

希望这有帮助!

 类似资料:
  • 问题内容: 我最近安装了隐私vpn,事实证明启用的openvpn会破坏docker。 当我尝试运行时,出现以下错误 禁用vpn可以解决此问题(但是我宁愿不禁用它)。有什么办法可以使这两者和平共处?我使用debian jessie,并且我的openvpn具有以下版本字符串 很多人通过禁用openvpn来“解决”此问题,因此我专门询问如何使这两个工具同时工作。 如果这有什么不同,我的vpn提供程序是:

  • 从docker容器分离可以使用。但是,如何在docker中分离docker? 在我的使用中,我在docker中运行ssh,在服务器上,我还附加到docker容器。现在我希望能够从服务器上连接的conatiner中分离,但是将从运行ssh连接的本地容器中分离。 有没有什么方法可以从码头机中的码头机中分离出来?

  • 问题内容: Docker和OpenShift都是用于实现PaaS服务的框架。 他们如何比较架构和功能? 问题答案: 主要区别在于,Docker作为一个项目仅专注于运行时容器,而OpenShift(作为系统)既包含运行时容器也包括REST API,协调和Web界面,以部署和管理各个容器。 仅比较运行时容器,OpenShift和Docker都使用内核隔离功能将租户进程分开。对于主要通过LXC实现的Do

  • 我让jenkins在github上的容器和项目源代码中运行。 我需要在与jenkins相同的主机上运行容器中的项目,但不是作为docker中的docker,我希望将它们作为兄弟容器运行。 我的管道如下所示: 从github中提取源文件 我现在要做的是使用jenkins容器中主机的docker套接字: jenkins容器将源代码为/var/jenkins_home/workspace/BRANCH_

  • 本文向大家介绍Docker与Golang的巧妙结合,包括了Docker与Golang的巧妙结合的使用技巧和注意事项,需要的朋友参考一下 Docker与Golang的巧妙结合 【编者的话】这是一个展示在使用Go语言时如何让Docker更有用的提示与技巧的简辑。例如,如何使用不同版本的Go工具链来编译Go代码,如何交叉编译到不同的平台(并且测试结果!),或者如何制作真正小的容器镜像。 下面的文章假定你

  • 这是一道样题!千万不要在生产中这样做。在单独的容器中运行NGINX/PHP/OTHER服务! 和: