在Docker容器中杀死一个分叉的进程,让容器在Jenkins docker slave插件上退出

我使用docker来build立和testing。 在testing过程中,我的testing用例将启动一个单独的进程(mongod进程),testing用例完成后将终止该进程。 在整个testing用例运行期间, mongod进程会被生成并被杀死很多次。 我遇到的问题是当mongod进程被终止,docker容器退出,代码137.我的docker文件如下:

 FROM ubuntu RUN sed -i -e 's/us.archive.ubuntu.com/archive.ubuntu.com/g' /etc/apt/sources.list && apt-get update && apt-get install -y curl RUN apt-get update && apt-get install -y --no-install-recommends \ openssh-client openssh-server rsync vim \ dh-autoreconf libcurl4-gnutls-dev libexpat1-dev gettext libz-dev libssl-dev \ && curl -OL https://github.com/git/git/archive/v2.13.1.tar.gz \ && tar -zxf v2.13.1.tar.gz && cd git-2.13.1 && make configure && ./configure --prefix=/usr && make all && make install && cd .. \ && apt-get remove -y dh-autoreconf libcurl4-gnutls-dev libexpat1-dev gettext libz-dev libssl-dev \ && rm -rf v2.13.1.tar.gz git-2.13.1 \ && rm -rf /var/lib/apt/lists/* RUN echo "unsafe-perm = true" > /root/.npmrc \ && echo "Australia/Melbourne" > /etc/timezone # && dpkg-reconfigure -f noninteractive tzdata RUN curl -sL https://deb.nodesource.com/setup_7.x | bash - && apt-get install -y nodejs && npm install -g yarn RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential \ python \ python-pip python-dev \ && rm -rf /var/lib/apt/lists/* \ && yarn global add node-gyp && pip install --upgrade pip && pip install setuptools RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6 \ && echo "deb http://repo.mongodb.org/apt/debian jessie/mongodb-org/3.4 main" | tee /etc/apt/sources.list.d/mongodb-org-3.4.list RUN apt-get update && apt-get install -y --no-install-recommends \ mongodb-org \ python-pip python-dev \ && pip install mtools pymongo numpy \ && rm -rf /var/lib/apt/lists/* USER root RUN adduser jenkins RUN chmod 777 /home/jenkins ADD ./.aws /home/jenkins/.aws USER jenkins 

我使用下面的命令启动mongod进程:

 mongod --dbpath /home/jenkins/.jenkins/data/db --logpath /home/jenkins/.jenkins/data/mongod.log --port 27017 --logappend --fork 

我在本地运行项目testing用例没有问题。 所以我认为这涉及到docker。 我的docker运行在CoreOS 。 版本是:

 $ docker --version Docker version 17.05.0-ce, build 89658be 

这个容器由jenkins docker slave插件启动。 经过一番调查,如果我通过docker run -it -d $NAME bash手动启动容器,但如果容器由Jenkins docker slave启动,则工作不正常。 我不知道哪个启动命令可能会导致这个问题。 我怎样才能解决这个问题,而不改变docker发射器命令?

