1. 程式人生 > >深入探究docker attach的退出方式

深入探究docker attach的退出方式

標準 部分 enc correct nds ace mage 退出 容器

docker attach可以將當前終端的標準輸入、標準輸出和標準錯誤連接到指定的容器中,可以顯示容器 ENTRYPOINT/CMD 進程的輸出,是容器調試的重要方法。docker attach之後退出的方法,主要有CTRL-c和CTRL-p CTRL-q兩種。大部分說法中,認為CTRL-c會導致容器退出,推薦使用CTRL-p CTRL-q方法。我在實際使用中,發現這些說法並不準確,這兩種方法都會收到docker run和docker attach命令選項的影響。


1. CTRL-c方式

與普通的進程一樣,docker attach之後執行CTRL-c會發送SIGINT信號。
docker attach命令有--sig-proxy選項,man docker attach中對該選項描述如下:

--sig-proxy=true|false
   Proxy all received signals to the process (non-TTY mode only). SIGCHLD, SIGKILL, and SIGSTOP are not proxied. The default is true.

可以看到,該選項僅在non-TTY模式下起作用,即docker run時不指定-t選項。此時,默認--sig-proxy為true,SIGINT信號被發送至docker中PID為1的進程。

doujl@ubuntu:~$ docker run -id centos:7 /bin/bash
edfe9bc8ae02567ff9309ffb6940a9772f02a18d24e4cf04a9da8c84c01e1f52
doujl@ubuntu:
~$ docker attach edfe ^C^C^C
doujl@ubuntu:~$ docker run -d centos:7 top -b
8700417c309d1b6c8e3a1618f38b232e8eddedae20287e73f2022b0cac716248
doujl@ubuntu:~$ docker attach 8700
top - 02:37:24 up 19 days,  1:59,  0 users,  load average: 0.94, 1.03, 1.17
Tasks:   1 total,   1 running,   0 sleeping,   0 stopped,   0 zombie
%Cpu(s): 10.4 us, 2.0 sy, 0.0 ni, 87.2 id, 0.3 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem : 8066788 total, 752956 free, 3659576 used, 3654256 buff/cache KiB Swap: 8282108 total, 7576840 free, 705268 used. 3378516 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1 root 20 0 51780 3576 3132 R 0.0 0.0 0:00.04 top^C doujl@ubuntu:~$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8700417c309d centos:7 "top -b" 11 seconds ago Exited (0) 3 seconds ago pensive_brahmagupta

上面兩個例子中,docker run沒有-t選項,docker attach中--sig-proxy默認為true,將信號發送至容器(SIGCHLD,SIGKILL,SIGSTOP除外)。因此SIGINT發送至PID為1的進程,分別為/bin/bash和top -b。第一個例子,/bin/bash沒有處理SIGINT信號(加上-i是為防止進程退出)。第二個例子中,top -b響應了SIGINT信號並退出,因此容器退出。

如果在docker attach時設置--sig-proxy=false,SIGINT信號不會發送到容器中PID為1的進程,而是被docker attach進程響應

doujl@ubuntu:~$ docker run -id centos:7 /bin/bash
5a6d97406a068b1a58b02d4b3267a974b8c69e268d37db19b44b2858b5086e0f
doujl@ubuntu:~$ docker attach --sig-proxy=false 5a6d
^C
doujl@ubuntu:~$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
5a6d97406a06        centos:7            "/bin/bash"         11 seconds ago      Up 9 seconds                                    reverent_goldstine
doujl@ubuntu:~$ docker run -d centos:7 top -b
37a80db8bf8f8c79bbb910353d04a46697ad54c0bcb4f34f4ef8edd42163d152
doujl@ubuntu:~$ docker attach --sig-proxy=false 37a8
top - 02:42:45 up 19 days,  2:04,  0 users,  load average: 0.58, 0.74, 0.99
Tasks:   1 total,   1 running,   0 sleeping,   0 stopped,   0 zombie
%Cpu(s):  8.2 us,  1.7 sy,  0.0 ni, 90.1 id,  0.1 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  8066788 total,   782360 free,  3642612 used,  3641816 buff/cache
KiB Swap:  8282108 total,  7576848 free,   705260 used.  3405820 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
    1 root      20   0   51780   3668   3224 R   0.0  0.0   0:00.06 top^C
doujl@ubuntu:~$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
37a80db8bf8f        centos:7            "top -b"            15 seconds ago      Up 13 seconds                           tender_kirch

上面兩個例子中,CTRL-c都能退出,但退出的是docker attach進程,容器本身不受影響。

以上的例子中,docker run都沒有-t選項,如果指定了-t選項呢?

