为什么我的Docker卷在远程生成框中不工作?

为什么我的Docker卷在远程生成框中不工作?,docker,docker-compose,circleci,docker-volume,Docker,Docker Compose,Circleci,Docker Volume,我正在尝试将卷添加到Docker容器中,该容器将在托管构建服务(CircleCI)上的Docker Compose系统中构建和运行。它可以在本地正常工作,但不能远程工作。CircleCI提供了一个SSH工具,我可以使用它来调试容器为何不能按预期运行 Docker Compose文件的相关部分如下: missive-mongo: image: missive-mongo command: mongod -v --logpath /var/log/mongodb/mongodb.

我正在尝试将卷添加到Docker容器中,该容器将在托管构建服务(CircleCI)上的Docker Compose系统中构建和运行。它可以在本地正常工作,但不能远程工作。CircleCI提供了一个SSH工具,我可以使用它来调试容器为何不能按预期运行

Docker Compose文件的相关部分如下:

  missive-mongo:
    image: missive-mongo
    command: mongod -v --logpath /var/log/mongodb/mongodb.log --logappend
    volumes:
    - ${MONGO_LOCAL}:/data/db
    - ${LOGS_LOCAL_PATH}/mongo:/var/log/mongodb
    networks:
    - storage_network
在本地,如果我执行了
docker inspect integration\u missive-mongo\u 1
(即运行的容器名称),我将按预期获得卷:

    ...
    "HostConfig": {
        "Binds": [
            "/tmp/missive-volumes/logs/mongo:/var/log/mongodb:rw",
            "/tmp/missive-volumes/mongo:/data/db:rw"
        ],
    ...
在同一个容器上,我可以插入并看到该卷运行良好:

docker exec -it integration_missive-mongo_1 sh
/ # tail /var/log/mongodb/mongodb.log 
2017-11-28T22:50:14.452+0000 D STORAGE  [initandlisten] admin.system.version: clearing plan cache - collection info cache reset
2017-11-28T22:50:14.452+0000 I INDEX    [initandlisten] build index on: admin.system.version properties: { v: 2, key: { version: 1 }, name: "incompatible_with_version_32", ns: "admin.system.version" }
2017-11-28T22:50:14.452+0000 I INDEX    [initandlisten]      building index using bulk method; build may temporarily use up to 500 megabytes of RAM
2017-11-28T22:50:14.452+0000 D INDEX    [initandlisten]      bulk commit starting for index: incompatible_with_version_32
2017-11-28T22:50:14.452+0000 D INDEX    [initandlisten]      done building bottom layer, going to commit
2017-11-28T22:50:14.454+0000 I INDEX    [initandlisten] build index done.  scanned 0 total records. 0 secs
2017-11-28T22:50:14.455+0000 I COMMAND  [initandlisten] setting featureCompatibilityVersion to 3.4
2017-11-28T22:50:14.455+0000 I NETWORK  [thread1] waiting for connections on port 27017
2017-11-28T22:50:14.455+0000 D COMMAND  [PeriodicTaskRunner] BackgroundJob starting: PeriodicTaskRunner
2017-11-28T22:50:14.455+0000 D COMMAND  [ClientCursorMonitor] BackgroundJob starting: ClientCursorMonitor
好的,现在来看看远程。我启动了一个构建,它失败了,因为Mongo无法启动,所以我使用SSH工具在构建失败后保持一个盒子的活动状态

我首先对DC文件进行黑客攻击,这样它就不会尝试启动Mongo,因为它会失败。我只是让它休眠:

  missive-mongo:
    image: missive-mongo
    command: sleep 1000
    volumes:
    - ${MONGO_LOCAL}:/data/db
    - ${LOGS_LOCAL_PATH}/mongo:/var/log/mongodb
    networks:
    - storage_network
然后,我运行
docker compose up
脚本来启动所有容器,然后检查有问题的框:
docker inspect integration\u commissive-mongo\u 1

    "HostConfig": {
        "Binds": [
            "/tmp/missive-volumes/logs/mongo:/var/log/mongodb:rw",
            "/tmp/missive-volumes/mongo:/data/db:rw"
        ],
看起来不错。因此,我在主机上创建了一个虚拟日志文件,并列出它以证明它存在:

bash-4.3# ls /tmp/missive-volumes/logs/mongo
mongodb.log
因此,我再次尝试输入,
docker exec-it integration\u-missive-mongo\u 1 sh
。这次我发现文件夹存在,但卷内容不存在:

/ # ls /var/log
mongodb
/ # ls /var/log/mongodb/
/ #
这是非常奇怪的,因为到目前为止,远程Docker/Compose配置中的卷的可靠性一直堪称典范

理论 我目前的主要观点是Docker和Docker Compose的不同版本可能与此有关。因此,我将列出我拥有的:

  • 本地的
    • 主持人:LinuxMint
    • Docker版本1.13.1,内部版本092cba3
    • docker compose版本1.8.0,构建未知
  • 遥远的
    • 主机:我怀疑它是Alpine(它使用
      apk
      进行安装)
    • 我正在使用CircleCI提供的
      docker:17.05.0-ce-git
      图像,版本显示为
      docker版本17.05.0-ce,构建89658be
    • Docker Composer是通过Pip安装的,获得该版本将生成
      Docker compose 1.13.0版,build 1719ceb
所以,有一些版本的差异。作为一个黑暗中的镜头,我可以尝试增加Docker/Compose,尽管我担心破坏其他东西

理想的情况是,我可以使用某种高级Docker命令来调试为什么卷似乎已注册但未在容器中公开。有什么想法吗?

因此本地绑定挂载不起作用

A将默认为
本地
驱动程序,并将在CircleCI的Compose设置中工作,卷将存在于容器运行的任何位置

在每个容器设置的单个进程中,日志记录通常应该留给stdout和stderr。然后,您可以使用发送到中央收集器。MongoDB在前台运行时默认记录到stdout/stderr

结合卷和日志记录:

version: "2.1"

services:

  syslog:
    image: deployable/rsyslog
    ports:
      - '1514:1514/udp'
      - '1514:1514/tcp'

  mongo:
    image: mongo
    command: mongod -v
    volumes:
      - 'mongo_data:/data/db'
    depends_on:
      - syslog
    logging:
      options:
        tag: '{{.FullID}} {{.Name}}'
        syslog-address: "tcp://10.8.8.8:1514"
      driver: syslog

volumes:
  mongo_data:

这是一个小问题,因为日志端点通常是外部的,而不是同一组中的容器。这就是日志使用外部地址和端口映射来访问syslog服务器的原因。此连接在docker守护程序和日志服务器之间,而不是容器到容器之间。

我想添加一个n接受的答案附带的其他答案。我在CircleCI上的用例是运行基于浏览器的集成测试,以检查整个堆栈是否正常工作。在使用的11个容器中,有许多容器为各种内容定义了卷,例如日志输出和原始数据库文件存储

直到现在我才意识到,由于Docker技术限制,CircleCI的Docker executor中的卷无法工作。由于此故障,在以前的每种情况下,文件都只是写入一个空文件夹

然而,在我的新案例中,这个问题导致Mongo失败。原因是我正在使用
--logappend
来防止Mongo在启动时进行自己的日志旋转,而此开关要求存在
--logpath
中指定的路径。由于它存在于主机上,但卷创建失败,因此容器无法查看日志文件

为了解决这个问题,我修改了我的Mongo服务条目,以调用
命令
部分中的脚本:

  missive-mongo:
    image: missive-mongo
    command: sh /root/mongo-logging.sh
脚本如下所示:

#!/bin/sh
#
# The command sets up logging in Mongo. The touch is for the benefit of any
# environment in which the logs do not already exist (e.g. Integration, since
# CircleCI does not support volumes)

touch /var/log/mongodb/mongodb.log \
    && mongod -v --logpath /var/log/mongodb/mongodb.log --logappend
在两种可能的用例中,其作用如下:

  • 在挂载工作(dev,live)的情况下,如果文件存在,它只需触摸文件,如果文件不存在,则创建文件(例如,一个全新的环境)
  • 如果挂载不工作(CircleCI),它将创建文件

不管怎样,这都是一个很好的安全功能,可以防止Mongo爆炸。

听起来像是。你需要绑定挂载做什么?你可以使用命名卷吗?啊,很好找到@Matt,谢谢-刚刚发布,还有。你的链接很有用,因为它解释了为什么这不起作用。我的用例是在CircleCI上运行集成测试-我带来的安装11个容器,然后运行一些浏览器测试。我不需要安装,因为我可以在这些测试中关闭它。但是,我在live中使用它(将Mongo日志存储在主机上,并与记录器容器共享)因此,我的理想是确保卷的任何故障都会导致集成测试失败。然而,这并不重要,我只想在CircleCI中关闭它(我已经在这个琐碎的任务中工作了好几个小时了);-))。非常棒的Matt,谢谢-我开始有点紧张了。。。不过谢天谢地,它似乎总是会重新长出来。我很感激您对如何安排登录Docker Compose的想法。这可能比我的安排要好——每个容器的所有日志都写入主机上的卷,然后所有卷都与用于