docker-compose link 导致服务不可用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了docker-compose link 导致服务不可用相关的知识,希望对你有一定的参考价值。

参考技术A

问题是这样的,一般我们在写 docker-compose.yaml 中的 service 时,service 之间可以通过 service 名称进行互相访问,如果使用名称进行服务间访问,docker 还会在底层提供负载的作用。

这里可以看到 docker 的内嵌 dns 为我们的 who 服务作了负载。

这里添加了一个 links

这里可以看到两次返回的 ip 是一样的,可以测试多次应该是得到都是同一个 ip。

可以再打开一个终端停止刚开始的容器

然后再去 ping 一下 who 的服务

那这里就发生的事情就很奇怪了,居然 ping 不通了。

这里可以推断出 docker compose 启动的时候就已经将 who 服务和它的 ip 写到 busybox 中,所以对于 busybox 来说只会和第一个启动的 who 绑定,也没有走 docker 内嵌的 dns 服务。

很多文章指出是直接将容器名和 ip 写到 /etc/hosts 中

我这里测试出来的结果是 32cee21646a5 是 busybox的 container id,172.20.0.3 是 busybox 的 ip,这里并没有找到 who 的对应关系,所以网上的一些文章应该是有误的。

我甚至用 tcpdump 去抓网卡对应的dns 解析的包

但是这个问题终究还是没有找到根本原因,可能需要去 docker 的内嵌 dns 解析的实现中去查找结果。

等后续。。。

构建Docker Compose服务堆栈

1.安装了docker-compose,现在我们要使用docker-compose来运行容器栈。这个地方会有两个容器,一个容器中使用Flask搭建的简单应用,另一个容器是Redis,Flash会向redis写入数据。因此设计到容器之间的通信。之前我们讲到了,容器之间通信可以使用--link,也可以使用docker networking的方式,那这节课,我们讲解使用docker-compose来更加方便的管理多容器栈。

2.创建composeapp目录

$ cd /home/xm6f/dev/
$ mkdir composeapp
$ cd composeapp
$ touch Dockerfile

Dockerfile中保存用于构建Docker镜像的指令;还要创建app.py文件,这个文件中编写Flask代码。

app.py文件内容:

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
# 导入 Flask 和 Redis 模块
from flask import Flask
from redis import Redis
import os
# 创建 Flask app
app = Flask(__name__)
# 通过 host 连接到 Redis
redis = Redis(host="redis",port=6379)
# 指定访问路径
@app.route(\'/\')
def hi():
  redis.incr("ping")
  return \'hi , you have ping {0} times\'.format(redis.get(\'ping\'))
if __name__ == \'__main__\':
  app.run(host="0.0.0.0",debug=True)

 

创建requirements.txt文件,里面放置程序依赖名称:

flask
redis

 

创建Dockerfile文件,用于构建镜像:

# 指定基镜像为 python2.7
FROM python
MAINTAINER ruthless 416501600@qq.com
ADD . /composeapp
WORKDIR /composeapp
RUN pip install -r requirements.txt

 

$ ls
app.py Dockerfile requirements.txt

 

使用docker build -t composeapp . 指令创建composeapp镜像。

$ docker build -t composeapp .
$ docker images

 

redis镜像我们就不自己制作了,直接使用Docker Hub上面默认的redis即可,获取redis镜像如下:

$ docker search redis
$ docker pull redis

 

3.编写docker-compose.yml文件
应用镜像都构建好了之后,就可以配置compose来创建服务了,compose通过一个约定格式的配置文件配置要启动的服务,每个服务可以选择配置适当的属性,这些属性和docker run命令需要的参数类似。所有的服务和属性都定义在YAML(一种标记语言)文件中,定义好了之后执行docker-compose up命令,compose服务将会根据docker-compose.yml文件启动服务。

创建docker-compose.yml文件
$ touch docker-compose.yml

docker-compose.yml文件中包括一个或者多个要运行的docker容器指令。

web: ##启动容器的名字
    image: composeapp ##从哪个镜像启动
    command: python app.py ##启动运行之后,执行哪些命令
    ports:
        - "5000:5000"
    volumes:
        - .:/composeapp ##当前目录挂载到composeapp目录
    links:
        - redis
        
redis:
    image: redis

在docker-compose.yml文件中,
image其实也可以指定为Dockerfile文件的路径,
通过command指定服务启动时要执行的命令,类似于Dockerfile中的CMD指令,
使用ports指定端口映射,
使用volumes指定卷,
使用links指定要连接到哪些服务。
这个地方是将redis和web服务进行性连接,类似于docker run命令里面的--link选项。

编辑好docker-compose.yml文件之后,使用docker-compose up命令在docker-compose.yml所在目录执行。compose即上传并开始解析定义在docker-compose.yml文件中的指令。

从运行打印的日志可以看到,compose创建了composeapp_redis_1、composeapp_web_1两个服务,这两个服务的名字是docker-compose.yml所在目录的名字加上docker-compose.yml文件中指定的名字再加上一个数字组成,其目的是保证服务的唯一性。

4.可以使用-d选项,以守护方式运行compose
$ docker-compose up -d

5.查看日志信息
$ docker-compose ps
$ docker-compose logs web
$ docker-compose logs redis

6.使用docker-compose port web 5000 查看web服务5000端口映射情况
$ docker-compose port web 5000
0.0.0.0:5000

注意:操作docker-compose命令要跟docker-compose.yml在同一目录,否则无法操作。

7.网页访问web计数器

刷新浏览器,times会依次递增

 

以上是关于docker-compose link 导致服务不可用的主要内容,如果未能解决你的问题,请参考以下文章

微服务架构 - 解决Docker-Compose服务编排启动顺序问题

使用主机 DNS 服务器的 Docker-compose 容器

构建Docker Compose服务堆栈

docker-compose 使用

docker-compose容器中redis权限问题

Docker学习总结(57)——Docker-compose 的portsexposelinksdepends_on的使用技巧