引言
大概是在2016/10前后,我們部門使用docker一段時(shí)間后偶爾會(huì)出現(xiàn)docker exec ... 無(wú)法進(jìn)入容器的問(wèn)題,環(huán)境為centos7.2、docker1.12.6,docker存儲(chǔ)引擎為devicemapper,經(jīng)過(guò)排查發(fā)現(xiàn)容器對(duì)應(yīng)的文件系統(tǒng)已經(jīng)umount,且發(fā)現(xiàn)開發(fā)同學(xué)用了大量的docker restart ... 操作。于是產(chǎn)生docker restart導(dǎo)致容器文件系統(tǒng)umount的疑問(wèn),后面對(duì)docker restart、start、stop三個(gè)命令與容器文件系統(tǒng)關(guān)系做了研究,以下是研究的記錄。
問(wèn)題描述
通過(guò)docker run啟動(dòng)一個(gè)容器后,docker會(huì)同時(shí)掛載該容器的內(nèi)存文件系統(tǒng)與容器的根文件系統(tǒng)(rootfs),比如
/dev/dm-1 10G 147M 9.9G 2% /var/lib/docker/devicemapper/mnt/9bf11bfa99d87e874df9cff2720fdfe03ffe9e9fbb95fabdbf1386f844cfc077
shm 64M 0 64M 0% /var/lib/docker/containers/e536db1a4695ca6c8c41523e736fc92f39840839d5628b3f722fedc1db795436/shm
若容器的根文件系統(tǒng)(rootfs)umount,執(zhí)行 docker exec -it xxx /bin/bash or /bin/sh會(huì)觸發(fā)異常:
rpc error: code = 13 desc = invalid header field value "oci runtime error: exec failed: container_linux.go:247: starting container process caused \"process_linux.go:75: starting setns process caused \\\"fork/exec /proc/self/exe: no such file or directory\\\"\"\n"
同時(shí)執(zhí)行 docker restart xxx會(huì)觸發(fā)異常:
Error response from daemon: Cannot restart container anyrobot-etl: invalid header field value "oci runtime error: rootfs (\"/var/lib/docker/devicemapper/mnt/e512b093e57e257ed7bf5cc451c24e08e7ae4823e46657af1e160c2a029357e2/rootfs\") does not exist\n"
查看containerRestart函數(shù)執(zhí)行的流程



查看containerStart函數(shù)執(zhí)行的流程



查看containerStop函數(shù)的源碼

