Docker Swarm 集群中的套接字端口未打开(已确定根本原因)
Socket port not opening in Docker Swarm Cluster (Root Cause Identified)
我有以下设置
- 两个虚拟机
- 创建覆盖网络
创建了两个 docker 集群服务
docker 服务创建 --name karaf1-service --replicas 1 --network karaf_net karaf1:2.0.0
docker 服务创建 --name karaf2-service --replicas 1 --network karaf_net karaf2:2.0.0
现在这些容器在启动时打开套接字端口,我观察了一段时间它能够成功地创建它,但很多时候它都失败了。
ServerSocketFactory.getDefault().createServerSocket(serverPort)
如果两个容器都在一个节点上启动,则大多数情况下是成功的,但是当容器在不同节点上创建时,几乎每次都会失败。
在解决网络问题之前,容器至少应该创建套接字。
此容器无法打开套接字
root@bd48643080b2:/opt/apache/apache-karaf-4.1.5# netstat -tulnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:8101 0.0.0.0:* LISTEN 61/java
tcp 0 0 127.0.0.1:1099 0.0.0.0:* LISTEN 61/java
tcp 0 0 0.0.0.0:41551 0.0.0.0:* LISTEN 61/java
tcp 0 0 127.0.0.11:44853 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:44444 0.0.0.0:* LISTEN 61/java
以下容器能够在端口 4550 上创建它,但有时反之亦然
root@38d26c7dde1a:/opt/apache/apache-karaf-4.1.5# netstat -tulnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:37347 0.0.0.0:* LISTEN 61/java
tcp 0 0 0.0.0.0:8101 0.0.0.0:* LISTEN 61/java
tcp 0 0 0.0.0.0:4550 0.0.0.0:* LISTEN 61/java
tcp 0 0 127.0.0.11:37575 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:1099 0.0.0.0:* LISTEN 61/java
tcp 0 0 127.0.0.1:35321 0.0.0.0:* LISTEN 61/java
tcp 0 0 0.0.0.0:44444 0.0.0.0:* LISTEN 61/java
已确定根本原因:
因为我正在创建两个服务,所以在创建第一个服务时,我将第二个服务作为主机名提供给第一个服务以保持验证状态,因此 java 在主机名上抛出错误,如 "karaf2-service"
java.net.UnknownHostException: karaf2-service: Name or service not known
at java.net.Inet4AddressImpl.lookupAllHostAddr(Native Method)
at java.net.InetAddress.lookupAllHostAddr(InetAddress.java:928)
现在我无法在 etc/hosts 中添加 karaf2-service 条目,所以套接字不要抱怨,因为我不知道哪个 IP 将分配给 docker-swarm 服务?在覆盖网络中,我们主要通过服务名称进行通信。
有什么解决这个问题的建议吗???
最简单的方法是在容器启动时检查是否可以访问其他服务,如果不能,请等待几秒钟,然后重试。
有多种工具可以做到这一点,例如 wait-for-it:https://github.com/vishnubob/wait-for-it
我有以下设置
- 两个虚拟机
- 创建覆盖网络
创建了两个 docker 集群服务
docker 服务创建 --name karaf1-service --replicas 1 --network karaf_net karaf1:2.0.0
docker 服务创建 --name karaf2-service --replicas 1 --network karaf_net karaf2:2.0.0
现在这些容器在启动时打开套接字端口,我观察了一段时间它能够成功地创建它,但很多时候它都失败了。
ServerSocketFactory.getDefault().createServerSocket(serverPort)
如果两个容器都在一个节点上启动,则大多数情况下是成功的,但是当容器在不同节点上创建时,几乎每次都会失败。
在解决网络问题之前,容器至少应该创建套接字。
此容器无法打开套接字
root@bd48643080b2:/opt/apache/apache-karaf-4.1.5# netstat -tulnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:8101 0.0.0.0:* LISTEN 61/java
tcp 0 0 127.0.0.1:1099 0.0.0.0:* LISTEN 61/java
tcp 0 0 0.0.0.0:41551 0.0.0.0:* LISTEN 61/java
tcp 0 0 127.0.0.11:44853 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:44444 0.0.0.0:* LISTEN 61/java
以下容器能够在端口 4550 上创建它,但有时反之亦然
root@38d26c7dde1a:/opt/apache/apache-karaf-4.1.5# netstat -tulnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:37347 0.0.0.0:* LISTEN 61/java
tcp 0 0 0.0.0.0:8101 0.0.0.0:* LISTEN 61/java
tcp 0 0 0.0.0.0:4550 0.0.0.0:* LISTEN 61/java
tcp 0 0 127.0.0.11:37575 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:1099 0.0.0.0:* LISTEN 61/java
tcp 0 0 127.0.0.1:35321 0.0.0.0:* LISTEN 61/java
tcp 0 0 0.0.0.0:44444 0.0.0.0:* LISTEN 61/java
已确定根本原因: 因为我正在创建两个服务,所以在创建第一个服务时,我将第二个服务作为主机名提供给第一个服务以保持验证状态,因此 java 在主机名上抛出错误,如 "karaf2-service"
java.net.UnknownHostException: karaf2-service: Name or service not known
at java.net.Inet4AddressImpl.lookupAllHostAddr(Native Method)
at java.net.InetAddress.lookupAllHostAddr(InetAddress.java:928)
现在我无法在 etc/hosts 中添加 karaf2-service 条目,所以套接字不要抱怨,因为我不知道哪个 IP 将分配给 docker-swarm 服务?在覆盖网络中,我们主要通过服务名称进行通信。
有什么解决这个问题的建议吗???
最简单的方法是在容器启动时检查是否可以访问其他服务,如果不能,请等待几秒钟,然后重试。
有多种工具可以做到这一点,例如 wait-for-it:https://github.com/vishnubob/wait-for-it