V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
leoleoasd
V2EX  ›  问与答

能否通过某方式使 ssh 客户端连接到 docker 某容器内的 bash?

  •  
  •   leoleoasd · 2019-04-02 22:24:29 +08:00 · 2876 次点击
    这是一个创建于 2091 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如题 想做到的效果是: ssh 客户端连接 docker 宿主机某端口 看到的内容是宿主机(根据用户名决定的某容器)内的 /bin/bash

    想过用 python api 转发 docker exec 的结果 但是这样子的话不支持类似 top 或者 vi 这样交互式的程序

    25 条回复    2019-04-03 21:26:54 +08:00
    neighbads
        1
    neighbads  
       2019-04-02 22:54:17 +08:00 via Android
    用端口好区分 用用户名就费劲了。
    Alliot
        2
    Alliot  
       2019-04-03 00:18:24 +08:00 via Android
    docker 里面跑个 sshd (逃
    yingyue
        3
    yingyue  
       2019-04-03 00:27:20 +08:00 via Android
    我觉得 2 楼方法最好
    cxyfreedom
        4
    cxyfreedom  
       2019-04-03 00:29:40 +08:00 via iPhone
    只能容器里面跑 sshd 吧,不然怎么 ssh (
    zeromake
        5
    zeromake  
       2019-04-03 00:48:25 +08:00 via Android   ❤️ 1
    可以看看我的 docker 小工具怎么处理 docker exec 的输入输出。github 的`zeromake/docker-debug`

    看不来 go 可以去看看 docker-compose 的 py 实现。
    然后找个 ssh server 实现库重定向输入输出到 ssh 里
    ETiV
        6
    ETiV  
       2019-04-03 01:27:03 +08:00 via iPhone
    authorized_key 的配置语法可以去了解一下

    ssh-rsa 前面可以加 no-tty、no-port-forwarding 等等这些

    但它还有个 command 指令( GitHub 之类的就是用它来鉴权的):
    我们这里貌似用 command="docker exec -ti container /bin/bash" 就可以了,你可能要自己多试试

    docker terminal window 有它自己的 size,所以这么连上去可能挺难用的(可能字符会胡乱折行)(印象中有个 docker resize 命令?)

    然后当用户通过这个对应的 key 连上来,就会执行 command 制定的命令
    ResidualBlood
        7
    ResidualBlood  
       2019-04-03 07:02:19 +08:00 via Android
    frp 可实现,虽然有点另辟蹊径。。。
    catalina
        8
    catalina  
       2019-04-03 07:12:38 +08:00 via Android
    @Alliot 这方法不是挺不错的嘛
    leoleoasd
        9
    leoleoasd  
    OP
       2019-04-03 08:01:04 +08:00
    @ETiV #6 这个 command 是否会覆盖 /etc/passwd 中的设置?
    比如我为了安全期间 /etc/passwd 中设置为 nologin 然后 command 写 docker exec
    leoleoasd
        10
    leoleoasd  
    OP
       2019-04-03 08:24:59 +08:00
    @zeromake #5 这样子的话容器内的程序 如 vi 能否读取到窗口的长宽?
    leoleoasd
        11
    leoleoasd  
    OP
       2019-04-03 08:25:41 +08:00
    @cxyfreedom #4 ssh 链接主机 主机转发到 docker exec 中的 bash 里
    问题是那种 vi 啥的 docker 内的程序怎么读取 ssh 客户端的窗口大小
    yuikns
        12
    yuikns  
       2019-04-03 08:40:19 +08:00
    CMD ["/usr/sbin/sshd", "-D"]

    可解决。

    不过有时候有些系统需要 hack 下。

    RUN ssh-keygen -A ; \
    mkdir -p /var/run/sshd ; \
    sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd ; \
    sed 's@#UseDNS yes@UseDNS no@g' -i /etc/ssh/sshd_config # prevent stucks here >> SSH2_MSG_SERVICE_ACCEPT received

    docker 里面 22 端口转出去即可。

    ssh 的话,vi 读窗口大小和这貌似没关系。这个就是 ssh 帮忙转发全局环境变量 COLUMNS LINES TERM 等。
    你 echo $LINES 可以看到。
    kaneg
        13
    kaneg  
       2019-04-03 08:48:25 +08:00 via iPhone
    可以参照我做的一个个人项目 httpshell,类似 ssh,但可以自定义需要执行的命令。
    AngryPanda
        14
    AngryPanda  
       2019-04-03 08:48:46 +08:00 via Android
    先 ssh 到宿主机,然后执行 docker exec bash
    yuikns
        15
    yuikns  
       2019-04-03 08:49:17 +08:00
    @yuikns 额,刚才搜了下,我后面记忆中的环境变量是错误的。抱歉丢人了...
    yuikns
        16
    yuikns  
       2019-04-03 08:50:38 +08:00
    另外,要是想要远程跑 python,jupyter notebook 也是个可选项。多用户用 jupyterhub 什么的也很好用
    leoleoasd
        17
    leoleoasd  
    OP
       2019-04-03 09:10:42 +08:00
    @ETiV #6 刚测试了下这样子用 VI 换行是没有问题的
    zeromake
        18
    zeromake  
       2019-04-03 09:18:53 +08:00 via Android
    @leoleoasd #10 docker 自己有个 resize 接口就是用来处理这个的
    leoleoasd
        19
    leoleoasd  
    OP
       2019-04-03 09:42:01 +08:00
    @yuikns #12 我目前需要的效果是不在 docker 内跑 sshd
    6 楼给的方法我测试了下春耕拱了
    leoleoasd
        20
    leoleoasd  
    OP
       2019-04-03 09:42:14 +08:00
    @yuikns 成功了
    lynnv2
        21
    lynnv2  
       2019-04-03 09:42:53 +08:00
    恰好,我们用的就是这种模式。用户.bashrc 文件里,加入运行写好调度 docker exec 的 python 程序即可。用户登录宿主机,直接会运行 python 程序,在程序里完成执行 exec 命令,在.bashrc 里,python 下一行,加入 exit 命令,可以实现用户退出 docker 后,同时退出宿主机。这是我们的一个业务跳板机。我们还实现了登录创建 docker 并进入,退出删除 docker 的功能。
    yuikns
        22
    yuikns  
       2019-04-03 10:00:37 +08:00
    @leoleoasd #6 的方法可以 scp/rsync 么?
    leoleoasd
        23
    leoleoasd  
    OP
       2019-04-03 10:05:44 +08:00
    @yuikns #22 不可以
    但是 我想要的是 不在 docker 内安装 sshd
    leoleoasd
        24
    leoleoasd  
    OP
       2019-04-03 18:45:30 +08:00   ❤️ 1
    @yuikns #22 发现了个曲线救国的方式 能用 6 楼的方式实现 scp:
    authorized_keys:
    command="ID=CONTAINER_ID /path/to/.sh" ...key...

    .sh 文件的内容:
    ```
    #!/bin/bash

    vars=( $SSH_ORIGINAL_COMMAND )
    case "${vars[0]}" in
    "scp")
    docker exec -i $ID /usr/bin/scp -t ${vars[2]}
    exit 0
    ;;
    *)
    docker exec -it $ID /bin/bash
    exit 0
    ;;
    esac
    ```
    这样子 只需要容器内有一个 scp 二进制文件就可以传输文件 不需要容器内运行 sshd
    可以所有容器公用一个端口 通过不同的 key 来分辨不同的 docker 容器
    yuikns
        25
    yuikns  
       2019-04-03 21:26:54 +08:00 via iPhone
    @leoleoasd 赞,这个厉害了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5643 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 01:42 · PVG 09:42 · LAX 17:42 · JFK 20:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.