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

ssh 端口转发和 K8S 网络问题

  •  1
     
  •   fighterhit · 2023-09-08 00:42:55 +08:00 · 1453 次点击
    这是一个创建于 468 天前的主题,其中的信息可能已经有所发展或是发生改变。
    1. 数据中心内网有个 k8s 集群,apiserver 证书绑定的内网 ip 地址(不能动),比如 10.xx.yy.1, 172.xx.yy.zz, 172.xx.yy.zz, master 节点假设为 A ,apiserver 不对公网开放
    2. 公网有个边缘节点 B (在 NAT 后),想加到上述集群中,目前 A 能 ssh 到 B 上,B 也能 ssh 到 A
    3. 未来只允许 A 能 ssh 到 B ,不允许 B ssh 到 A ,也就是不允许边缘访问数据中心服务器
    4. 这种条件下为了能把节点加到集群,我试了两种 ssh 隧道转发:
    • 第一种:远程端口转发:
    1. 在 A 上执行 ssh -R 6443:apiserver 内网 ip:6443 -N B-user@B-ip -p B-port 发起远程端口转发;从 A 上把自己 .kube/config 拷贝到 B 上,把 config 中的 server 地址改成: https://127.0.0.1:6443,此时在 B 上执行 kubectl get po 会报错:
    Unable to connect to the server: x509: certificate is valid for 10.xx.yy.1, 172.xx.yy.zz, not 127.0.0.1
    
    • 第二种:ssh 动态转发
    1. 在 B 上执行 ssh -D 1080 -q -N A-user@A-ip,将 A 的 .kube/config 拷贝到 B 上,但把 config 中的 server 地址下面多加一个 socks5 代理 proxy-url: socks5://localhost:1080,此时执行 kubectl get po 正常得到 A 集群的 pod

    问题:

    1. 想知道为什么第二种方式可以,但第一种不行,第一种到 apiserver 为什么会是 127.0.0.1 ?因为未来不允许从 B ssh 到 A ,第二种方式用不了该怎么访问 apiserver ?
    2. 上述情况能访问 apiserver 后,kubeadm join 节点还加不进去,不确定 kubelet 配置文件是不是也要加 proxy-url: socks5 才行,是否可行?
    3. 这种公网节点加入内网集群,带宽流量大不大?
    11 条回复    2023-09-15 20:55:53 +08:00
    zed1018
        1
    zed1018  
       2023-09-08 09:28:53 +08:00
    要不要考虑用个 vpn 做集群网络?比如 wg
    fighterhit
        2
    fighterhit  
    OP
       2023-09-08 09:47:28 +08:00
    @zed1018 考虑过,这种搭建复杂吗? wg 安全不?
    zzlyzq
        3
    zzlyzq  
       2023-09-08 10:14:44 +08:00
    @fighterhit
    1. wg or openvpn 等都可以,把边缘和数据中心搞成内网互通,好多事都好办了。
    2. 如果想进一步安全,可以闲置 wg or openvpn 两边的白名单访问。
    zzlyzq
        4
    zzlyzq  
       2023-09-08 10:21:29 +08:00
    1. 想知道为什么第二种方式可以,但第一种不行,第一种到 apiserver 为什么会是 127.0.0.1 ?因为未来不允许从 B ssh 到 A ,第二种方式用不了该怎么访问 apiserver ?
    答:
    (1) 第二种是前向代理的方式,集群看到访问来源是数据中心内部
    (2) 第一种,因为你是把 apiserver 接口映射到了本地,所以访问的是 127.0.0.1 ,而你的证书不包括 127.0.0.1 。这个问题仅仅是 ip 地址的问题。127.0.0.1 是本地环回接口,你可以在本地新建一个 lo 接口,地址是 10.xx.yy.1 或者 172.xx.yy.zz ,如下命令:
    ifconfig lo:1 10.xx.yy.1 ,
    ssh -R 6443:apiserver 内网 ip<换成 lo 口地址>:6443 -N B-user@B-ip -p B-port
    (3) 修改.kube/config 文件为你的 lo:1 地址。
    (4) 可以试试看了

    2. 上述情况能访问 apiserver 后,kubeadm join 节点还加不进去,不确定 kubelet 配置文件是不是也要加 proxy-url: socks5 才行,是否可行?
    答:
    ( 1 )不要考虑 socks5 的方式了,因为集群底层有集群网络,搞个代理还是分离的两个网络。
    ( 2 )如果仅仅是控制集群,可以使用代理。
    ( 3 )如果是边缘节点加入到数据中心集群,需要加入内网。

    3. 这种公网节点加入内网集群,带宽流量大不大?
    答:
    ( 1 )带宽不大,猜测 1Mbps 足够,但是会一直有,主要是集群控制流量和数据流量。
    fighterhit
        5
    fighterhit  
    OP
       2023-09-08 11:10:51 +08:00
    @zzlyzq
    1. 请问“在本地新建一个 lo 接口”,是在 A 还是 B 上建呢?
    2. 因为之前看到 openyurt 有个隧道方案,但前提是要节点先加到集群里 https://openyurt.io/zh/docs/user-manuals/network/raven ,所以想试试先把节点加到集群再部署 raven 。但现在用 socks5 方式节点加入集群 kubelet 还会报错,猜测是没走 socks5 代理导致的。尝试在 /etc/kubernetes/kubelet.conf 加入 proxy-url ,但每次重启 kubelet 新增的 proxy-url 都会消失,应该怎么让 kubelet 只在访问 apiserver 时走代理呢?
    ```
    Sep 07 22:57:50 debian11 kubelet[21429]: E0907 22:57:50.210450 21429 kubelet.go:2466] "Error getting node" err="node \"debian11\" not found"
    Sep 07 22:57:50 debian11 kubelet[21429]: E0907 22:57:50.311075 21429 kubelet.go:2466] "Error getting node" err="node \"debian11\" not found"
    Sep 07 22:57:50 debian11 kubelet[21429]: E0907 22:57:50.337677 21429 file_linux.go:61] "Unable to read config path" err="path does not exist, ignoring" path="/etc/kubernetes/manifests"
    Sep 07 22:57:50 debian11 kubelet[21429]: E0907 22:57:50.337862 21429 controller.go:144] failed to ensure lease exists, will retry in 200ms, error: Get "https://172.xx.yy.11:6443/apis/coordination.k8s.io/v1/namespaces/kube-node-lease/leases/debian11?timeout=10s": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
    Sep 07 22:57:50 debian11 kubelet[21429]: E0907 22:57:50.412172 21429 kubelet.go:2466] "Error getting node" err="node \"debian11\" not found"

    ```
    3. 请问 wg 搭建有没有比较好的资料参考,谢谢!
    fighterhit
        6
    fighterhit  
    OP
       2023-09-08 11:34:05 +08:00
    @zzlyzq 根据上面第 2 种方式:
    1. 在 B 上新增 lo:1 ip: 172.xx.yy.zz ,如下
    ```
    lo:1: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
    inet 172.xx.yy.zz netmask 255.255.0.0
    loop txqueuelen 1000 (Local Loopback)
    ```
    2. 在 A 上执行 ssh -R 6443:新增的 lo:1 ip:6443 -N B-user@B-ip -p B-port
    3. 在 B 的 config server 换为 lo:1 ip ,执行 kubectl get po 报错:The connection to the server 172.xx.yy.zz:6443 was refused - did you specify the right host or port?
    zzlyzq
        7
    zzlyzq  
       2023-09-08 13:37:43 +08:00
    @fighterhit 可以加 qq 聊:1405903283
    zzlyzq
        8
    zzlyzq  
       2023-09-08 14:11:24 +08:00
    @fighterhit 小朋友,刚想起来,自己打隧道恐怕不行。
    虽然打隧道可以让你的 edge 和 datacenter 之间形成整体内部路由环境,但是 k8s 需要二层进行容器流量互通,所以你打的隧道是三层互通,对于 k8s 需要使用 calicao 的 ipip 功能,有些复杂。
    就像你说的,可以用 openyurt 或者 kubesphere 的 edge 等软件实现更好一些。
    fighterhit
        9
    fighterhit  
    OP
       2023-09-08 15:17:11 +08:00
    @zzlyzq 对,现在想先用 vpn 连 apiserver ,然后再部署 raven 之类的;不然现在似乎 kubelet 没法连 apiserver
    dropdatabase
        10
    dropdatabase  
       2023-09-15 10:41:08 +08:00
    1.解决边缘节点和 apiserver 通信问题;
    ```
    ssh -NL 127.0.01:6443:x.x.x.x:6443 -o ServerAliveCountMax=3 -o ServerAliveInterval=15 -o ExitOnForwardFailure=yes -p port [email protected]
    ```
    2.解决 kubelet 与 apiserver 通信问题;可以在 kubelet 的配置中添加 httpProxy 和 httpsProxy 字段来指定代理地址。
    ```
    apiVersion: kubelet.config.k8s.io/v1beta1
    kind: KubeletConfiguration
    ...
    proxyConfig:
    httpProxy: http://localhost:1080
    httpsProxy: http://localhost:1080
    ...
    ```
    fighterhit
        11
    fighterhit  
    OP
       2023-09-15 20:55:53 +08:00
    @dropdatabase cni calico 怎么解决呢?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3543 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 00:07 · PVG 08:07 · LAX 16:07 · JFK 19:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.