실행중인 컨테이너에서 쉘 세션을 시작할 수 있습니까 (ssh없이)


341

나는이 명령이 실행중인 컨테이너에서 bash 쉘을 실행할 것으로 순진하게 기대했다.

docker run "id of running container" /bin/bash

불가능한 것 같습니다. 오류가 발생합니다.

2013/07/27 20:00:24 Internal server error: 404 trying to fetch remote history for 27d757283842

따라서 실행중인 컨테이너에서 bash 쉘을 실행하려면 (예 : 진단 목적으로)

SSH 서버를 실행하고 ssh를 통해 로그인해야합니까?


1
docker run CONTAINER1.0
예정일

7
고정 표시기 1.3 이후 당신은 진짜로에 설명 할해야 이 답변
Thomasleveil

1
그냥docker attach container_name
maxbellec

1
요즘 두 번째 답변이 기존 답변보다 훨씬 낫습니다. 수락 된 답변을 다시 고려할 수 있습니까?
jsbueno 2016 년

답변:


285

편집 : 이제 사용할 수 있습니다 docker exec -it "id of running container" bash( doc )

이전에는이 ​​질문에 대한 답변은 다음과 같습니다.

실제로 디버그 환경에 있어야하고이를 수행 할 수있는 경우 다음을 수행 할 수 있습니다 sudo lxc-attach -n <ID> . id는 전체 이름 ( docker ps -notrunc) 이어야합니다 .

그러나 나는 이것을 반대하는 것이 좋습니다.

공지 : -notrunc더 이상 사용되지 않으며 --no-trunc곧 교체 될 예정입니다.


1
왜 그것을 추천하지 않습니까?
Max L.

7
1) 최신 커널이 필요하기 때문에 2) 권장하지 않습니다 .2) 도커 외부에서 작업을 수행하므로 추적 할 수 없습니다 (로그, 첨부 등). 또한 docker는 현재 lxc를 사용할 수 있지만 영원히 그렇게 할 것이라는 보장은 없습니다.
creack

1
0.7.6으로 업데이트하십시오. Docker는 여전히 lxc를 사용하고 lxc-attach있으며 정상적으로 작동합니다. 방금 확인을 두 배로하고 나에게 효과적입니다. 3.8 이전의 커널에서는 작동하지 않습니다.
creack

2
기본적으로 0.9 도커는 LXC에서 더 이상 실행되지 않습니다. 다음과 같이 docker deamon을 시작해야합니다.docker -d -e lxc
kevzettler

2
Max L., 사용 사례는 데이터 볼륨 으로 해결할 수 있습니다 . 테스트되지 않은 예 : 1) 데이터 볼륨에 nginx 로그가있는 컨테이너를 실행합니다. docker run -v /var/log/nginx -name somename imagename command; 2) 다른 컨테이너를 실행하여 데이터 볼륨 내용을 봅니다 docker run -volumes-from somename -i -t busybox /bin/sh..
ciastek

615

docker 1.3에는 새로운 명령이 docker exec있습니다. 이렇게하면 실행중인 도커에 들어갈 수 있습니다.

docker exec -it "id of running container" bash

2
이것은 나를 위해 잘 작동했습니다. 도커 실행에 매우 도움이됩니다.
oraserrata

실행중인 컨테이너를 실행하는 동안 변경 한 후 온라인에서 변경 사항을 반영하려면 어떻게합니까? 모범 사례는 무엇입니까?
mediaroot

굉장히 유용하다. 감사합니다
luongnv89

docker ps실행중인 인스턴스의 ID를 얻는 데 사용
muon

참고 : 컨테이너에 bash가 없을 수 있습니다 (»exec : "bash": 실행 파일을 찾을 수 없습니다«). 사용 docker inspect <image>가능한 쉘을 확인하는 데 사용 하십시오. 예를 들어 docker exec -it <container id> /bin/sh대신 실행하십시오 .
pixelbrackets

14

그냥 해

docker attach container_name

주석에서 언급했듯이 컨테이너를 중지하지 않고 분리하려면 Ctrlpthen을 입력하십시오 Ctrlq.