查看docker debug日志信息
分別查看docker restart、start、stop三個(gè)命令的debug信息,這里的實(shí)踐環(huán)境為:centos7.2、docker1.12.6、存儲(chǔ)引擎(storage-driver):devicemapper、鏡像:nginx:1.12
- 創(chuàng)建nginx容器
docker run -itd --name nginx nginx:1.12
nginx容器對(duì)應(yīng)的根文件系統(tǒng)與內(nèi)存文件系統(tǒng)mount信息分別為:
/dev/dm-1 10G 147M 9.9G 2% /var/lib/docker/devicemapper/mnt/86f8de453061f09db6eebebacb4a439bfa2f5afa3d202b98f55887c13bdfa0da
shm 64M 0 64M 0% /var/lib/docker/containers/6d3286762568ae0535908de12382f2789a77b8e4faa1fd76a30e981f00f4d34f/shm
nginx容器對(duì)應(yīng)的塊設(shè)備為dm-1
- docker stop nginx,系統(tǒng)日志輸出:
Nov 2 16:09:14 node dockerd: time="2016-11-02T16:09:14.846401331+08:00" level=debug msg="Calling POST /v1.24/containers/nginx/stop?t=10"
Nov 2 16:09:14 node dockerd: time="2016-11-02T16:09:14.846470393+08:00" level=debug msg="Sending 15 to 6d3286762568ae0535908de12382f2789a77b8e4faa1fd76a30e981f00f4d34f"
Nov 2 16:09:14 node dockerd: time="2016-11-02T16:09:14.853533994+08:00" level=debug msg="containerd: process exited" id=6d3286762568ae0535908de12382f2789a77b8e4faa1fd76a30e981f00f4d34f pid=init status=0 systemPid=121294
Nov 2 16:09:14 node dockerd: time="2016-11-02T16:09:14.861900485+08:00" level=debug msg="libcontainerd: received containerd event: &types.Event{Type:\"exit\", Id:\"6d3286762568ae0535908de12382f2789a77b8e4faa1fd76a30e981f00f4d34f\", Status:0x0, Pid:\"init\", Timestamp:(*timestamp.Timestamp)(0xc820ef9d30)}"
Nov 2 16:09:14 node dockerd: time="2016-11-02T16:09:14.862344401+08:00" level=debug msg="Revoking external connectivity on endpoint nginx (7b98d117889d1c01a21a7ca674e64a785b792bec135f66c6fb365168b193b3e6)"
Nov 2 16:09:14 node dockerd: time="2016-11-02T16:09:14.862964952+08:00" level=warning msg="failed to close stdin: rpc error: code = 2 desc = containerd: container not found"
Nov 2 16:09:14 node kernel: docker0: port 1(vethe871091) entered disabled state
Nov 2 16:09:14 node kernel: docker0: port 1(vethe871091) entered disabled state
Nov 2 16:09:14 node kernel: device vethe871091 left promiscuous mode
Nov 2 16:09:14 node kernel: docker0: port 1(vethe871091) entered disabled state
Nov 2 16:09:14 node dockerd: time="2016-11-02T16:09:14.885060892+08:00" level=debug msg="Releasing addresses for endpoint nginx's interface on network bridge"
Nov 2 16:09:14 node dockerd: time="2016-11-02T16:09:14.885104751+08:00" level=debug msg="ReleaseAddress(LocalDefault/172.17.0.0/16, 172.17.0.2)"
Nov 2 16:09:14 node dockerd: time="2016-11-02T16:09:14.888964154+08:00" level=debug msg="devmapper: UnmountDevice(hash=86f8de453061f09db6eebebacb4a439bfa2f5afa3d202b98f55887c13bdfa0da)"
Nov 2 16:09:14 node dockerd: time="2016-11-02T16:09:14.888997975+08:00" level=debug msg="devmapper: Unmount(/var/lib/docker/devicemapper/mnt/86f8de453061f09db6eebebacb4a439bfa2f5afa3d202b98f55887c13bdfa0da)"
Nov 2 16:09:14 node kernel: XFS (dm-1): Unmounting Filesystem
Nov 2 16:09:14 node dockerd: time="2016-11-02T16:09:14.911053057+08:00" level=debug msg="devmapper: Unmount done"
Nov 2 16:09:14 node dockerd: time="2016-11-02T16:09:14.911106735+08:00" level=debug msg="devmapper: deactivateDevice(86f8de453061f09db6eebebacb4a439bfa2f5afa3d202b98f55887c13bdfa0da)"
Nov 2 16:09:14 node dockerd: time="2016-11-02T16:09:14.911192040+08:00" level=debug msg="devmapper: removeDevice START(docker-202:1-1589930-86f8de453061f09db6eebebacb4a439bfa2f5afa3d202b98f55887c13bdfa0da)"
Nov 2 16:09:14 node dockerd: time="2016-11-02T16:09:14.919197718+08:00" level=debug msg="devmapper: removeDevice END(docker-202:1-1589930-86f8de453061f09db6eebebacb4a439bfa2f5afa3d202b98f55887c13bdfa0da)"
Nov 2 16:09:14 node dockerd: time="2016-11-02T16:09:14.919246950+08:00" level=debug msg="devmapper: deactivateDevice END(86f8de453061f09db6eebebacb4a439bfa2f5afa3d202b98f55887c13bdfa0da)"
Nov 2 16:09:14 node dockerd: time="2016-11-02T16:09:14.919259532+08:00" level=debug msg="devmapper: UnmountDevice(hash=86f8de453061f09db6eebebacb4a439bfa2f5afa3d202b98f55887c13bdfa0da) END"
Nov 2 16:09:17 node ntpd[473]: Deleting interface #42 vethe871091, fe80::3cb6:deff:fe0e:9bda#123, interface stats: received=0, sent=0, dropped=0, active_time=220 secs
有文件系統(tǒng)umount的操作信息
- docker start nginx,系統(tǒng)日志輸出:
Nov 2 16:12:18 node dockerd: time="2016-11-02T16:12:18.559834721+08:00" level=debug msg="Calling POST /v1.24/containers/nginx/start"
Nov 2 16:12:18 node dockerd: time="2016-11-02T16:12:18.560447373+08:00" level=debug msg="devmapper: activateDeviceIfNeeded(86f8de453061f09db6eebebacb4a439bfa2f5afa3d202b98f55887c13bdfa0da)"
Nov 2 16:12:18 node kernel: XFS (dm-1): Mounting V5 Filesystem
Nov 2 16:12:18 node kernel: XFS (dm-1): Ending clean mount
Nov 2 16:12:18 node dockerd: time="2016-11-02T16:12:18.590744411+08:00" level=debug msg="container mounted via layerStore: /var/lib/docker/devicemapper/mnt/86f8de453061f09db6eebebacb4a439bfa2f5afa3d202b98f55887c13bdfa0da/rootfs"
Nov 2 16:12:18 node dockerd: time="2016-11-02T16:12:18.590914625+08:00" level=debug msg="Assigning addresses for endpoint nginx's interface on network bridge"
Nov 2 16:12:18 node dockerd: time="2016-11-02T16:12:18.590938496+08:00" level=debug msg="RequestAddress(LocalDefault/172.17.0.0/16, <nil>, map[])"
Nov 2 16:12:18 node kernel: device veth1a44a92 entered promiscuous mode
Nov 2 16:12:18 node kernel: IPv6: ADDRCONF(NETDEV_UP): veth1a44a92: link is not ready
Nov 2 16:12:18 node kernel: docker0: port 1(veth1a44a92) entered forwarding state
Nov 2 16:12:18 node kernel: docker0: port 1(veth1a44a92) entered forwarding state
Nov 2 16:12:18 node kernel: docker0: port 1(veth1a44a92) entered disabled state
Nov 2 16:12:18 node dockerd: time="2016-11-02T16:12:18.601330774+08:00" level=debug msg="Assigning addresses for endpoint nginx's interface on network bridge"
Nov 2 16:12:18 node dockerd: time="2016-11-02T16:12:18.608483995+08:00" level=debug msg="Programming external connectivity on endpoint nginx (d5ceb98ca54865a44156310cf4e3f7f3df2c5a74646598552cbd4f78e8ff2b4e)"
Nov 2 16:12:18 node kernel: IPv6: ADDRCONF(NETDEV_CHANGE): veth1a44a92: link becomes ready
Nov 2 16:12:18 node kernel: docker0: port 1(veth1a44a92) entered forwarding state
Nov 2 16:12:18 node kernel: docker0: port 1(veth1a44a92) entered forwarding state
Nov 2 16:12:18 node dockerd: time="2016-11-02T16:12:18.669534147+08:00" level=debug msg="sandbox set key processing took 7.06337ms for container 6d3286762568ae0535908de12382f2789a77b8e4faa1fd76a30e981f00f4d34f"
Nov 2 16:12:18 node dockerd: time="2016-11-02T16:12:18.726420146+08:00" level=debug msg="libcontainerd: received containerd event: &types.Event{Type:\"start-container\", Id:\"6d3286762568ae0535908de12382f2789a77b8e4faa1fd76a30e981f00f4d34f\", Status:0x0, Pid:\"\", Timestamp:(*timestamp.Timestamp)(0xc820f34350)}"
Nov 2 16:12:18 node dockerd: time="2016-11-02T16:12:18.729815704+08:00" level=debug msg="libcontainerd: event unhandled: type:\"start-container\" id:\"6d3286762568ae0535908de12382f2789a77b8e4faa1fd76a30e981f00f4d34f\" timestamp:<seconds:1546416738 nanos:724341305 > "
Nov 2 16:12:21 node ntpd[473]: Listen normally on 43 veth1a44a92 fe80::c8c8:65ff:fe20:7b01 UDP 123
Nov 2 16:12:33 node kernel: docker0: port 1(veth1a44a92) entered forwarding state
有文件系統(tǒng)的mount操作信息
- docker restart nginx,系統(tǒng)日志輸出:
Nov 2 16:13:50 node dockerd: time="2016-11-02T16:13:50.463384463+08:00" level=debug msg="Calling POST /v1.24/containers/nginx/restart?t=10"
Nov 2 16:13:50 node dockerd: time="2016-11-02T16:13:50.463476842+08:00" level=debug msg="container mounted via layerStore: /var/lib/docker/devicemapper/mnt/86f8de453061f09db6eebebacb4a439bfa2f5afa3d202b98f55887c13bdfa0da/rootfs"
Nov 2 16:13:50 node dockerd: time="2016-11-02T16:13:50.463550127+08:00" level=debug msg="Sending 15 to 6d3286762568ae0535908de12382f2789a77b8e4faa1fd76a30e981f00f4d34f"
Nov 2 16:13:50 node dockerd: time="2016-11-02T16:13:50.470408535+08:00" level=debug msg="containerd: process exited" id=6d3286762568ae0535908de12382f2789a77b8e4faa1fd76a30e981f00f4d34f pid=init status=0 systemPid=122202
Nov 2 16:13:50 node dockerd: time="2016-11-02T16:13:50.479775109+08:00" level=debug msg="libcontainerd: received containerd event: &types.Event{Type:\"exit\", Id:\"6d3286762568ae0535908de12382f2789a77b8e4faa1fd76a30e981f00f4d34f\", Status:0x0, Pid:\"init\", Timestamp:(*timestamp.Timestamp)(0xc820f34d60)}"
Nov 2 16:13:50 node dockerd: time="2016-11-02T16:13:50.480243393+08:00" level=debug msg="Revoking external connectivity on endpoint nginx (d5ceb98ca54865a44156310cf4e3f7f3df2c5a74646598552cbd4f78e8ff2b4e)"
Nov 2 16:13:50 node dockerd: time="2016-11-02T16:13:50.480852093+08:00" level=warning msg="failed to close stdin: rpc error: code = 2 desc = containerd: container not found"
Nov 2 16:13:50 node kernel: docker0: port 1(veth1a44a92) entered disabled state
Nov 2 16:13:50 node kernel: docker0: port 1(veth1a44a92) entered disabled state
Nov 2 16:13:50 node kernel: device veth1a44a92 left promiscuous mode
Nov 2 16:13:50 node kernel: docker0: port 1(veth1a44a92) entered disabled state
Nov 2 16:13:50 node dockerd: time="2016-11-02T16:13:50.499758603+08:00" level=debug msg="Releasing addresses for endpoint nginx's interface on network bridge"
Nov 2 16:13:50 node dockerd: time="2016-11-02T16:13:50.499800548+08:00" level=debug msg="ReleaseAddress(LocalDefault/172.17.0.0/16, 172.17.0.2)"
Nov 2 16:13:50 node kernel: device veth4fb623e entered promiscuous mode
Nov 2 16:13:50 node kernel: IPv6: ADDRCONF(NETDEV_UP): veth4fb623e: link is not ready
Nov 2 16:13:50 node kernel: docker0: port 1(veth4fb623e) entered forwarding state
Nov 2 16:13:50 node kernel: docker0: port 1(veth4fb623e) entered forwarding state
Nov 2 16:13:50 node dockerd: time="2016-11-02T16:13:50.508096957+08:00" level=debug msg="container mounted via layerStore: /var/lib/docker/devicemapper/mnt/86f8de453061f09db6eebebacb4a439bfa2f5afa3d202b98f55887c13bdfa0da/rootfs"
Nov 2 16:13:50 node dockerd: time="2016-11-02T16:13:50.508248137+08:00" level=debug msg="Assigning addresses for endpoint nginx's interface on network bridge"
Nov 2 16:13:50 node dockerd: time="2016-11-02T16:13:50.508274138+08:00" level=debug msg="RequestAddress(LocalDefault/172.17.0.0/16, <nil>, map[])"
Nov 2 16:13:50 node dockerd: time="2016-11-02T16:13:50.518255720+08:00" level=debug msg="Assigning addresses for endpoint nginx's interface on network bridge"
Nov 2 16:13:50 node dockerd: time="2016-11-02T16:13:50.525383372+08:00" level=debug msg="Programming external connectivity on endpoint nginx (fb933f68c93990950cdec7d41a001568e5342a7d935f17f48fd07b077d9a91ad)"
Nov 2 16:13:50 node kernel: IPv6: ADDRCONF(NETDEV_CHANGE): veth4fb623e: link becomes ready
Nov 2 16:13:50 node dockerd: time="2016-11-02T16:13:50.585250711+08:00" level=debug msg="sandbox set key processing took 5.83763ms for container 6d3286762568ae0535908de12382f2789a77b8e4faa1fd76a30e981f00f4d34f"
Nov 2 16:13:50 node dockerd: time="2016-11-02T16:13:50.635658245+08:00" level=debug msg="libcontainerd: received containerd event: &types.Event{Type:\"start-container\", Id:\"6d3286762568ae0535908de12382f2789a77b8e4faa1fd76a30e981f00f4d34f\", Status:0x0, Pid:\"\", Timestamp:(*timestamp.Timestamp)(0xc820eef780)}"
Nov 2 16:13:50 node dockerd: time="2016-11-02T16:13:50.638449684+08:00" level=debug msg="libcontainerd: event unhandled: type:\"start-container\" id:\"6d3286762568ae0535908de12382f2789a77b8e4faa1fd76a30e981f00f4d34f\" timestamp:<seconds:1546416830 nanos:634697526 > "
Nov 2 16:13:53 node ntpd[473]: Listen normally on 44 veth4fb623e fe80::982c:ecff:fe44:47f2 UDP 123
Nov 2 16:13:53 node ntpd[473]: Deleting interface #43 veth1a44a92, fe80::c8c8:65ff:fe20:7b01#123, interface stats: received=0, sent=0, dropped=0, active_time=92 secs
并沒(méi)有文件系統(tǒng)的umount與mount的操作信息。
通過(guò)上面的日志輸出可以了解到
- docker start ... 包含容器文件系統(tǒng)掛載的操作
- docker stop ... 包含容器文件系統(tǒng)卸載的操作
- docker restart ... 不包含容器文件系統(tǒng)的卸載與掛載操作,本質(zhì)上docker restart不涉及文件系統(tǒng)的操作,因此restart命令并不是stop與start兩個(gè)命令的順序疊加。
結(jié)論
分析發(fā)現(xiàn),docker restart命令并不是stop、start兩個(gè)命令的順序疊加,docker restart操作并不涉及容器文件系統(tǒng)的處理,開始懷疑的由于docker restart操作導(dǎo)致容器的文件系統(tǒng)處于umount狀態(tài)此處沒(méi)有找到證據(jù),但為了保證容器的根文件系統(tǒng)與內(nèi)存系統(tǒng)mount的正確性,推薦對(duì)一個(gè)容器的重啟使用docker stop xxx 然后 docker start xxx,而非docker restart xxx。