programing

정지된 도커 컨테이너를 다른 명령으로 시작하는 방법?

codeshow 2023. 10. 19. 22:51
반응형

정지된 도커 컨테이너를 다른 명령으로 시작하는 방법?

기본 명령이 충돌하므로 다른 명령으로 정지된 도커 컨테이너를 시작하고 싶습니다. 즉 컨테이너를 시작한 다음 'docker exec'을 사용할 수 없습니다.

기본적으로 용기의 내용물을 검사할 수 있도록 포탄을 시작하고 싶습니다.

운 좋게도 나는 -it 옵션으로 컨테이너를 만들었습니다!

정지된 컨테이너 ID 찾기

docker ps -a

정지된 컨테이너를 커밋합니다.

이 명령은 수정된 컨테이너 상태를 다음 이름의 새 이미지로 저장합니다.user/test_image:

docker commit $CONTAINER_ID user/test_image

다른 진입 지점에서 시작/실행:

docker run -ti --entrypoint=sh user/test_image

진입점 인수 설명:

https://docs.docker.com/engine/reference/run/ #/entrypoint-default-command-to-execute-at-

참고:

위 단계에서는 동일한 파일 시스템 상태로 정지된 컨테이너를 시작합니다.신속한 조사를 위해서는 매우 좋지만, 환경 변수, 네트워크 구성, 첨부 볼륨 등은 상속되지 않습니다.이 모든 인수를 명시적으로 지정해야 합니다.

정지된 컨테이너를 시작하는 단계는 여기서 차용했습니다: (마지막 코멘트) https://github.com/docker/docker/issues/18078

정지된 컨테이너에 해당하는 이 파일을 편집합니다.

vi /var/lib/docker/containers/923...4f6/config.json

/bin/bash와 같이 새 명령을 가리키도록 "Path" 매개 변수를 변경합니다.명령에 인수를 전달하도록 "Args" 매개변수를 설정할 수도 있습니다.

도커 서비스를 다시 시작합니다(라이브 복원을 처음 활성화하지 않는 한 실행 중인 모든 컨테이너가 중지됩니다).

service docker restart

컨테이너를 나열하고 명령이 변경되었는지 확인합니다.

docker ps -a

용기를 시작하고 거기에 붙이세요. 이제 당신은 당신의 껍질 안에 있어야 합니다!

docker start -ai mad_brattain

도커 1.7.1을 사용하여 페도라 22에서 작업했습니다.

참고: 셸이 대화형이 아닌 경우(예: -it 옵션으로 원래 컨테이너를 만들지 않은 경우), 셸을 가져오는 다른 방법으로 "docker exec -it CONTID /bin/bash"를 수행할 시간을 충분히 주기 위해 명령을 "/bin/sleep 600" 또는 "/bin/tail -f /dev/null"로 변경할 수 있습니다.

참고2: 최신 버전의 도커에는 config.v2.json이 있습니다. 엔트리포인트 또는 Cmd를 변경해야 합니다(사용자 60561 감사).

엔트리포인트 스크립트 맨 위에 체크 추가

도커는 이를 새로운 기능으로 구현해야 하지만 성공 또는 실패 후 종료되는 엔트리 포인트가 있는 상황에 대한 또 다른 해결 방법이 있습니다. 이 경우 디버깅이 어려울 수 있습니다.

엔트리포인트 스크립트가 아직 없는 경우 컨테이너에 필요한 모든 명령을 실행하는 스크립트를 만듭니다.그런 다음 이 파일의 맨 위에 줄을 추가합니다.entrypoint.sh:

# Run once, hold otherwise
if [ -f "already_ran" ]; then
    echo "Already ran the Entrypoint once. Holding indefinitely for debugging."
    cat
fi
touch already_ran

# Do your main things down here

확실히 하기 위해서는cat연결을 유지합니다. TTY를 제공해야 할 수도 있습니다.Entrypoint 스크립트를 사용하여 컨테이너를 실행합니다.

docker run -t --entrypoint entrypoint.sh image_name

