我正在尝试将一个卷添加到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_missive-mongo_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_missive-mongo_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_missive-mongo_1 sh
。这次我发现文件夹存在,但不是卷内容:
/ # ls /var/log
mongodb
/ # ls /var/log/mongodb/
/ #
这很奇怪,因为到目前为止,远程Docker / Compose配置中卷的可靠性一直是典范。
目前我的主要版本是Docker和Docker Compose的不同版本可能与它有关。所以我会列出我的内容:
apk
进行安装)docker:17.05.0-ce-git
图片,版本显示为Docker version 17.05.0-ce, build 89658be
docker-compose version 1.13.0, build 1719ceb
。因此,存在一些版本差异。作为一个在黑暗中的镜头,我可以试着碰到Docker / Compose,虽然我对打破其他事情很谨慎。
虽然是理想的,但是我可以使用某种高级Docker命令来调试为什么卷似乎已注册但未在容器内公开。有什么想法吗?
答案 0 :(得分:3)
CircleCI runs docker-compose
remotely from the Docker daemon所以本地绑定挂载不起作用。
named volume将默认为local
驱动程序,并且可以在CircleCI的Compose设置中运行,该卷将存在于容器运行的任何位置。
通常应将记录留给每个容器设置的单个进程中的stdout和stderr。然后,您可以使用logging driver plugin运送到中央收集器。 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守护程序和日志服务器之间,而不是容器到容器之间。
答案 1 :(得分:2)
我想在接受的答案中添加一个额外的答案。我在CircleCI上的用例是运行基于浏览器的集成测试,以检查整个堆栈是否正常工作。正在使用的11个容器中有许多是为各种事物定义的,例如日志输出和原始数据库文件存储。
直到现在我还没有意识到,由于技术Docker限制,CircleCI的Docker执行程序中的卷不起作用。由于此失败,在以前的每种情况下,文件都只写入空文件夹。
然而,在我的新案例中,这个问题导致Mongo失败。原因是我使用<ActionBar title="Groceries">
<!-- On iOS devices, <ActionItem>s are placed from left to right in sequence; you can override that (as the code above does) by providing an ios.position attribute. -->
<ActionItem text="Share" (tap)="share()" android.systemIcon="ic_menu_share_holo_dark" ios.systemIcon="9" ios.position="right"></ActionItem>
</ActionBar>
<GridLayout rows="auto, *">
<!-- add-bar necessary since we moved the page up 20 over the status bar on iOS-->
<GridLayout row="0" columns="*, auto" class="add-bar">
<TextField #groceryTextField [(ngModel)]="grocery" hint="Enter a grocery item" (returnPress)="add()" col="0"></TextField>
<Image src="res://add" (tap)="add()" col="1"></Image>
</GridLayout>...
来阻止Mongo在启动时执行自己的日志轮换,并且此开关要求--logappend
中指定的路径存在。由于它存在于主机上,但是卷创建失败,容器无法看到日志文件。
要解决此问题,我已修改我的Mongo服务条目以调用--logpath
部分中的脚本:
command
脚本看起来像这样:
missive-mongo:
image: missive-mongo
command: sh /root/mongo-logging.sh
在两个可能的用例中,这将按如下方式执行:
无论哪种方式,这都是一个很好的安全功能,可以防止Mongo爆炸。