V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
HugeNature
V2EX  ›  Kubernetes

从外部 ssh 到 k8s 的 pod 里面

  •  
  •   HugeNature · 2023-12-07 13:01:57 +08:00 · 7236 次点击
    这是一个创建于 381 天前的主题,其中的信息可能已经有所发展或是发生改变。

    求教大佬,从外部 ssh 到 k8s 的 pod 里面,有什么方案么?

    64 条回复    2024-05-11 11:28:05 +08:00
    SoulSleep
        1
    SoulSleep  
       2023-12-07 13:05:40 +08:00
    首先默认的网络方案是不支持的...我们有用大二层网络架构的 k8s 可以,pod 就像一个 vm 一样....

    要不你开个 node port 把 ssh 给映射出去(不安全

    很多平台支持 webshell...
    julyclyde
        2
    julyclyde  
       2023-12-07 13:08:30 +08:00
    首先容器里就别运行完整的操作系统
    它也不拥有固定的 IP 地址

    ssh 进去这个,一定是你的需求有问题
    hicdn
        3
    hicdn  
       2023-12-07 13:11:05 +08:00 via Android
    pod 里跑个 ttyd ,可以开认证选项,把端口映射出来,就可以在浏览器里执行命令了
    kenvix
        4
    kenvix  
       2023-12-07 13:11:07 +08:00
    @julyclyde 这种需求是存在的,我们这里有一种人工智能平台就在 k8s 阵列上运行 sshd 然后用户 vscode sshd 进去写代码跑模型训练
    julyclyde
        5
    julyclyde  
       2023-12-07 13:13:22 +08:00
    @kenvix 设计错误
    HugeNature
        6
    HugeNature  
    OP
       2023-12-07 13:14:18 +08:00
    @julyclyde 我们的需求类似 kenvix ,用户需要进去 pod 做一些修改能快速地做一些验证。
    buffzty
        7
    buffzty  
       2023-12-07 13:15:17 +08:00
    1. 加个 wireguard 直通集群
    2. k8s port-forward
    临时建议第二种 长期建议第一种 第一种只能给后端负责人
    julyclyde
        8
    julyclyde  
       2023-12-07 13:15:22 +08:00
    @HugeNature 你这种情况不应该用 k8s 而应该是一个长生命周期的服务器
    HugeNature
        9
    HugeNature  
    OP
       2023-12-07 13:15:57 +08:00
    @hicdn 这个方案的确是一个可选项,但是 web terminal 体验不是很好,不能做太重的事情。
    HugeNature
        10
    HugeNature  
    OP
       2023-12-07 13:16:52 +08:00
    @buffzty 1. 加个 wireguard 直通集群 这个方案可以详细解释下么?是将 wg 安装在 pod 里还是 host 上?
    defunct9
        11
    defunct9  
       2023-12-07 13:17:35 +08:00
    kubectl exec -it pod -- /bin/bash
    HugeNature
        12
    HugeNature  
    OP
       2023-12-07 13:18:07 +08:00
    @defunct9 这个不是 ssh 哈。
    happyxhw101
        13
    happyxhw101  
       2023-12-07 13:18:35 +08:00
    @HugeNature 可以看看 k8s dashboard 里面是怎么实现的,应该是在前端实现了 kubectl exec -it xxxx -- sh
    HugeNature
        14
    HugeNature  
    OP
       2023-12-07 13:19:22 +08:00
    @julyclyde 现状就是已经用了 k8s 了,没办法推倒,只能想办法解决 ssh 的问题
    66z
        15
    66z  
       2023-12-07 13:25:33 +08:00
    好像 kubeflow 的方案是 jupter
    qilme
        16
    qilme  
       2023-12-07 13:26:42 +08:00
    平添麻烦,参考一下 okteto 的实现是每个容器加一个 ssh 服务器进去,然后做端口转发
    https://www.okteto.com/docs/reference/ssh-server/
    killva4624
        17
    killva4624  
       2023-12-07 13:27:46 +08:00
    kubectl exec -it pod bash

    把这层封装到前端做一个 Terminal
    buffzty
        18
    buffzty  
       2023-12-07 13:28:07 +08:00
    @HugeNature wireguard 安在 node 上 你客户端也要安装一个 可以自己设置代理仅集群内流量 集群 dns 也可以用 本地跟集群全互通
    defunct9
        19
    defunct9  
       2023-12-07 13:30:33 +08:00   ❤️ 1
    容器里本来就没有 ssh ,非要跑一个干嘛,你的目的就是远程调试,那么启个 bash 接进来就是正解。你可以在你发起 ssh 的机器上配好 kubectl 不就行了。
    ppto
        20
    ppto  
       2023-12-07 13:31:11 +08:00
    sidecar 感觉可以。
    HugeNature
        21
    HugeNature  
    OP
       2023-12-07 13:31:32 +08:00
    @killva4624 还是裸的 ssh 的适用性更强,比如 terminal ssh ,用户用 vscode 连接 pod 等等
    HugeNature
        22
    HugeNature  
    OP
       2023-12-07 13:32:54 +08:00
    @buffzty node 上安装 wg 的话,外面 ssh 最多到 host 上吧?进不到 pod 里应该
    HugeNature
        23
    HugeNature  
    OP
       2023-12-07 13:34:25 +08:00
    @defunct9 需求就是要可以 ssh ,咱也没办法,只能想办法去实现
    buffzty
        24
    buffzty  
       2023-12-07 13:35:47 +08:00
    @HugeNature 我都跟你说了集群全互通 我都用了几年了
    Frankcox
        25
    Frankcox  
       2023-12-07 13:36:36 +08:00
    client-go tool 下有 remotecommand ,你可以用 Go+前端 webshell 包装一下,实现类似于 ssh 的效果。
    hicdn
        26
    hicdn  
       2023-12-07 13:38:42 +08:00 via Android
    @HugeNature 那就在 pod 里跑一个完整系统,把 ssh 端口转发出来
    HugeNature
        27
    HugeNature  
    OP
       2023-12-07 13:39:18 +08:00
    @buffzty 额,大佬可以解释下“集群全互通”么? 不是很理解这个概念。谢谢啦。
    HugeNature
        28
    HugeNature  
    OP
       2023-12-07 13:40:21 +08:00
    @Frankcox 希望的是原生的 ssh ,用户可以用任何方式 ssh ,terminal ,vscode ,或者其他的 GUI 工具。
    HugeNature
        29
    HugeNature  
    OP
       2023-12-07 13:40:57 +08:00
    @hicdn 那太重了,可以安装 sshserver ,开端口转发
    xuzhzzz
        30
    xuzhzzz  
       2023-12-07 13:43:02 +08:00
    简单的方法就是部署一个 xxx 容器管理平台,里面 terminal 登录 pod 是很常见的功能
    kindom
        31
    kindom  
       2023-12-07 13:52:12 +08:00
    K8S site: kubeflow -> codeserver
    Client site: VScode -> k8s plugin -> kubeflow
    buffzty
        32
    buffzty  
       2023-12-07 13:53:54 +08:00
    node1 ip 172.10.0.1 ,pod ip 10.80.1.0/24
    node2 ip 172.10.0.2 ,pod ip 10.80.2.0/24
    node3 ip 172.10.0.3 ,pod ip 10.80.3.0/24
    client 连接 wg 到任意一个你设置的 node ( wg 转发节点)
    此时 client 可以访问上面的所有 ip 也可以用集群 dns 比如 mysql.default.svc.cluster.local
    需要通几个 node 就在那几个 node 上开 wg
    如果 node2 开了 wg node3 没开 那么 10.80.3.0/24 这个网段你访问不了
    kenvix
        33
    kenvix  
       2023-12-07 13:55:08 +08:00
    @julyclyde 那你得去跟 H3C 他们讲🤣这套系统带着机器一套卖几千万
    aleimu
        34
    aleimu  
       2023-12-07 14:20:13 +08:00
    这个还真可以的,就是镜像里需要启动 sshd 服务,并且 pod 要开 22 端口,密码的话随机生成或固定,这样方便开发者自己通过堡垒机登录定位问题, kubectl exec -it pod bash 只能运维人员用用, webshell 的话不好对接堡垒机还依赖浏览器环境
    Kinnice
        35
    Kinnice  
       2023-12-07 14:45:29 +08:00
    集群:
    1. pod 里面需要开 ssh-server ,cluster IP 即可
    2. 然后再任意 node ,部署[可以物理机直接部署或容器部署] openvpn/wireguard 暴露出 nodePort ,配置好到 clusterIP 段的路由和 dns
    eg: https://github.com/helm/charts/tree/master/stable/openvpn
    使用者:
    1. 连接 openvpn/wireguerd
    2. 使用 pod-ip/name 直接 ssh 即可
    anubu
        36
    anubu  
       2023-12-07 14:46:06 +08:00
    一直在 autodl 租 GPU ,容器实例就是在容器里部署 sshd 端口映射到公网,当做一个虚拟机使用。所以你这里容器部署 sshd ,nodeport 批量暴露出来应该是没有问题的。虽然不符合所谓的最佳实践,但业务上的东西一般都是各种情况的 trade-off ,不能强制追求完美。autodl 也算正经商业化的业务,举例是说明这样实现肯定不能说是很差的选择。
    Kinnice
        37
    Kinnice  
       2023-12-07 14:47:02 +08:00
    @Kinnice #35 还有一种就是使用者配置好 kubectl 然后通过 port-forward 把 pod 内部 ssh 端口映射到本地
    https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/
    chronos
        38
    chronos  
       2023-12-07 14:54:11 +08:00
    如果是自己人用,简单点就 kubectl port-forward 将 pod 的 sshd 端口映射到本地。

    如果是开放到外部使用,可以考虑使用 frp ,先部署一个 frps 并开放端口用于转发流量,然后每个 sshd 的 pod 启动时里面再启动一个 frpc 连接 frps ,使用 stcp 模式,配置文件中的 name 和 secretKey 要输出给用户。用户侧 frpc 使用 stcp 连接 frps ,secretKey 要相同。这样就可以将 sshd 的端口映射到本地,然后本地的 vscode 之类的工具就可以使用映射过来的本地端口连接。

    stcp 的配置参考: https://gofrp.org/zh-cn/docs/examples/stcp/
    nilai
        39
    nilai  
       2023-12-07 14:56:45 +08:00
    1. node port 方式
    2.大二层方案,calico 支持
    3. 最简单的,更改外部连接机器的路由表,
    HugeNature
        40
    HugeNature  
    OP
       2023-12-07 15:00:06 +08:00
    @nilai 2.大二层方案,calico 支持 这个方案可以介绍下么?谢啦
    nilai
        41
    nilai  
       2023-12-07 15:04:18 +08:00
    步骤比较多, 一时半会还讲不清楚, 不过你可以尝试搜索 calico bgp 关键字 应该会有很多资料的
    ETiV
        42
    ETiV  
       2023-12-07 15:34:33 +08:00 via iPhone
    - ssh 到跳板机
    - 跳板机 authorized_key 里,配置 command
    - 可以在这 command 里加 kubectl exec bash 命令,当然,大概需要做一个前置的 TUI 程序,让人选择想要进入的 pod 和 container
    standchan
        43
    standchan  
       2023-12-07 16:09:08 +08:00
    把集群的连接信息保存到本地.kube/config ,然后 kubectl exec -it <pod-name> /bin/sh
    LyleLaii
        44
    LyleLaii  
       2023-12-07 17:10:37 +08:00
    @kenvix 确实有这种需求😂
    @HugeNature
    之前我在公司搭的 jupyterhub 就有业务说想用 IDE 更方便,我就搞过一个小玩意作 ssh 转发。
    整体逻辑是 pod 内都需要运行 sshd ,然后通过一个统一的服务进行认证,再将 ssh 的进行代理转发到指定 pod 。这个统一 服务用一个 nodeport 或者用 ingress 代理都行,可以参考下
    https://github.com/LyleLaii/jupyterhub-ssh-proxy
    julyclyde
        45
    julyclyde  
       2023-12-07 17:51:25 +08:00
    @HugeNature 那你试试把 pod 设置为 host 模式吧
    至于浮动 IP 你只能自己想办法了
    bigfei
        46
    bigfei  
       2023-12-07 18:02:24 +08:00 via Android
    calico bgp 配好就行,只是可能需要你们的网管配合开一下 bgp 配置
    wWjd5V5L0636B5YV
        47
    wWjd5V5L0636B5YV  
       2023-12-07 18:04:39 +08:00
    @defunct9 这不是 docker 命令么?
    zhoujinjing09
        48
    zhoujinjing09  
       2023-12-07 18:12:25 +08:00
    有现成工具 https://containerssh.io/v0.4/ ,缺点是 ssh 是通过 k8s api server 转发 kubectl exec 的,流量大的话可能会影响集群稳定性
    2n80HF9IV8d05L9v
        49
    2n80HF9IV8d05L9v  
       2023-12-07 18:13:57 +08:00
    如果只是临时的, 可以直接找个跳板, ssh -fNL, ssh -fNR
    superchijinpeng
        50
    superchijinpeng  
       2023-12-07 18:23:17 +08:00
    Tailscale 也行
    wangbin11
        51
    wangbin11  
       2023-12-07 18:43:42 +08:00
    我们的方案是,直接 k8s 跑个 wiregaurd 的 pod ,然后映射一个 udp 端口出去通过 vpn 连接到内部,有需要可以回复我,我发你方案
    Daath
        52
    Daath  
       2023-12-07 18:46:39 +08:00
    ingress-controller 修改 tcp-config 开放对应的端口直接映射到内部 pod 相关的 svc 的端口,如果还有负载均衡,那 lb 上开放 svc 对应的端口,应该就可以直通某个 pod 吧
    yougg
        53
    yougg  
       2023-12-07 19:37:57 +08:00
    干嘛非要 pod 里面做 server 端才行, 开一堆洞不好收拾烂摊子
    把思路打开 反弹 shell 一样能搞定任务.
    https://gist.github.com/yougg/b47f4910767a74fcfe1077d21568070e
    killerirving
        54
    killerirving  
       2023-12-07 22:38:51 +08:00
    看看这个? 用 kubectl 插件实现了一个 ssh ProxyCommand 的功能
    https://github.com/ciiiii/kube-ProxyCommand
    ```
    Host develop-container
    HostName develop-container
    User root
    Port 22
    IdentityFile /path/to/private/key
    ProxyCommand kube-proxyCommand --name=podName --namespace=podNamespace --port=%p
    ```
    smilingsun
        55
    smilingsun  
       2023-12-07 23:46:14 +08:00
    可以参考一下 Coder ,用 Tailscale 实现 p2p 到 pod

    > When possible, we establish direct connections between users and workspaces. Direct connections are as fast as connecting to the workspace outside of Coder. When NAT traversal fails, connections are relayed through the coder server. All user <-> workspace connections are end-to-end encrypted.

    https://coder.com/docs/v2/latest/networking#networking
    tudou1514
        56
    tudou1514  
       2023-12-08 09:36:56 +08:00
    ingress-controller 支持添加 80 、443 以外的 tcp 和 udp 协议暴漏,可以试试
    Masoud2023
        57
    Masoud2023  
       2023-12-08 09:40:36 +08:00
    就必须得要拿 ssh 进吗?

    如果不要其他特性,比如端口映射或者 scp ,感觉倒是可以自己写一个。
    byte10
        58
    byte10  
       2023-12-08 10:01:28 +08:00
    不太合理的的需求 请用不太合理的方式实现,管它是否安全,用了再说吧。
    relife
        59
    relife  
       2023-12-08 10:59:24 +08:00
    开个新的 ssh 用户,然后 chsh 修改登录直接 exec 到容器里面
    xabclink
        60
    xabclink  
       2023-12-08 12:42:39 +08:00
    https://ki.xabc.io 可以满足你的需求
    tohearts
        61
    tohearts  
       2023-12-08 15:47:45 +08:00
    remote ssh 的需求是什么,如果是方便开发代码,直接使用 okteto 开源版本就行。 直接在 pod 内部开发,本地 <-->pod 实时同步文件,并且提供 remote terminal.
    wbuntu
        62
    wbuntu  
       2023-12-08 17:01:32 +08:00
    可以考虑在 pod 里起一个 sidecar 容器,比如用 gost ,可以提供一个基于 websocket 的代理,本地 gost 客户端连接到这个 sidecard 容器(可以走 nodePort 、也可以用 ingress 在 7 层转发),ssh 时可以用 ProxyCommand 连接本地代理端口就行

    ssh-client -> gost-local ( socks5 )-> gost-local ( ws )-> ingrss-controller -> gost-remote ( ws ) -> ssh-server
    winson030
        63
    winson030  
       353 天前
    vscode 的 ssh container 是不是更好? 开箱就用
    yunshangdetianya
        64
    yunshangdetianya  
       225 天前
    @buffzty 说的很对,就是这个道理
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   900 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 22:12 · PVG 06:12 · LAX 14:12 · JFK 17:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.