doujl@ubuntu:~$ docker run -itd centos:7 /bin/bash
4ff1e8d42537115f46c98eeae6c1554b388cd3322039f8185bb4e3a1848ec519
doujl@ubuntu:~$ docker attach 4ff1
[root@4ff1e8d42537 /]# ^C
[root@4ff1e8d42537 /]# ^C
[root@4ff1e8d42537 /]# 
doujl@ubuntu:~$ docker run -td centos:7 /bin/bash
7a8f3c2ba41b5b4c047dfe4b9d41774cb6972e1e969b38636affd39920b83b2f
doujl@ubuntu:~$ docker attach 7a8f
[root@7a8f3c2ba41b /]# ^C
doujl@ubuntu:~$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
7a8f3c2ba41b        centos:7            "/bin/bash"         18 seconds ago      Up 17 seconds                           peaceful_bose
doujl@ubuntu:~$ docker run -itd centos:7 top -b
829a0f9c9ac70147783d3db9674def5c2179059956923a1d59ccd8a33f339b37
doujl@ubuntu:~$ docker attach 829a
top - 02:49:10 up 19 days,  2:10,  0 users,  load average: 0.55, 0.72, 0.91
Tasks:   1 total,   1 running,   0 sleeping,   0 stopped,   0 zombie
%Cpu(s): 11.5 us,  2.3 sy,  0.0 ni, 86.2 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  8066788 total,   757280 free,  3659324 used,  3650184 buff/cache
KiB Swap:  8282108 total,  7576884 free,   705224 used.  3384468 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
    1 root      20   0   51780   3584   3140 R   0.0  0.0   0:00.05 top

top - 02:49:10 up 19 days,  2:10,  0 users,  load average: 0.55, 0.72, 0.91
Tasks:   1 total,   1 running,   0 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  8066788 total,   757280 free,  3659324 used,  3650184 buff/cache
KiB Swap:  8282108 total,  7576884 free,   705224 used.  3384468 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
    1 root      20   0   51780   3584   3140 R   0.0  0.0   0:00.05 top^C
doujl@ubuntu:~$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
829a0f9c9ac7        centos:7            "top -b"            12 seconds ago      Exited (0) 2 seconds ago                       angry_yonath
doujl@ubuntu:~$ docker run -td centos:7 top -b
79cfe842cfba1b211dea37fafbc5676c9da2ad6e186f261cccee4098ee1dd02a
doujl@ubuntu:~$ docker attach 79cf
top - 02:50:02 up 19 days,  2:11,  0 users,  load average: 0.33, 0.63, 0.87
Tasks:   1 total,   1 running,   0 sleeping,   0 stopped,   0 zombie
%Cpu(s): 10.3 us,  2.8 sy,  0.0 ni, 86.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  8066788 total,   749208 free,  3659560 used,  3658020 buff/cache
KiB Swap:  8282108 total,  7576884 free,   705224 used.  3376832 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
    1 root      20   0   51780   3636   3192 R   0.0  0.0   0:00.05 top

top - 02:50:02 up 19 days,  2:11,  0 users,  load average: 0.33, 0.63, 0.87
Tasks:   1 total,   1 running,   0 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  8066788 total,   749208 free,  3659560 used,  3658020 buff/cache
KiB Swap:  8282108 total,  7576884 free,   705224 used.  3376832 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
    1 root      20   0   51780   3636   3192 R   0.0  0.0   0:00.05 top^C
doujl@ubuntu:~$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
79cfe842cfba        centos:7            "top -b"            9 seconds ago       Up 7 seconds                            loving_ride

可以看到,docker run指定-t選項時,是否指定-i選項也會對docker attach命令有影響。指定-i選項時,SIGINT信號發送到了容器中PID為1的進程,不指定時,信號被docker attach接收。註意,此時docker attach的--sig-proxy選項不起作用。
綜上,docker attach後執行CTRL-c會發送SIGINT信號,而信號的接收方會受到docker run的-i、-t選項,和docker attach的--sig-proxy選項影響。

2. CTRL-p CTRL-q方式

CTRL-p CTRL-q方式比較簡單,只需要註意docker run時要同時指定-it選項。該方式只會退出docker attach,對容器沒有影響

doujl@ubuntu:~$ docker run -itd centos:7 /bin/bash
e73e04370cee90497783a621fd4a044ca196dc419c06a01bae5a4b116d7afc4e
doujl@ubuntu:~$ docker attach e73e
#執行CTRL-p CTRL-q [root@e73e04370cee
/]# doujl@ubuntu:~$ doujl@ubuntu:~$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e73e04370cee centos:7 "/bin/bash" 44 seconds ago Up 42 seconds vibrant_archimedes

如果-it選項沒有同時指定,CTRL-p CTRL-q無法生效

3. 其他退出方式
上面兩種方式在退出時都有限制,有沒有其他方法呢?
其實,我們只要另起一個終端,把docker attach進程殺死就可以了

#終端1中執行,沒有同時指定-it,CTRL-p CTRL-q無法退出
doujl@ubuntu:~$ docker run -id centos:7 /bin/bash
00c031965cb2075643e15a3b88141026e753a79e8b03b960880d505950488014
doujl@ubuntu:~$ docker attach 00c0 ^P /bin/bash: line 1: $\020: command not found ^P
#終端2中殺死docker attach進程
doujl@ubuntu:~/dettach$ pkill -9 -f docker.*attach doujl@ubuntu:~/dettach$
#終端1中,docker attach已退出
/bin/bash: line 2: $\020: command not found
已殺死
doujl@ubuntu:~$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
00c031965cb2        centos:7            "/bin/bash"         About a minute ago   Up About a minute                       trusting_meitner


參考文檔:
1. man docker attach
2. https://docs.docker.com/engine/reference/commandline/attach/
3. https://stackoverflow.com/questions/25267372/correct-way-to-detach-from-a-container-without-stopping-it/45985809#45985809



深入探究docker attach的退出方式