首页 文章

是否可以在正在运行的容器中启动shell会话(没有ssh)

提问于
浏览
305

我天真地期望这个命令在一个正在运行的容器中运行一个bash shell:

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 shell(例如用于诊断目的)

我必须在其中运行SSH服务器并通过ssh登录吗?

14 回答

  • 1

    使用docker 1.3,有一个新命令docker exec . 这允许您输入正在运行的docker:

    docker exec -it "id of running container" bash
    
  • 2

    如果目标是检查应用程序的日志,这篇文章显示启动tomcat并拖尾记录为CMD的一部分 . 主机上使用“docker logs containerid”可以使用tomcat日志 .

    http://blog.trifork.com/2013/08/15/using-docker-to-efficiently-create-multiple-tomcat-instances/

  • 10

    运行容器时分配名称很有用 . 您不需要引用container_id .

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

  • -2

    在开发容器时,也许你像我一样误导了虚拟机 . 我的建议:尽量不要 .

    容器就像任何其他过程一样 . 实际上,您可能希望“附加”它们以进行调试(想想/ proc // env或strace -p),但这是一个非常特殊的情况 .

    通常你只是“运行”这个过程,所以如果你想修改配置或读取日志,只需创建一个新的容器,并确保通过共享目录,写入stdout来写日志之外的日志(所以docker日志工作)或类似的东西 .

    出于调试目的,您可能需要启动shell,然后启动代码,然后按CTRL-p CTRL-q使shell保持原样 . 这样你可以使用以下方法重新连接:

    docker attach <container_id>
    

    如果你想调试容器,因为它希望它能做到,请尝试调试它:https://serverfault.com/questions/596994/how-can-i-debug-a-docker-container-initialization

  • 1

    实际上有一种方法可以在容器中安装shell .

    假设您的 /root/run.sh 启动流程,流程管理员(主管)或其他任何东西 .

    使用一些gnu-screen技巧创建 /root/runme.sh

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

    现在,您可以在选项卡0中使用守护进程,并在选项卡1中使用交互式shell . docker attach 随时查看容器内发生的情况 .

    另一个建议是在 生产环境 映像的顶部创建一个“开发包”图像,其中包含所有必要的工具,包括此屏幕技巧 .

  • 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的选项:

    • 与exec(我使用),运行:

    docker run --name $ CONTAINER_NAME -dt $ IMAGE_NAME

    然后

    docker exec -it $ CONTAINER_NAME / bin / bash

    并使用

    CTRL D分离

    • with attach,运行:

    docker run --name $ CONTAINER_NAME -dit $ IMAGE_NAME

    然后

    docker附加$ CONTAINER_NAME

    并使用

    CTRL P和CTRL Q分离

    选项之间的区别在参数 -i

  • 4

    请关注此拉取请求:https://github.com/docker/docker/pull/7409

    它实现了即将发布的 docker exec <container_id> <command> 实用程序 . 当这可用时,应该可以例如在正在运行的容器中启动和停止ssh服务 .

    还有 nsinit 这样做:"nsinit provides a handy way to access a shell inside a running container's namespace",但看起来很难运行 . https://gist.github.com/ubergarm/ed42ebbea293350c30a6

  • 588

    由于事情正在变化,目前推荐的访问正在运行的容器的方法是使用 nsenter .

    您可以在github repository找到更多相关信息 . 但一般来说你可以像这样使用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ômePetazzoni的博客文章中找到:Why you don't need to run sshd in your docker containers

  • 0

    不,这是不可能的 . 如果需要,可以使用像 supervisord 这样的东西来获取ssh服务器 . 虽然,我绝对质疑需要 .

  • 1

    您可以使用

    docker exec -it <container_name> bash
    
  • 13

    有两种方法 .

    随着附加

    $ sudo docker attach 665b4a1e17b6 #by ID
    

    有了exec

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

    编辑:现在你可以使用 docker exec -it "id of running container" bashdoc

    以前,这个问题的答案是:

    如果你真的必须而且你在调试环境中,你可以这样做: sudo lxc-attach -n <ID> 注意id必须是完整的( docker ps -notrunc ) .

    但是,我强烈建议不要这样做 .

    注意: -notrunc 已弃用,很快就会被 --no-trunc 取代 .

  • 8

    首先,你无法运行

    docker run "existing container" command
    

    因为这个命令期望一个图像而不是一个容器,它无论如何都会导致产生一个新的容器(所以不是你想看的那个)

    我同意这样的事实:对于docker我们应该以不同的方式进行思考(所以你应该找到方法让你不需要登录容器),但我仍然觉得它很有用,这就是我的工作方式周围 .

    我在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
    

    它的作用是它允许你"attach"到容器并被提供 supervisorctl 接口来停止/启动/重启并检查日志 . 如果这还不够,你可以 Ctrl+D 然后你会进入一个shell,让你可以看看它是否像普通系统一样 .

    请注意,该系统不如没有外壳的容器那么安全,因此请采取所有必要步骤来保护容器 .

  • -4

    做就是了

    docker attach container_name
    

    如评论中所述,要从容器中分离而不停止它,请键入Ctrlpthen Ctrlq .

相关问题