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

容器连通性(容器到某个网络是否畅通)检查方案

  •  
  •   helenfrank · 304 天前 · 2427 次点击
    这是一个创建于 304 天前的主题,其中的信息可能已经有所发展或是发生改变。
    目前远程对 pod 的网络连通性 检查有啥比较好的方案吗, 地址可以是 domain, domain:port, ip, ip:port
    1. client-go 调 exec 执行 curl, ping, nc (我目前使用的方案, 但存在存量镜像没有这些工具)
    2. 再挂个工具 container (侵入性较大, 且更占资源)
    3. nsenter (需要连接 node, docker inspect 获取 Pid, client-go 获取 pod dns 地址, 依赖于 node 上的工具)

    还有啥比较好的方案吗
    39 条回复    2024-01-19 12:17:18 +08:00
    Nooooobycat
        1
    Nooooobycat  
       304 天前
    直接与这个地址建立 Socket 连接就行了。 上面开进程去验证属于脱裤子放屁

    package main

    import (
    "fmt"
    "net"
    "time"
    )

    func connectTCP(address string) bool {
    // 设置连接超时时间
    timeout := 5 * time.Second

    // 尝试建立连接
    conn, err := net.DialTimeout("tcp", address, timeout)

    // 检查是否出现错误
    if err != nil {
    fmt.Println("连接失败:", err)
    return false
    }

    // 关闭连接
    defer conn.Close()

    fmt.Println("连接成功")
    return true
    }
    helenfrank
        2
    helenfrank  
    OP
       304 天前
    @Nooooobycat #1 并不是这样, 我是在做上层云平台的功能, 这个功能是为了检查运行中的 pod 到某个网络是否畅通
    latteczy
        3
    latteczy  
       304 天前
    sidecar?
    helenfrank
        4
    helenfrank  
    OP
       304 天前
    @latteczy #3 见第二条, 目前没上 istio, 所以...
    lntouchables
        5
    lntouchables  
       304 天前
    在上家公司也有做过这种需求,用的 nsenter ,如果 k8s 版本支持的话可以看一下 kubectl-debug
    lujiaosama
        6
    lujiaosama  
       304 天前
    插眼. 确实是个问题. 进到容器没 PING, CURL 还测不了接口是否联通.
    leonshaw
        7
    leonshaw  
       304 天前
    就走 2
    ysicing
        8
    ysicing  
       304 天前
    lrh3321
        9
    lrh3321  
       304 天前 via Android
    nsenter

    或者把容器的网络命名空间 mount 到 /run/netns/NAME 下,然后
    ip netns exec NAME cmd....
    julyclyde
        10
    julyclyde  
       304 天前
    @helenfrank 如果存在“有时候通”那你应该去解决网络的问题啊,而不是每次运行的时候检查一下啊
    Frankcox
        11
    Frankcox  
       304 天前
    在存量镜像没法修改的情况下,就用 2 的 sidecar 呗,sidecar 是一种模式,不一定跟 istio 绑定,你可以自己用 go 写一个小程序,或者就提前封装好一个镜像+bash 脚本。然后在集群部署个 mutating webhook ,当指定 deployment 部署时,自动通过 webhook 把这个 container 注入到 deployment 中。
    Frankcox
        12
    Frankcox  
       304 天前
    @Frankcox 另外看这个帖子学到了 nsenter ,挺好的东西
    helenfrank
        13
    helenfrank  
    OP
       304 天前
    @julyclyde #10 不是每次运行(我理解你的意思是启动)的时候, 是在正常运行时, 出现了一些服务不可用, 项目组成员可以通过云平台先检查下是不是网络问题
    helenfrank
        14
    helenfrank  
    OP
       304 天前
    @Frankcox #11 是的, 理解你的想法, 并且实践过, 如我在 2 里所提到的(侵入性较大, 且更占资源)
    fengxsong
        15
    fengxsong  
       304 天前
    这个不是监控要做的事吗。。
    helenfrank
        16
    helenfrank  
    OP
       304 天前
    @fengxsong #15 需求是可以把这个功能给到项目组成员, 让他们在运行中可以检查到某个网络是否通畅, 进而可以反馈给管理网络的人, 毕竟谁知道项目组的人想访问哪个网络呢
    zjb861107
        17
    zjb861107  
       304 天前 via Android
    之前看过一个观点是这个容器里运行的程序是什么语言,就用对应的语言开发一个/ping 接口或者脚本来检查该程序是否在运行,我觉得这也是个办法。一般这种逻辑也不会太复杂,定制化也容易。
    helenfrank
        18
    helenfrank  
    OP
       304 天前
    @zjb861107 #17 你对需求理解的有误差, 想要的是测试 pod 到某个网络是否通畅, 不是检测 pod 正常运行
    yimiaoxiehou
        19
    yimiaoxiehou  
       304 天前   ❤️ 1
    在所属节点创建一个特权 pod ,在 pod 中使用 nsenter -t { PID } -n { CMD } 检测
    huanghanzhilian
        20
    huanghanzhilian  
       304 天前
    我也用到了 docker ,挺吃力的,不过部署成功了

    我开源了一个精美的电商开源项目,如果对你有帮助,请在 github 上帮我点亮星星,这会是对我莫大的鼓励。
    在线体验: http://shop.huanghanlian.com
    开源项目 传送门: https://github.com/huanghanzhilian/c-shopping
    yimiaoxiehou
        21
    yimiaoxiehou  
       304 天前
    @huanghanzhilian 机器人?
    helenfrank
        22
    helenfrank  
    OP
       304 天前
    @yimiaoxiehou #19 这个方案不错
    helenfrank
        23
    helenfrank  
    OP
       304 天前
    @yimiaoxiehou #19 和第三种方案差别不大
    CivAx
        24
    CivAx  
       304 天前
    unix 经典问题,无网络工具如何测网,经典回答永远是 /dev/tcp
    CivAx
        25
    CivAx  
       304 天前   ❤️ 1
    纯 IP:exec 9<> /dev/tcp/127.0.0.1/80

    可以顺便验证 DNS:exec 9<> /dev/tcp/www.baidu.com/443

    别忘了 exec 9>&-,不然就要等 CLOSE_WAIT 超时了。

    或者 echo < /dev/tcp/127.0.0.1/7777 && echo "ok" || echo "fail"
    cheng6563
        26
    cheng6563  
       304 天前
    1 就行了,把所有工具自己打包一下完事,或者完全自己写个单文件工具
    yimiaoxiehou
        27
    yimiaoxiehou  
       304 天前
    @helenfrank 可以避免需要 ssh 进入 node ,也可以避免 node 没有对应工具
    mightybruce
        28
    mightybruce  
       304 天前
    容器网络是 linux 的特性,linux 没有/dev/tcp

    另外容器网络是在命名空间中的

    无 shell 或工具的 pod 调试就是 nsenter
    CivAx
        29
    CivAx  
       304 天前 via iPhone
    @mightybruce 只要基础镜像是 bash fs 有 bash 就有 tcp ,op 都能 exec 进容器调 nc 了很自然能调到 tcp
    helenfrank
        30
    helenfrank  
    OP
       304 天前
    @CivAx #29 貌似并不如你所言, 我找了个是 bash 的容器, 并没有/dev/tcp, 我自己的 arch or mac 上面也没有/dev/tcp
    helenfrank
        31
    helenfrank  
    OP
       304 天前
    @helenfrank #30 验证

    arch:
    ```bash
    ❯ exec 9<> /dev/tcp/www.baidu.com/443
    zsh: no such file or directory: /dev/tcp/www.baidu.com/443
    ```

    mac
    ```bash
    exec 9<> /dev/tcp/www.baidu.com/443
    zsh: no such file or directory: /dev/tcp/www.baidu.com/443
    ```
    CivAx
        32
    CivAx  
       304 天前
    @helenfrank #31 /dev/tcp 要 redirect 调用,本身并不存在这个文件,具体 lib 在 /proc/net/tcp 。如果你在本机 docker run ,/proc 会受宿主机影响,你可以 uname -r 看看内核,我这会儿没在 Arm Mac 旁边,没法验证你这个场景。

    Redirect: https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Redirections

    ``` deployment
    apiVersion: v1
    kind: Pod
    metadata:
    name: arch
    namespace: default
    spec:
    containers:
    - image: docker.io/library/archlinux
    command:
    - sleep
    - "3600"
    imagePullPolicy: IfNotPresent
    name: arch
    restartPolicy: Always
    ```
    root@WSL [17:13:39] :~ # kubectl apply -f deployment.yaml
    pod/arch created

    root@WSL [17:13:47] :~ # kubectl get pod
    NAME READY STATUS RESTARTS AGE
    arch 0/1 ContainerCreating 0 4s

    root@WSL [17:14:03] :~ # kubectl get pod
    NAME READY STATUS RESTARTS AGE
    arch 1/1 Running 0 19s

    root@WSL [17:14:05] :~ # kubectl exec -it arch -- bash

    [root@arch /]# cat /etc/issue
    Arch Linux \r (\l)

    [root@arch /]# uname -r
    6.1.59

    [root@arch /]# echo < /dev/tcp/8.8.8.8/53 && echo "ok" || echo "fail"

    ok
    [root@arch /]#
    naison
        33
    naison  
       304 天前
    可以尝试使用 kubevpn https://github.com/kubenetworks/kubevpn ,本地直接链接到 k8s 网络,在本地直接 ping pod ip
    zong400
        34
    zong400  
       304 天前
    @CivAx 宿主是 ubuntu 貌似不行
    ```
    /app $ exec 9<> /dev/tcp/127.0.0.1/80
    sh: can't create /dev/tcp/127.0.0.1/80: nonexistent directory
    /app $
    /app $ uname -r
    5.15.0-60-generic
    ```
    CivAx
        35
    CivAx  
       304 天前 via iPhone
    @zong400 我在 Ubuntu @ WSL 拉起没问题,但我 uname -r 看内核是 MS 自己编译的,我这边没有其他的 Ubuntu 环境。
    julyclyde
        36
    julyclyde  
       304 天前
    @mightybruce /dev/tcp 是 bash 的
    julyclyde
        37
    julyclyde  
       304 天前
    @helenfrank 故障时检查,我以前一般都是 kubectl exec 进去查看的
    但是如果遇到某些洁癖的人,把 image 里各种工具软件都删了,那算没办法了……
    yingqiuQAQ
        38
    yingqiuQAQ  
       304 天前
    nicolaka github 这个工具用起来挺方便
    julyclyde
        39
    julyclyde  
       303 天前
    你这么惨,该不会是 shopee 或者腾讯 teg 的吧?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2961 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 12:49 · PVG 20:49 · LAX 04:49 · JFK 07:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.