이렇게 하면 스크립트가 한 번 실행되어 이미 실행되었음을 나타내는 파일이 컨테이너의 가상 파일 시스템에서 생성됩니다.그런 다음 컨테이너를 다시 시작하여 디버깅을 수행할 수 있습니다.

docker start container_name

컨테이너를 다시 시작하면already_ran파일이 발견되어 엔트리포인트 스크립트가 다음과 같이 정지하게 됩니다.cat(이것은 절대 오지 않을 입력을 영원히 기다리지만 컨테이너는 계속 유지합니다.)그런 다음 디버깅을 실행할 수 있습니다.bash세션:

docker exec -i container_name bash

컨테이너가 실행되는 동안 다음을 제거할 수도 있습니다.already_ran그리고 수동으로 실행합니다.entrypoint.sh스크립트를 통해 다시 실행할 수 있습니다. 그런 방식으로 디버깅해야 하는 경우.

이것은 정확히 당신이 요구하는 것은 아니지만, 당신은 사용할 수 있습니다.docker export파일을 검사하는 것만 원하는 경우 정지된 컨테이너에 저장할 수 있습니다.

mkdir $TARGET_DIR
docker export $CONTAINER_ID | tar -x -C $TARGET_DIR

도커 - compose 실행 -- 진입점 /bin/ bash cont_id_or_name

(편리하게, env, volummounts를 도커에 넣으십시오- compose.yml)

또는 도커 런을 사용하고 수동으로 사양을 지정합니다.

나는 @Dmitriusan의 대답을 받아들여 가명으로 만들었습니다.

alias docker-run-prev-container='container_prev_id="$(docker ps -aq | head -n1)" & 도커 커밋 "$container_prev_id" "container_prev/$container_bash_id" & 도커 런 -it --entrypoint=container "prev_prev/$container_id"'

이것을 당신의 것에 추가합니다.~/.bashrc별칭 파일을 사용하면 새 파일을 얻을 수 있습니다.docker-run-prev-container이전 컨테이너의 포탄 안으로 당신을 떨어뜨릴 별칭입니다.

디버깅에 실패한 경우 도움이 됩니다.docker builds.

컨테이너가 시작된 후 도커는 진입 지점을 변경할 수 없는 것 같습니다.그러나 사용자 정의 진입점을 설정하고 다음에 다시 시작할 때 진입점의 코드를 변경할 수 있습니다.

예를 들어 다음과 같은 컨테이너를 실행합니다.

docker run --name c --entrypoint "/boot" -v "./boot":/boot $image

부팅 진입 지점은 다음과 같습니다.

#!/bin/bash
command_a

다른 명령을 사용하여 c를 다시 시작해야 할 때는 부팅 스크립트를 변경하기만 하면 됩니다.

#!/bin/bash
command_b

다시 시작합니다.

docker restart c

간단한 명령을 찾았습니다.

docker start -a [container_name]

이렇게 하면 효과가 있습니다.

아니면

docker start [container_name]

그리고나서

docker exec -it [container_name] bash

내 문제:

  • 저는 용기를 시작했습니다.docker run <IMAGE_NAME>
  • 그리고 이 컨테이너에 파일 몇개를 추가했습니다.
  • 그리고 용기를 닫고 위와 같은 명령으로 다시 시작하려고 했습니다.
  • 하지만 제가 새 파일을 확인했을 때, 그 파일들은 사라진 상태였습니다.
  • 내가 뛸때docker ps -a두 개의 컨테이너가 보였습니다.
  • 그 말은 내가 뛸 때마다docker run <IMAGE_NAME>명령, 새 이미지가 생성되고 있습니다.

해결책:처음에 만든 컨테이너에서 작업하려면 다음 단계를 수행합니다.

  • docker ps용기를 가져오다
  • docker container start <CONTAINER_ID>기존 컨테이너를 시작하다
  • 그러면 떠난 곳에서 계속할 수 있습니다. 예를 들어.docker exec -it <CONTAINER_ID> /bin/bash
  • 그런 다음 새 이미지를 만들기로 결정할 수 있습니다.

InnoDB 테이블이 손상되어 시작할 때 MariaDB 컨테이너가 계속 충돌하는 도커 컨테이너가 있었습니다.

