k3s 中的负载均衡如何能够直接把域名解析到当前节点的 pod? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
cyjme
V2EX    Kubernetes

k3s 中的负载均衡如何能够直接把域名解析到当前节点的 pod?

  •  
  •   cyjme 2022-12-08 14:47:18 +08:00 2543 次点击
    这是一个创建于 1090 天前的主题,其中的信息可能已经有所发展或是发生改变。

    背景:

    1. 最近刚开始使用 k8s, 用多台服务器组了集群,服务器在不同地区,服务器之间网速较慢。

    2. load balancer 用的是 k3s 自带的,ingress type 是 traefik 。

    3. 我将网站 pod 部署在了 nodeA 节点, nodeA, nodeB 不在同一地区。

    然后我理解的目前我的网站被访问时的路径是:

    user requset ---[1]--> node A(svclb-pod) ---[2]---> node B(traefik service 所在节点) ---[3]---> nodeA(website-pod)-----> response 反向传回去

    我希望请求到 load balancer 之后,直接就能转发到 nodeA (website-pod),而不经过跨地区的网络传输。

    也就是 user request -----> nodeA(svclb-pod)---->nodeA(website-pod)---->response

    这样不跨地区访问 nodeB 之后,网站速度就能更快一些。请问有办法实现这种需求吗?

    刚接触 k8s ,如果有描述不恰当的地方还请谅解。

    7 条回复    2024-03-04 09:55:39 +08:00
    GopherDaily
        1
    GopherDaily  
       2022-12-08 15:15:18 +08:00
    Google is your friends, https://www.google.com.hk/search?q=k8s+loadbalancer+local&oq=k8s+loadbalancer+local&aqs=chrome..69i57j0i22i30l2j0i10i22i30j0i390l5.7176j0j7&sourceid=chrome&ie=UTF-8

    https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip

    .spec.externalTrafficPolicy - denotes if this Service desires to route external traffic to node-local or cluster-wide endpoints. There are two available options: Cluster (default) and Local. Cluster obscures the client source IP and may cause a second hop to another node, but should have good overall load-spreading. Local preserves the client source IP and avoids a second hop for LoadBalancer and NodePort type Services, but risks potentially imbalanced traffic spreading.
    cyjme
        2
    cyjme  
    OP
       2022-12-08 18:33:16 +08:00
    @GopherDaily 感谢。

    根据文档看起来好像是和 externalTrafficPolicy 有一些关系,我做了尝试之后,发现 externalTrafficPolicy 可以产生如下如下影响:

    cluster: nodeA, nodeB, nodeC

    blog-servcie ( type: NodePort, port:30025), blog-pod 只运行在 nodeA ,

    将 externalTrafficPolicy 设为 Local 后,只有 http://nodeA:30025 可以访问,nodeB:30025 无法访问。externalTrafficPolicy 默认的 Cluster 所有节点都可以访问这个端口。


    ** 但是这个并不能解决当下的问题: **

    以 http://blog.domain 为例,ip 指向 nodeA, blog-pod 运行在 nodeA, nodeB, nodeC 三个节点上,blog-service 的 externalTrafficPolicy 设为 Local ,当访问 blog.domain 的时候,nodeB 和 nodeC 依然会分流收到请求。

    期望结果是 只有 nodeA 上的 blog-pod 能收到请求。

    我查看了 nodeA 的 svclb-pod 中的 iptables ,它只是把所有流量都转发到了 traefik 的 service ,而 traefik pod 实际只运行在 nodeB ,所以流量必然要先经过 nodeB ?

    有没有什么其他方法呢?
    GopherDaily
        3
    GopherDaily  
       2022-12-08 22:54:19 +08:00
    理论上 Service 的 externalTrafficPolicy 设置为 Local 后,从外部访问 Service 的流量到达某个节点后是不会再被路由到的另外一个节点的。

    所以外部流量到 nodeA 上后会去找 nodeA 上的 traefik ,而不会尝试找 nodeB 上的 traefik.
    traefik 收到这个请求后将请求转发给 website 这个 服务,这次转发依赖其他配置了。

    你 的 svclb-pod 是什么意思? Service 是一个逻辑概念,Traefik 是实际的 Pod


    以阿里云为例的常见架构:
    固定 IP 的 SLB 用来承载 DNS 解析,
    Nginx/Envoy 做为 IngressGateway ,并注册类似为 LoadBalancer 的 Service
    某个 Controller 监听这个 Service 并自动注册到 SLB 做为后端服务
    nxcdJaNnmyF9O90X
        4
    nxcdJaNnmyF9O90X  
       2022-12-08 23:20:05 +08:00
    在 k3s 中,负载均衡是由 ingress controller 来实现的,具体实现方式取决于选择的 ingress controller 类型。

    对于您所描述的情况,我们可以通过设置 ingress 的路由规则来实现直接将域名解析到当前节点的 pod 。

    首先,您需要为您的应用创建一个 ingress 资源,并设置域名和路径的路由规则。例如:
    apiVersion: networking.k8s.io/v1bet1
    kind: Ingress
    metadata:
    name: my-ingress
    spec:
    rules:
    - host: my-website.com
    http:
    paths:
    - path: /
    backend:
    serviceName: my-website
    servicePort: 80

    然后,您需要为您的 ingress 资源添加一个节点选择器,以确保请求只能被路由到目标节点上。例如:

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
    name: my-ingress
    labels:
    app: my-website
    annotations:
    # 指定 ingress 资源只能被 nodeA 节点上的 ingress controller 处理
    ingress.kubernetes.io/affinity: "cookie"
    ingress.kubernetes.io/session-cookie-name: "ingress-lb-node"
    ingress.kubernetes.io/session-cookie-enabled: "true"
    ingress.kubernetes.io/session-cookie-max-age: "86400"
    ingress.kubernetes.io/session-cookie-generate-request-header: "true"
    spec:
    rules:
    - host: my-website.com
    http:
    paths:
    - path: /
    backend:
    serviceName: my-website
    servicePort: 80
    # 指定 ingress 资源只能被 nodeA 节点上的 ingress controller 处理
    nodeSelector:
    kubernetes.io/hostname: nodeA
    cyjme
        5
    cyjme  
    OP
       2022-12-09 18:07:43 +08:00
    @GopherDaily

    今天折腾了很多,这里重新梳理下,我前面的关注点太多了,下面只关注流量到达 traefik pod

    前面的 svclb-pod 是由 k3s 自带的一个 Load Balancer(Klipper LB)创建的 daemon 。


    **当前的环境:**

    有一个类型为 LoadBalancer 的 traefik service, load balance 是通过 KipperLB 实现的。Traefik
    Service 创建了 Daemon Sets: "svclb-traefik",运行在每一个节点上,监听 80/443 端口。

    将 traefik deployment scale 到每个节点上都有一个,并且开启了 access log 。

    设置 traefik service 的 spec.externalTrafficPolicy = Local 。



    **问题:**

    理论上来说,应该只有被访问的节点上的 traefik pod 可以收到请求,但是目前是其他节点也可以收到。






    今天刚开始调试的时候看日志是大部分请求都到了同一个节点的,但是会有少量请求到其他节点,以为是配置生效了,怀疑可能是网络的问题(用了 zerotier ,k3s server --flannel-iface={zerotier-Iface}),worker node 在国外,网络质量不够高之类的,但是调试一番之后,其实还是配置没生效,只是我之前只请求一个 url ,似乎有某种机制让请求只到达一个节点?只要换了 url 其他节点也会收到大量请求。externalTrafficPolicy = Local 生效的话,应该是其他节点完全收不到请求才对。


    然后又查了一些其他资料,也有人遇到这个问题,但没有明确的答案。可能会和 k3s 的 Klipper LB 有关系,更细节的调试还要涉及到 cni, flannel 还有 k8s 的各种命令。但是我现在这方面知识缺失很多,排查问题过程很艰难。我周末把 k8s 的文档和网络相关的文档先看一遍,然后再重新排查这个问题,可能还要重新搞一个虚拟机环境,尝试不同的 lb 和 cni 配置。后续有结果了我再更新到这里。
    GopherDaily
        6
    GopherDaily  
       2022-12-09 22:12:09 +08:00
    @cyjme 不如贴一些 k get -n xxx all ,再给请求加一些日志
    xiaochong2020
        7
    xiaochong2020  
       2024-03-04 09:55:39 +08:00
    关掉 servicelb ,你会发现正常了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana   nbsp; 1575 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 16:23 PVG 00:23 LAX 08:23 JFK 11:23
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86