首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >来自运行在Fargate集群上的AWS ECS docker容器中的java应用程序的UnknownHostException

来自运行在Fargate集群上的AWS ECS docker容器中的java应用程序的UnknownHostException
EN

Stack Overflow用户
提问于 2018-01-30 03:19:35
回答 4查看 6.6K关注 0票数 10

我有一个大型的Java应用程序,我正试图在AWS的fargate集群上运行。镜像在我本地机器的docker上成功运行。当我在fargate中运行它时,它成功启动,但最终遇到以下错误,之后应用程序被卡住:

代码语言:javascript
复制
! java.net.UnknownHostException: 690bd678bcf4: 690bd678bcf4: Name or service not known
! at java.net.InetAddress.getLocalHost(InetAddress.java:1505) ~[na:1.8.0_151]
! at tracelink.misc.SingletonTokenDBO$.<init>(SingletonTokenDBO.scala:34) ~[habari.jar:8.4-QUARTZ-SNAPSHOT]
! at tracelink.misc.SingletonTokenDBO$.<clinit>(SingletonTokenDBO.scala) ~[habari.jar:8.4-QUARTZ-SNAPSHOT]
!... 10 common frames omitted
Caused by: ! java.net.UnknownHostException: 690bd678bcf4: Name or service not known
! at java.net.Inet4AddressImpl.lookupAllHostAddr(Native Method) ~[na:1.8.0_151]
! at java.net.InetAddress$2.lookupAllHostAddr(InetAddress.java:928) ~[na:1.8.0_151]
! at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1323) ~[na:1.8.0_151]
! at java.net.InetAddress.getLocalHost(InetAddress.java:1500) ~[na:1.8.0_151]
!... 12 common frames omitted

令人不快的Scala代码行是:

代码语言:javascript
复制
  private val machineName = InetAddress.getLocalHost().getHostName()

一些初步研究表明,该错误与容器中/etc/hosts文件的内容有关。因此,我创建了一个小测试程序,它的行为与我的实际应用程序相同,并且还将/etc/hosts的内容转储到stdout:

代码语言:javascript
复制
import java.net.*;
import java.io.*;

public class NetworkTest {
   public static void main(String[] args) throws InterruptedException, IOException, FileNotFoundException {
      while(true) {
         networkDump();
         Thread.sleep(10000);
      }
   }

   private static void networkDump() throws IOException, FileNotFoundException {
      System.out.println("/etc/hosts:");
      System.out.println("");

      FileReader f = new FileReader("/etc/hosts");
      BufferedReader reader = new BufferedReader(f);
      String line = null;
      while((line = reader.readLine()) != null) {
         System.out.println(line);
      }
      System.out.println("");

      dumpHostname();
   }

   private static void dumpHostname() {
      try {
         String hostname = InetAddress.getLocalHost().getHostName();
         System.out.printf("Hostname: %s\n\n", hostname);
      } catch(UnknownHostException e) {
         System.out.println(e.getMessage());
      }
   }
}

Dockerfile:

代码语言:javascript
复制
FROM openjdk:8

WORKDIR /site
ADD . /site

CMD ["java", "NetworkTest"]

我在AWS中得到的输出如下所示:

代码语言:javascript
复制
/etc/hosts:
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

3a5a4271a6e3: 3a5a4271a6e3: Name or service not known

与在本地机器上的docker中运行的输出相比:

代码语言:javascript
复制
> docker run networktest

/etc/hosts:
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.4  82691e2fb948

Hostname: 82691e2fb948

未获得异常的本地版本在/etc/hosts中有一个主机名条目,而AWS hosts文件没有主机名条目。我尝试添加一个/etc/rc.local文件来手动将主机名添加到localhost行的末尾,然后在Dockerfile中添加一个RUN命令来做同样的事情。两者都没有起到任何作用。

有没有人知道是否有一种方法可以配置镜像或ECS任务定义,以便在AWS中正确配置主机名?

EN

回答 4

Stack Overflow用户

发布于 2018-03-08 14:04:59

通过执行以下命令将主机名指向127.0.0.1:

代码语言:javascript
复制
echo "127.0.0.1 $HOSTNAME" >> /etc/hosts

为我修复了这个问题。

我正在使用Docker Compose。所以我有一个这样的docker-compose.yml文件:

代码语言:javascript
复制
version: '2'

services:
  myservice:
    command: ["/set-hostname.sh", "--", "/run-service.sh"]

然后set-hostname.sh文件如下所示:

代码语言:javascript
复制
#!/bin/bash

set -e

shift
cmd="$@"

echo "127.0.0.1 $HOSTNAME" >> /etc/hosts

exec $cmd
票数 5
EN

Stack Overflow用户

发布于 2019-04-12 21:11:42

和我纠结了很长一段时间的问题完全一样。这个解决方案对我很有效:

代码语言:javascript
复制
ENTRYPOINT ["/bin/sh", "-c" , "echo 127.0.0.1 $HOSTNAME >> /etc/hosts && exec mvn spring-boot:run"]
票数 3
EN

Stack Overflow用户

发布于 2018-04-26 19:44:24

所以,我遇到了完全相同的问题,问题是,正如您已经提到的,主机名没有多大意义。获取VPC中可见的实际实例IP的唯一方法是使用AWS任务元数据API,在我的例子中我就是这样做的。https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-metadata-endpoint.html

我编写了以下代码来获取localhost IP:

代码语言:javascript
复制
try {
            final ResponseEntity<String> taskInfoResponse = this.restTemplate.getForEntity("http://169.254.170.2/v2/metadata", String.class);
            log.info("Got AWS task info: {}", taskInfoResponse);
            log.info("Got AWS task info: {}", taskInfoResponse.getBody());
            if (taskInfoResponse.getStatusCode() == HttpStatus.OK) {
                try {
                    final ObjectNode jsonNodes = this.objectMapper.readValue(taskInfoResponse.getBody(), ObjectNode.class);
                    final JsonNode jsonNode = jsonNodes.get("Containers")
                            .get(0).get("Networks")
                            .get(0)
                            .get("IPv4Addresses").get(0);
                    log.info("Got IP to use: {}", jsonNode);
                    if (jsonNode != null) {
                        awsTaskInfo.setTaskAddress(InetAddress.getByName(jsonNode.asText()));
                    }
                } catch (IOException e) {
                    throw new IllegalArgumentException(e);
                }
            } else {
                awsTaskInfo.setTaskAddress(InetAddress.getLoopbackAddress());
            }
        }catch (ResourceAccessException e){
            log.error("Failed to fetch AWS info", e);
            awsTaskInfo.setTaskAddress(InetAddress.getLoopbackAddress());
        }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48508480

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档