문제를 해결하기 위해 한 일은 다음과 같습니다.

  • docker-entrypoint.sh 을 컨테이너에서 로컬 파일 시스템( docker cp)으로 복사합니다.
  • 필요한 명령줄 매개 변수를 포함하도록 편집합니다(--innodb-force-recovery=1).
  • 편집된 파일을 다시 도커 컨테이너에 복사하여 기존 진입점 스크립트를 덮어씁니다.

대부분의 경우 구성 파일을 수정하는 동안 사람들이 이것을 마주치는 것 같은데, 그것이 제가 한 일입니다.Vue SPA를 진입점으로 하는 PHP/Apache 서버에 대한 CORS를 우회하려고 했습니다.어쨌든, 당신이 호킹한 파일을 안다면, 나에게 효과가 있었던 간단한 해결책은

  1. 이미지에서 호킹한 파일을 복사합니다.

    도커 cpbt-php:/etc/apache2/apache2.conf.

  2. 로컬로 수정

  3. 다시 복사

    도커 cp apache2.confbt- php:/etc/ apache2/ apache2.conf

  4. 컨테이너 백업 시작

  5. *보너스 포인트 - 이 파일은 수정 중이므로 작성 또는 빌드 스크립트에 추가하면 이미지에 맞게 구워집니다!

이를 둘러싼 많은 논의가 있었기 때문에 위에 나열된 것을 바로 볼 수 없는 것을 하나 더 추가하려고 생각했습니다.

컨테이너의 진입점에 대한 전체 경로가 알려진 경우(또는 검사를 통해 검색 가능한 경우), 'docker cp'를 사용하여 정지된 컨테이너 안팎으로 복사할 수 있습니다.즉, 원본을 컨테이너 밖으로 복사하고, 해당 복사본을 편집하여 수행 중이던 작업 대신 배시 셸(또는 긴 절전 타이머)을 시작한 다음 컨테이너를 다시 시작할 수 있습니다.이제 실행 중인 컨테이너를 bash shell로 추가 편집하여 문제를 수정할 수 있습니다.원래 진입점의 다른 도커 cp 편집이 완료되면 용기에 다시 들어가 다시 시작해야 합니다.

저는 이것을 한 번 사용하여 제가 버터핑한 '빠른 수정'을 수정한 적이 있으며 수정될 때까지 정상적인 진입 지점으로 컨테이너를 실행할 수 없었습니다.

또한 도커를 통해 이를 수행할 수 있는 더 나은 방법이 있어야 한다는 것에 동의합니다.대체 진입 지점을 허용하는 '도커 재시작' 옵션?이봐, 그게 벌써 '-진입점'에서 작동하는 건 아닐까요?잘 모르겠어요, 안해봤어요, 독자용 운동으로 남겨졌어요, 효과가 있으면 알려주세요. :)

나에게 도커는 항상 취미를 위해 만들어진 것이라는 인상을 남깁니다. 그것은 그것을 위해 잘 작동합니다.
만약 어떤 일이 실패하거나 효과가 없다면, 전문적인 해결책을 기대하지 마세요.

그럼요.도커는 이러한 기본적인 관리 업무를 지원하지 않을 뿐만 아니라 이를 막으려고 합니다.

해결책:

  1. cd /var/lib/docker/overlay2/
    
  2. find | grep somechangedfile 
    # You now can see the changed file from your container in a hexcoded folder/diff
    
  3. cd hexcoded-folder/diff
    
  4. 만들기entrypoint.sh(기존 백업이 있으면 백업해야 함)

    cat > entrypoint.sh
    #!/bin/bash
    while ((1)); do sleep 1; done;
    

    Ctrl+C

     chmod +x entrypoint.sh
    
  5. docker stop
    docker start
    

이제 도커 컨테이너가 원래 엔트리 대신 끝없는 루프를 실행하고, Bash into를 실행하거나, 필요한 모든 작업을 수행할 수 있습니다.컨테이너 중지가 완료되면 사용자 지정 진입점을 제거/이름 변경합니다.

언급URL : https://stackoverflow.com/questions/32353055/how-to-start-a-stopped-docker-container-with-a-different-command

반응형