docker attach와 docker exec의 차이점


82

둘 다 컨테이너에서 명령을 실행할 수 있습니다. 둘 다 컨테이너를 분리 할 수 ​​있습니다.

그렇다면 docker exec와 docker attach의 실제 차이점은 무엇입니까?

답변:


85

문서에 추가 된 커밋 PR 이 있습니다.

참고 : 이 명령 ( attach)은 컨테이너에서 새 프로세스를 실행하기위한 것이 아닙니다. 참조 : docker exec.

" Docker. 실행 된 컨테이너 ( run -d)에서 bash \ ssh를 얻는 방법 ? "에 대한 대답 은 차이점을 보여줍니다.

(고정 표시기> = 1.3) 우리가 사용하는 경우 docker attach, 우리는 쉘의 한 인스턴스를 사용할 수 있습니다 .
따라서 컨테이너 셸의 새 인스턴스로 새 터미널을 열려면 다음을 실행하면됩니다.docker exec

도커 컨테이너가 /bin/bash명령을 사용하여 시작된 경우 연결을 사용하여 액세스 할 수 있습니다. 그렇지 않은 경우 명령을 실행 하여를 사용하여 컨테이너 내부에 bash 인스턴스를 만들어야합니다 exec.

이번 호 에서 언급했듯이 :

  • 연결은 컨테이너에서 추가 작업을 실행하기위한 것이 아니라 실행중인 프로세스에 연결하기위한 것입니다.
  • " docker exec"은 이미 시작된 컨테이너에서 새로운 것을 실행하기위한 것입니다. 셸이든 다른 프로세스이든 상관 없습니다.

동일한 문제가 추가됩니다.

동안은 attach물론 특히 때문에 LXC 명령의 명명되지 않은 lxc-attach(더 가깝다 docker exec <container> /bin/sh, 그러나 LXC 특정)는 말 그대로 도커 시작하는 과정에 당신을 연결의 특정 목적을 가지고있다.
프로세스가 무엇인지에 따라 동작이 다를 수 있습니다. 예를 들어에 연결 /bin/bash하면 셸이 제공되지만 redis-server에 연결하면 데몬 화하지 않고 바로 redis를 시작한 것과 같습니다.


24

컨테이너가 / bin / bash를 사용하여 시작되면 컨테이너 PID 1이 되고 docker attach는 컨테이너의 PID 1 내부에 들어가는 데 사용됩니다. 따라서 docker attach <container-id> 는 컨테이너를 시작하는 동안 언급했듯이 PID 1이므로 bash 터미널 내부로 이동합니다. 컨테이너에서 나가면 컨테이너가 중지됩니다.

에 반면 고정 표시기 간부 명령을 지정할 수있는 당신이에 입력 할 쉘있다. 컨테이너의 PID 1로 이동하지 않습니다. bash에 대한 새 프로세스를 생성합니다. docker exec -it <container-id> bash . 컨테이너에서 나가도 컨테이너가 중지되지는 않습니다.

nsenter 를 사용 하여 컨테이너 내부에 들어갈 수도 있습니다 . nsenter -m -u -n -p -i -t <pid of container> 다음을 사용하여 컨테이너의 PID를 찾을 수 있습니다. docker inspect <container-id> | grep PID

참고 : -d 플래그로 컨테이너를 시작한 경우 컨테이너를 종료해도 내부로 들어가기 위해 attach 또는 exec를 사용하더라도 컨테이너가 중지되지 않습니다.


사용에 대한 흥미로운 아이디어 nsenter. 자세히 설명해 주시겠습니까? 옵션을 설명하는 것이 순서입니다. 모든 네임 스페이스를 입력하지 않는 이유는 무엇입니까? 왜이 특별한 것입니까?
x-yuri 19

7

Michael Sun이 그의 대답에서 말했듯이

docker exec컨테이너 환경에서 새로운 명령을 실행 / 새 프로세스 생성, 컨테이너 docker attach내부의 메인 프로세스 (PID 1 포함)의 표준 입 / 출력 / 오류를 현재 터미널 (터미널)의 해당 표준 입 / 출력 / 오류에 연결하기 만하면됩니다. 명령을 실행하는 데 사용하고 있습니다).

내 대답은 위의 진술을 확인하고 더 명확하게 이해하는 데 더 중점을 둘 것입니다.

터미널 창을 열고 명령을 실행합니다 docker run -itd --name busybox busybox /bin/sh. 이 명령은 이미지 busybox가 아직없는 경우 가져옵니다 . 그런 다음 busybox이 이미지를 사용 하여 이름으로 컨테이너를 만듭니다 .

명령을 실행하여 컨테이너의 상태를 확인할 수 있습니다 docker ps -a | grep busybox.

를 실행 docker top busybox하면 다음과 같은 출력이 표시됩니다.

UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                7469                7451                0                   11:40               pts/0               00:00:00            /bin/sh

물론 PID, PPID및 기타 값은 귀하의 경우에 다릅니다. 당신은뿐만 아니라 같은 다른 도구와 유틸리티를 사용할 수 있습니다 pstree, top, htop의 목록을 확인 PID하고 PPID.

PIDPPID프로세스 ID와 부모 프로세스 ID를 의미한다. 이 프로세스는 명령을 사용하여 컨테이너를 만들고 시작했을 때 시작되었습니다 /bin/sh. 이제 명령을 실행하십시오 docker attach busybox. 그러면 컨테이너의 표준 입력 / 출력 / 오류 스트림이 터미널에 연결됩니다.

컨테이너를 연결 한 후 명령을 실행하여 셸 세션을 만듭니다 sh. CTRL-p CTRL-q순서를 누르십시오 . 이렇게하면 컨테이너에서 터미널이 분리되고 컨테이너가 계속 실행됩니다. 이제를 실행 docker top busybox하면 목록에 두 개의 프로세스가 표시됩니다.

UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                7469                7451                0                   11:40               pts/0               00:00:00            /bin/sh
root                7737                7469                0                   11:43               pts/0               00:00:00            sh

그러나 PPID두 프로세스는 다를 것입니다. 실제로 PPID두 번째 프로세스의 프로세스는 PID첫 번째 프로세스와 동일 합니다. 첫 번째 프로세스는 방금 만든 셸 세션의 부모 프로세스 역할을합니다.

이제 docker exec -it busybox sh. 컨테이너 내부 busybox에서 명령을 실행하여 다른 터미널 창에서 컨테이너 에 대해 실행중인 프로세스 목록을 확인합니다 docker top busybox. 다음과 같은 것이 보일 것입니다.

UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                7469                7451                0                   11:40               pts/0               00:00:00            /bin/sh
root                7737                7469                0                   11:43               pts/0               00:00:00            sh
root                7880                7451                0                   11:45               pts/1               00:00:00            sh

PPID첫 번째 및 세 번째 과정은 어떤 확인한다 같은 것 docker exec중에 용기의 환경에서 새로운 프로세스를 생성 docker attach단지 현재의 표준 입력 / 출력 / 에러 대응하는 콘테이너 내의 주요 프로세스의 표준 입력 / 출력 / 오류 연결 단말기.


5

Docker exec는 컨테이너 환경에서 새 명령을 실행 / 새 프로세스를 생성하는 반면, docker attach는 컨테이너 내부의 기본 프로세스 (PID 1 포함)의 표준 입력 / 출력 / 오류를 해당 표준 입력 / 출력 / 전류 오류에 연결합니다. 터미널 (명령을 실행하는 데 사용하는 터미널).

컨테이너는 일부 프로세스가 환경에서 실행되는 격리 된 환경입니다. 특히 컨테이너에는 호스트 및 기타 컨테이너와 분리 된 자체 파일 시스템 공간과 PID 공간이 있습니다. 컨테이너가 "docker run –it…"을 사용하여 시작되면 주 프로세스는 pseudo-tty와 STDIN이 열린 상태로 유지됩니다. tty 모드에서 연결되면 구성 가능한 키 시퀀스를 사용하여 컨테이너에서 분리 (실행 상태로 두는) 할 수 있습니다. 기본 시퀀스는 CTRL-p CTRL-q입니다. --detach-keys 옵션 또는 구성 파일을 사용하여 키 시퀀스를 구성합니다. Docker 연결을 사용하여 분리 된 컨테이너에 다시 연결할 수 있습니다.

Docker exec는 컨테이너의 환경 내, 즉 컨테이너의 PID 공간에 속하는 새 프로세스를 시작합니다.

예를 들어 "docker run –dit XXX / bin / bash"를 사용하여 컨테이너를 시작하면 두 개의 다른 터미널을 사용하여 컨테이너 (의 기본 프로세스)에 연결할 수 있습니다. 한 터미널에 입력하는 동안 두 터미널이 동일한 tty에 연결되어 있기 때문에 다른 터미널에 나타나는 것을 볼 수 있습니다. 이제 컨테이너의 주요 프로세스에 있다는 점에주의하세요. "exit"를 입력하면 컨테이너가 종료되고 ( 주의, 분리 키를 사용하여 분리 ) 두 터미널이 모두 종료 된 것을 볼 수 있습니다. 그러나 두 터미널에서 "docker exec –it XXX / bin / bash"를 실행하면 컨테이너 내부에서 두 개의 새로운 프로세스를 시작한 것입니다. 두 프로세스는 서로 관련이없고 기본 프로세스와 관련이 없으며 안전하게 종료 할 수 있습니다. .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.