Spring Cloud基于Docker进行打包部署4-容器间的连接和通信(单主机环境)

今天部署项目发现只有当配置中心config server完全启动后,config client才能正常启动,但是我没想出来怎么判断一个java应用完全启动完成。我想的办法是将config server应用的管理放在单独的一个名为docker-compose-base. yml的文件中,执行docker-compose -f docker-compose-base.yml up去构建镜像并启动config server容器,之后再sh脚本中sleep一段时间,再去执行包含其他应用的docker compose配置文件。但是,据说根据不同配置文件启动的容器之间是网络隔离的,今天就来探究下这个问题:

问题描述:如何设置容器间的连接(包括两种情况 1 :容器定义在同一个配置文件中,2 :容器定义在不同配置文件中)。

答案:
1、StackOverFlow网站相关资料:
在同一个docker-compose.yml文件中的不同容器设置连接,使用links参数,如下: Use links when you want to link together containers within the same docker-compose.yml. All you need to do is set the link to the service name. Like this:
---
elasticsearch:
  image: elasticsearch:latest
  command: elasticsearch -Des.network.host=0.0.0.0
  ports:
    - "9200:9200"

logstash:
  image: logstash:latest
  command: logstash -f logstash.conf
  ports:
    - "5000:5000"
  links:
    - elasticsearch

连接不同docker-compose.yml中的容器,需要使用external_links参数,设置目标容器的名字。

If you want to link a container inside of the docker-compose.yml to another container that was not included in the same docker-compose.yml or started in a different manner then you can use external_links and you would set the link to the container's name. Like this:

---
logstash:
  image: logstash:latest
  command: logstash -f logstash.conf
  ports:
    - "5000:5000"
  external_links:
    - my_elasticsearch_container

建议把应用放在同一个docker-compose.yml文件中

I would suggest the first way unless your use case for some reason requires that they cannot be in the same docker-compose.yml

2、51CTO网站相关资料:

容器定义在同一个docker-compose.yml文件中的情况与上边一样,来看在不同yml文件中的情况:

方式:让需要链接的容器同属一个外部网络

我们还是使用nginx镜像来模拟这样的一个情景:假设我们需要将两个使用Docker Compose管理的nignx容器( test1 和 test2 )链接起来,使得 test2 能够访问 test1 中提供的服务,这里我们以能ping通为准。

首先,我们定义容器 test1 的 docker-compose.yml 文件内容为:

version: "3" 
services: 
  test2: 
  image: nginx 
  container_name: test1 
  networks: 
    - default 
    - app_net 
networks: 
  app_net: 
  external: true 

容器 test2 内容与 test1 基本一样,只是多了一个 external_links ,需要特别说明的是: 最近发布的Docker版本已经不需要使用external_links来链接容器,容器的DNS服务可以正确的作出判断 ,因此如果你你需要兼容较老版本的Docker的话,那么容器 test2 的 docker-compose.yml文件内容为
version: "3" 
services: 
  test2: 
  image: nginx 
  networks: 
    - default 
    - app_net 
  external_links: 
    - test1 
  container_name: test2 
networks: 
  app_net: 
  external: true 

否则的话, test2 的 docker-compose.yml 和 test1 的定义完全一致,不需要额外多指定一个 external_links 。

正如你看到的那样,这里两个容器的定义里都使用了同一个外部网络 app_net ,因此,我们需要在启动这两个容器之前通过以下命令再创建外部网络:

docker network create app_net 
之后,通过 docker-compose up -d 命令启动这两个容器,然后执行 docker exec -it test2 ping test1 ,可以看到两者是可以ping通的。

证明这两个容器是成功链接了,反过来在 test1 中ping test2 也是能够正常ping通的。

如果我们通过 docker run --rm --name test3 -d nginx 这种方式来先启动了一个容器( test3 )并且没有指定它所属的外部网络,而需要将其与 test1 或者 test2 链接的话,这个时候手动链接外部网络即可:

docker network connect app_net test3 

这样,三个容器都可以相互访问了。

重点来了

在以上两篇资料的基础上集合docker的特性我们得到几个有效信息:

(1)在docker的新版本中,已经不需要使用external_links来链接容器,容器的DNS服务可以正确的作出判断 。还有,links也不需要设置了。

(2)使用docker-compose up命令时,如果docker-compose.yml文件中没有配置网络,docker会生成一个默认的网络,而且同一个文件夹下的docker compose配置文件使用的是同一个网络名为  "文件夹名_default"。

所以在项目中如果需要定义两个docker compose的配置文件,可以把两个文件放在同一个文件夹下,那么就不需要自定义网络,也不需要写links或者external_links配置就可以实现所有容器间的互通了。

后记:

实现容器按顺序启动,需要用到depends_on

但是会有一个问题:depends_on只保证启动顺序,而我们的实际需求是:config client容器启动的commands必须等到config server完全启动,config client容器的command才可以执行。我们可以加如restart: always,这样的话config client容器会不断重启直到config server容器启动完成。

你可能感兴趣的:(微服务)