以下是docker inspect输出:

 [ { "Id": "81ffad4b15115077dda23c221eb8053915f41cdf0e75de4417d23f81df12f87f", "Created": "2017-07-28T01:08:40.598084613Z", "Path": "/trampoline", "Args": [ "wait" ], "State": { "Status": "running", "Running": true, "Paused": false, "Restarting": false, "OOMKilled": false, "Dead": false, "Pid": 14152, "ExitCode": 0, "Error": "", "StartedAt": "2017-07-28T01:08:41.044051569Z", "FinishedAt": "0001-01-01T00:00:00Z" }, "Image": "sha256:7d1e60ecf32337654f46c54b05e3db11f724f12c4f879ccd42c9566c59edc6b2", "ResolvConfPath": "/var/lib/docker/containers/097e51587d94fa0282ee51f6b84c006a6a410aadb2891f24b25caf41a1d14f39/resolv.conf", "HostnamePath": "/var/lib/docker/containers/097e51587d94fa0282ee51f6b84c006a6a410aadb2891f24b25caf41a1d14f39/hostname", "HostsPath": "/var/lib/docker/containers/097e51587d94fa0282ee51f6b84c006a6a410aadb2891f24b25caf41a1d14f39/hosts", "LogPath": "/var/lib/docker/containers/81ffad4b15115077dda23c221eb8053915f41cdf0e75de4417d23f81df12f87f/81ffad4b15115077dda23c221eb8053915f41cdf0e75de4417d23f81df12f87f-json.log", "Name": "/heuristic_ritchie", "RestartCount": 0, "Driver": "overlay2", "MountLabel": "system_u:object_r:svirt_lxc_file_t:s0:c896,c995", "ProcessLabel": "system_u:system_r:svirt_lxc_net_t:s0:c896,c995", "AppArmorProfile": "", "ExecIDs": [ "a827e4666391224dc9b3e7f94ea3a7615fb5215c82de6a481289fa125bf9495f" ], "HostConfig": { "Binds": null, "ContainerIDFile": "", "LogConfig": { "Type": "json-file", "Config": {} }, "NetworkMode": "container:097e51587d94fa0282ee51f6b84c006a6a410aadb2891f24b25caf41a1d14f39", "PortBindings": {}, "RestartPolicy": { "Name": "no", "MaximumRetryCount": 0 }, "AutoRemove": false, "VolumeDriver": "", "VolumesFrom": [ "097e51587d94fa0282ee51f6b84c006a6a410aadb2891f24b25caf41a1d14f39" ], "CapAdd": null, "CapDrop": null, "Dns": [], "DnsOptions": [], "DnsSearch": [], "ExtraHosts": null, "GroupAdd": null, "IpcMode": "container:097e51587d94fa0282ee51f6b84c006a6a410aadb2891f24b25caf41a1d14f39", "Cgroup": "", "Links": null, "OomScoreAdj": 0, "PidMode": "", "Privileged": false, "PublishAllPorts": false, "ReadonlyRootfs": false, "SecurityOpt": [ "label=user:system_u", "label=role:system_r", "label=type:svirt_lxc_net_t", "label=level:s0:c896,c995" ], "UTSMode": "", "UsernsMode": "", "ShmSize": 67108864, "Runtime": "runc", "ConsoleSize": [ 0, 0 ], "Isolation": "", "CpuShares": 0, "Memory": 4294967296, "NanoCpus": 0, "CgroupParent": "", "BlkioWeight": 0, "BlkioWeightDevice": null, "BlkioDeviceReadBps": null, "BlkioDeviceWriteBps": null, "BlkioDeviceReadIOps": null, "BlkioDeviceWriteIOps": null, "CpuPeriod": 0, "CpuQuota": 0, "CpuRealtimePeriod": 0, "CpuRealtimeRuntime": 0, "CpusetCpus": "", "CpusetMems": "", "Devices": [], "DeviceCgroupRules": null, "DiskQuota": 0, "KernelMemory": 0, "MemoryReservation": 0, "MemorySwap": 8589934592, "MemorySwappiness": -1, "OomKillDisable": false, "PidsLimit": 0, "Ulimits": null, "CpuCount": 0, "CpuPercent": 0, "IOMaximumIOps": 0, "IOMaximumBandwidth": 0 }, "GraphDriver": { "Data": { "LowerDir": "/var/lib/docker/overlay2/bf2b1c63a0862bcc09c3a126e41b6658b60178ade943a8844780a24b01cf2f7c-init/diff:/var/lib/docker/overlay2/be89c1495150690fd934ba56411d144f7de43d06d268fe4b2d0e12552bab6b31/diff:/var/lib/docker/overlay2/d222b270a29034ff81603a80776dd05a259369dcb721515bb2ad08039e9327f1/diff:/var/lib/docker/overlay2/0f1c10959b14c67f2776cd5696a8281f514a42505ec2e0aab759f8543f0e6eed/diff:/var/lib/docker/overlay2/adfec4e3f9b8b1252520f8a56ee27d4cf5fb3f3a01dae344c9932f5bda7d732f/diff:/var/lib/docker/overlay2/e350f5d2bcc4252a5f067eb72b5ad65c6c620178347373736e1308c35e0a17d3/diff:/var/lib/docker/overlay2/2ed71b40ecf304222f071b0ccfc14f10dbd7566de01d16ff80169dea80dd72d4/diff:/var/lib/docker/overlay2/1b20e86eb201191ce6fd4d904f1bfd95fe3423bd6d083cd763c7995a518c9e23/diff:/var/lib/docker/overlay2/35c6c2859ec66d741643c7f9ff47e8513504e7560ea63369f671b305a66edaa1/diff:/var/lib/docker/overlay2/50e277363a9f73f105e6a60edb47c257b04f8383e4575e0cb67e6d628148c305/diff:/var/lib/docker/overlay2/3163f8c2fc0c94623b3390178b5d9de9938d2e9399df0f0341384f8d0fc75761/diff:/var/lib/docker/overlay2/1dc179342c7786f88e98fd68f72dcb187d8524b203ce6122158cf68d94df3a3a/diff:/var/lib/docker/overlay2/f3f749adb1ea12915a0bc1b6258682cbf7571288656325152784b02039b56fd1/diff:/var/lib/docker/overlay2/deb0c7c423d5f685db5213536810c71fae89fee553d830f6a7cfba3b29853097/diff", "MergedDir": "/var/lib/docker/overlay2/bf2b1c63a0862bcc09c3a126e41b6658b60178ade943a8844780a24b01cf2f7c/merged", "UpperDir": "/var/lib/docker/overlay2/bf2b1c63a0862bcc09c3a126e41b6658b60178ade943a8844780a24b01cf2f7c/diff", "WorkDir": "/var/lib/docker/overlay2/bf2b1c63a0862bcc09c3a126e41b6658b60178ade943a8844780a24b01cf2f7c/work" }, "Name": "overlay2" }, "Mounts": [ { "Name": "46705245e5a0a71c14665c843a34ee349f19b4cc0efeed655e9b3575b0b83a3d", "Source": "/var/lib/docker/volumes/46705245e5a0a71c14665c843a34ee349f19b4cc0efeed655e9b3575b0b83a3d/_data", "Destination": "/home/jenkins/.jenkins", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" } ], "Config": { "Hostname": "097e51587d94", "Domainname": "", "User": "10000:10000", "AttachStdin": false, "AttachStdout": true, "AttachStderr": true, "Tty": false, "OpenStdin": false, "StdinOnce": false, "Env": [ "TMPDIR=/home/jenkins/.jenkins/.tmp", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "NPM_CONFIG_LOGLEVEL=info", "NODE_VERSION=7.10.0", "YARN_VERSION=0.24.4" ], "Cmd": [ "/trampoline", "wait" ], "Image": "jenkins-mongo-3.4", "Volumes": null, "WorkingDir": "/home/jenkins/.jenkins", "Entrypoint": null, "OnBuild": null, "Labels": { "maintainer": "zhaoyi0113@gmail.com" } }, "NetworkSettings": { "Bridge": "", "SandboxID": "", "HairpinMode": false, "LinkLocalIPv6Address": "", "LinkLocalIPv6PrefixLen": 0, "Ports": {}, "SandboxKey": "", "SecondaryIPAddresses": null, "SecondaryIPv6Addresses": null, "EndpointID": "", "Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAddress": "", "IPPrefixLen": 0, "IPv6Gateway": "", "MacAddress": "", "Networks": {} } } ] 

而不是使用mongod进程作为pid1,而是使用supervisor 。

因此,使用主pipe启动mongodb(如果需要的话,您的testing本身并不真正开始)。

这样,您的testing可以使用以下方法轻松启动/停止进程:

supervisorctl stop mongod并使用supervisorctl start mongod重新启动它

停止mongod服务将不会退出容器,因为supervisord是pid1

如果你想让testing使用二进制文件来启动它,你不需要PID跟踪和连接,你可以使用busyscript作为PID,然后使用testing在容器中启动mongod进程。

总线看起来像这样

 #!/bin/sh #set -x pid=0 # SIGTERM-handler term_handler() { if [ $pid -ne 0 ]; then kill -SIGTERM "$pid" wait "$pid" fi exit 143; # 128 + 15 -- SIGTERM } # setup handlers # on callback, kill the last background process, which is `tail -f /dev/null` and execute the specified handler trap 'kill ${!}; term_handler' SIGTERM echo "Started DW php code" # wait forever while true do tail -f /dev/null & wait ${!} done 

或者,更多的努力,但可能是docker的方式将用于容器。 一个是你的testing运行者与一个主机安装dockersockets。 这个人将运行testing并启动mongod contaienr并且随意杀死,所以基本上testing会杀死/ rm mongod容器而不是进程本身 – 然后再次启动容器。