5
감사!! 도움이되었습니다. 그리고 실제 질문과 관련하여 무언가를 추가하고 싶습니다. 사용하여 우리의 용기를 디버깅 한 후 docker attach container_name사용 ctrl p하고 ctrl q대신 exit. exit명령으로 컨테이너 중지 ctrlp하고 ctrl q그냥 컨테이너를 분리하고 실행 유지
피닉스를

10

상황이 바뀌기 때문에 현재 실행중인 컨테이너에 액세스하는 권장 방법은 nsenter입니다.

github 저장소 에 대한 자세한 정보를 찾을 수 있습니다 . 그러나 일반적으로 다음과 같이 nsenter를 사용할 수 있습니다.

PID=$(docker inspect --format {{.State.Pid}} <container_name_or_ID>)
nsenter --target $PID --mount --uts --ipc --net --pid

또는 래퍼를 사용할 수 있습니다 docker-enter.

docker-enter <container_name_or_ID>

이 주제에 대한 좋은 설명은 Jérôme Petazzoni의 블로그 항목에서 찾을 수 있습니다. 도커 컨테이너에서 sshd를 실행할 필요가없는 이유


불행히도 env 변수는이 방법을 사용하여 엉망이됩니다 (링크로 만든 변수를 확인하려는 경우). 나는 할 것을 제안한다 source /proc/*/environ.
Tomas Tomecek

8

가장 먼저 달릴 수없는 것

docker run "existing container" command

이 명령은 컨테이너가 아닌 이미지를 기대하고 있기 때문에 새로운 컨테이너가 생성됩니다 (따라서보고 싶지 않은)

도커를 사용하면 다른 방식으로 생각하도록 스스로를 밀어야한다는 사실에 동의하지만 (컨테이너에 로그온 할 필요가없는 방법을 찾아야 함) 여전히 유용하다는 것을 알았습니다. 그 주위에.

DEAMON 모드에서 감독자를 통해 명령을 실행합니다.

그런 다음 내가 부르는 것을 실행합니다 docker_loop.sh . 내용은 거의 다음과 같습니다.

#!/bin/bash
/usr/bin/supervisord
/usr/bin/supervisorctl
while ( true )
    do
    echo "Detach with Ctrl-p Ctrl-q. Dropping to shell"
    sleep 1
    /bin/bash
done

컨테이너에 "연결"하고 supervisorctl로그를 중지 / 시작 / 다시 시작 및 확인하기 위한 인터페이스 가 제공됩니다 . 그것이 충분하지 않으면, 당신은 할 수 Ctrl+D있고 당신은 마치 정상적인 시스템 인 것처럼 주변을 들여다 볼 수있는 껍질에 떨어질 것입니다.

이 시스템이 쉘이없는 컨테이너를 갖는 것만 큼 안전하지 않은지 확인하십시오. 따라서 컨테이너를 고정하는 데 필요한 모든 단계를 수행하십시오.


5

이 풀 요청에 주목하십시오 : https://github.com/docker/docker/pull/7409

다음 docker exec <container_id> <command>유틸리티를 구현 합니다. 이것이 가능할 때, 실행중인 컨테이너 내부에서 ssh 서비스를 시작하고 중지하는 것이 가능해야합니다.

이 또한 nsinit이렇게하려면 "nsinit 실행중인 컨테이너의 네임 스페이스 내부 쉘에 액세스 할 수있는 편리한 방법을 제공합니다" 하지만, 실행 얻을 어려워 보인다. https://gist.github.com/ubergarm/ed42ebbea293350c30a6


docker exec그것을 만들고 실행중인 컨테이너에 새로운 쉘 세션에 참가하는 것이 가능하므로, 도커 1.3에 도착
포즈


1

실제로 컨테이너에 쉘을 넣을 수있는 방법이 있습니다.

/root/run.sh프로세스, 프로세스 관리자 (감독자) 등을 시작 한다고 가정합니다 .

/root/runme.sh일부 gnu- 스크린 트릭으로 작성하십시오 .

# Spawn a screen with two tabs
screen -AdmS 'main' /root/run.sh
screen -S 'main' -X screen bash -l
screen -r 'main'

이제 docker attach컨테이너 0에서 데몬이 있고 탭 1 에서 대화식 쉘이 있어 컨테이너 내부에서 어떤 일이 일어나고 있는지 확인할 수 있습니다.

또 다른 조언은이 스크린 트릭을 포함하여 필요한 모든 도구를 사용하여 프로덕션 이미지 위에 "개발 번들"이미지를 작성하는 것입니다.


1

여기 내 해결책이 있습니다

DOckerfile의 일부 :

...
RUN mkdir -p /opt
ADD initd.sh /opt/
RUN chmod +x /opt/initd.sh
ENTRYPOINT ["/opt/initd.sh"]

"initd.sh"의 일부

#!/bin/bash
...
/etc/init.d/gearman-job-server start
/etc/init.d/supervisor start
#very important!!!
/bin/bash

이미지가 빌드 된 후 exec 및 attach를 사용하는 두 가지 옵션이 있습니다.

  1. exec (내가 사용하는)로 다음을 실행하십시오.

docker run --name $ CONTAINER_NAME -dt $ IMAGE_NAME

그때

docker exec -it $ CONTAINER_NAME / bin / bash

사용

분리 할 Ctrl + D

  1. 첨부하여 다음을 실행하십시오.

docker run --name $ CONTAINER_NAME -dit $ IMAGE_NAME

그때

도커 첨부 $ CONTAINER_NAME

사용

분리 할 Ctrl + P 및 Ctrl + Q

옵션의 차이점은 매개 변수 -i에 있습니다.


1

두 가지 방법이 있습니다.

첨부

$ sudo docker attach 665b4a1e17b6 #by ID

exec로

$ sudo docker exec - -t 665b4a1e17b6 #by ID


0

컨테이너를 실행할 때 이름을 지정하는 것이 유용합니다. container_id를 참조 할 필요는 없습니다.

docker run --name container_name yourimage docker exec -it container_name bash


0

먼저 원하는 컨테이너의 컨테이너 ID를 가져옵니다.

docker ps

당신은 이와 같은 것을 얻을 것입니다 :

CONTAINER ID        IMAGE                  COMMAND             CREATED             STATUS                          PORTS                    NAMES
3ac548b6b315        frontend_react-web     "npm run start"     48 seconds ago      Up 47 seconds                   0.0.0.0:3000->3000/tcp   frontend_react-web_1

이제이 컨테이너 ID를 복사하고 다음 명령을 실행하십시오.

docker exec -it container_id sh

docker exec -it 3ac548b6b315 sh


-2

컨테이너를 개발할 때 VM과 관련하여 생각하는 것처럼 자신이 잘못되었을 수도 있습니다. 내 충고 :하지 마십시오.

컨테이너는 다른 프로세스와 같습니다. 실제로 디버깅 목적으로 (/ proc // env 또는 strace -p 생각) 이들을 "첨부"하고 싶을 때 매우 특별한 경우입니다.

일반적으로 프로세스를 "실행"하기 때문에 구성을 수정하거나 로그를 읽으려면 새 컨테이너를 작성하고 디렉토리를 공유하고 stdout에 기록하여 외부에 로그를 작성하십시오 (Docker 로그가 작동 함). 또는 그런 것.

디버깅 목적으로 쉘을 시작한 다음 코드를 시작한 다음 CTRL-p + CTRL-q를 눌러 쉘을 그대로 두십시오. 이 방법으로 다음을 사용하여 다시 연결할 수 있습니다.

docker attach <container_id>

컨테이너가 예상하지 않은 작업을 수행하여 컨테이너를 디버깅하려면 디버깅을 시도하십시오. /server/596994/how-can-i-de-bug-a-docker-container 초기화


이것은 완전히 잘못되었습니다. 응용 프로그램이 실행중인 LXC 네임 스페이스를 조사 할 수있는 것은 "매우 특별한 경우"가 아니며 모든 개발자에게 공통적 인 일상 활동입니다.
sleepycal

@sleepycal "모든 개발자"는 약간 편향되어 있습니다. 어쨌든 나는 프로세스의 내부 검사를 사용하므로 동일한 내용이 컨테이너에 적용됩니다. 이것이 디버깅의 아이디어입니다. 프로세스에 디버거를 연결합니다 (cli가있을 수 있음). 컨테이너에 "로그인"되었다고 생각하면 여전히 오해의 소지가 있습니다.
estani

-4

아니요. 불가능합니다. supervisord필요한 경우 ssh 서버를 얻는 것과 같은 것을 사용하십시오 . 그래도 나는 그 필요성에 의문을 제기한다.

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