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

自行搭建 k8s ,怎么通过域名访问服务

  •  
  •   lingerr · 123 天前 · 3614 次点击
    这是一个创建于 123 天前的主题,其中的信息可能已经有所发展或是发生改变。

    问题描述

    1. 楼主最近在公网搭建了 Kubernetes (K8s) 集群,集群由三台具有公网 IP 的机器组成。目前使用 NodePort 方式访问服务,由于预算有限,没有使用公网负载均衡。
    2. 服务架构为前后端分离,前端通过 Nginx 启动,NodePort 端口为 30080 。访问方式为直接通过 IP:Port 进行访问。
    3. 现在是已有域名比如test.com解析到机器 A ,并在机器 A 上通过 80 端口反向代理到机器 A 、B 、C ,以实现通过域名访问服务。
    4. 有使用过 Ingress Controller, 但是还是使用的 nodeport 方式, 感觉多此一举

    问题

    请问是否有其他更好的方法来实现通过域名访问 K8s 集群中的服务?公司里面一般是怎么做的呢, 新手不太明白

    38 条回复    2024-08-13 17:25:17 +08:00
    lzh690554304
        1
    lzh690554304  
       123 天前
    ingress controller 是第一步
    lzh690554304
        2
    lzh690554304  
       123 天前
    还有一种模式叫做 hostnetwork
    THESDZ
        3
    THESDZ  
       123 天前
    ingress controller caddy/traefik
    wandehul
        4
    wandehul  
       123 天前
    企业服务还在乎 alb 那点钱 ? 流量费算是最便宜的部份了。 搞什么 nodeport ?人工运维的成本都要比 alb + 流量贵很多。
    lingerr
        5
    lingerr  
    OP
       123 天前
    @lzh690554304 @THESDZ 感谢, 我去看看
    lingerr
        6
    lingerr  
    OP
       123 天前
    @wandehul 企业服务肯定是不在乎的, 个人好像玩不起啊
    mightybruce
        7
    mightybruce  
       123 天前   ❤️ 4
    自己测试想怎么玩怎么玩,
    我只说一下在正式环境中不使用 nodeport,生产环境中是不许 NodePort ,NodePort 会在所有节点( VM )上打开一个特定的端口,并且发送到该端口的所有流量都将转发到该服务。

    此方法有很多缺点:
    每个端口只能提供一次服务
    您只能使用端口 30000–32767
    如果您的节点/ VM IP 地址更改,则需要处理

    正常情况都是通过各种 ingress controller 比如 nginx ingress 来访问的
    生产环境建议使用 Loadbalancer 和 Ingress ,四层( TCP/UDP )代理使用 Loadbalancer ,七层( HTTP/HTTPS )代理使用 Ingress 。
    另外也不是直接访问 ip 和端口,而是通过 ingress 去访问 service(clusterIP), service 再访问 pod
    mightybruce
        8
    mightybruce  
       123 天前
    ingress 是可以自建的,另外 ingress controller 也提供 NodePort 选项来访问。
    sujin190
        9
    sujin190  
       123 天前
    看来你对 Ingress 有误解啊,Ingress Controller 调整配置绑定到 host network 就可以绑定到宿主机的 80 和 443 端口了啊,然后直接域名解析到部署 Ingress Controller 的那个节点就好了啊,否则 Ingress Controller 还是通过 nodeport 导出的,不能绑定到 80 和 443 端口,域名解析自然也还是需要输入端口
    sujin190
        10
    sujin190  
       123 天前   ❤️ 1
    如果你有 lbs 的话,lbs 会绑定到 Ingress Controller 的 nodeport ,如果你没有 lbs ,那么简单点的做法就是调整 Ingress Controller pod 的网络配置使用 host 网络,让 Ingress Controller 的 80 和 443 端口直接绑定到宿主机的 80 和 443 端口,之后域名直接解析到宿主机 ip 就可以了
    lingerr
        11
    lingerr  
    OP
       123 天前
    @mightybruce 我也发现了
    wandehul
        12
    wandehul  
       123 天前
    个人玩,配通了 就 delete 了 , 十块钱就能让你拥有云运维经验。 不比你这 hostport 那 nginx 转发爽多了 。
    lingerr
        13
    lingerr  
    OP
       123 天前
    @sujin190 Ingress 还可以这样的使用啊, 老哥说的很详细
    JayZXu
        14
    JayZXu  
       123 天前
    ingress 默认启动就是 80 和 443 ,接管了本地反代,后面的东西直接在 k8s 里面改配置就行了
    sudosu
        15
    sudosu  
       123 天前   ❤️ 1
    rancher
    Daath
        16
    Daath  
       123 天前   ❤️ 1
    * 抛开外网怎么访问 k8s 里面的具体什么应用服务,在 k8s 的运行机制里面,pod 对外服务交由 svc 来暴露,所以在 pod 之间访问也一般都经过 svc
    * 当你使用 ingress controller 这类资源时,它也首先是作为应用服务 pod ,譬如 nginx-ingress-controller ,然后接收 k8s 的 ingress 配置来让 controller 这个 pod 服务知道怎么访问别的 namespace 下的 svc ,至此,从 controller 的 pod 到其他应用 pod 的链路就通了
    * 那么外网怎么访问服务,只需要考虑如何让外网访问到 ingress-controller ,那么是由 ingress-controller-svc 来描述,至于是采用 nodeport 或者 lb 类型,都是告知集群上节点机器宿主端口做映射到集群上 ingress-controller 的 svc 端口,从而实现外部访问
    guoguobaba
        17
    guoguobaba  
       123 天前
    假设你的 k8s 的 ip 是 ip1 ,你设置了一个 host1 对应到 ip1 ,无论是公共的 dns 解析还是你机器上的/etc/hosts 解析。
    然后在 ingress 里绑定一个 host1 对应到相关 cluster ip 就可以了。
    当然,你也可以开一个 node port 的 service ,然后用 host1:<node port>访问也可以。
    ingress 里绑定证书,你就可以用 https 访问

    如果你是多节点,也可以弄一个 SLB ,把 host1 绑定在 SLB 的 ip 上,这样 SLB 会自动负载均衡到所有 INGRESS 对应的 ip 上。
    Cola98
        18
    Cola98  
       123 天前
    traefik 做代理,就是需要配置 hosts 文件
    NevadaLi
        19
    NevadaLi  
       123 天前 via iPhone
    istio
    smilingsun
        20
    smilingsun  
       123 天前
    如果不使用云的负载均衡的话,也许可以参考这个使用 haproxy ?
    https://docs.k3s.io/datastore/cluster-loadbalancer
    kennylam777
        21
    kennylam777  
       123 天前
    @mightybruce 其實在正式的 LoadBalancer 上, 也是用 NodePort 的, 不然雲服務商的 LoadBalancer 如何連接到服務上? LoadBalancer 的實作會幫你把 NodePort 至雲上的對應都處理好, 可以看看 aws-load-balancer-controller 的實作。


    只是在生產環境上, Node Group 的端口不能直接全開到公網。

    @lingerr 自己玩的就直接用 HostPort 吧, 一般 ingress controller 都支持, 這樣最簡單了。
    moonlight010
        22
    moonlight010  
       123 天前
    使用 ingress controller 去访问 service,然后 service 去访问 pod ,这比较好吧
    nodeport 是对 k8s 集群每个机器上指定特定的端口提供对外暴露,测试的时候使用
    ingress 其实就是一个 nginx ,这个 ingress 比如使用的是 80 端口,然后可以配置二级域名解析到对应的 service ,比如 a.xx.com 解析到 tomcat 服务。b.xx.com 解析到 wordpress 服务,c.xx.com 解析到 springboot 服务等等,这样以来只暴露了 80 端口,而且这个端口是复用的,当然因为你是三台机器,可以配置 ingress nginx 是 nodeport 方式暴露 80 服务,然后可以使用 haproxy 配置一个配置云服务器 VIP(虚拟 ip),真正访问的域名,解析到这个 vip
    liuhai233
        23
    liuhai233  
       123 天前 via iPhone
    这个月刚把云 k8s 的服务迁移到自建 k3s 了,成本省了不少,可以参考我的迁移过程: https://dreamhunter2333.com/posts/k8s/install-k3s.html
    ysicing
        24
    ysicing  
       123 天前
    可以看看我写的 k3s 集群私有负载均衡的另一种选择 Tailscale ,k8s 跑也是可以的
    https://ysicing.me/k3s-tailscale-loadbalancer
    caicaiwoshishui
        25
    caicaiwoshishui  
       123 天前
    你还需要一个服务器,做 nginx 代理转发,
    1. 你的域名代理到这个服务器,这个服务的 nginx 的 upstram 设置为你的 k8s 对外的 ingress ip ,可以多个 ip 。
    2. 再通过 ingress 实现代理到具体 pod service
    wuoty
        26
    wuoty  
       123 天前
    如果不使用负载均衡的情况下使用 Ingress ,那么可以用 MetalLB 的 Layer2 模式,把用户的所有 443 和 80 的流量集中到一个节点上,再通过这个节点转发到其他节点上

    这个是 Nginx Ingress 提供的一种解决方案 https://kubernetes.github.io/ingress-nginx/deploy/baremetal/#a-pure-software-solution-metallb

    lingerr
        27
    lingerr  
    OP
       121 天前
    @Daath 我也知道 ingress 是做路由控制的, 但是自己搭建当时只有 nodeport 可用才有疑问
    lingerr
        28
    lingerr  
    OP
       121 天前
    @guoguobaba 明白了, 我就是想直接域名解析到服务, 不想再套一层 nodeport 的
    lingerr
        29
    lingerr  
    OP
       121 天前
    @JayZXu
    @wuoty
    @caicaiwoshishui
    @ysicing
    @liuhai233 感谢各位的回复, 我看看
    lingerr
        30
    lingerr  
    OP
       121 天前
    @kennylam777 你的看法和楼上 @lzh690554304 差不多, ingress 直接用 hostnetwork 就行了, 我了解一下
    lingerr
        31
    lingerr  
    OP
       121 天前
    @moonlight010 好像 ingress nginx 的 nodeport 方式没办法暴露 80 服务吧
    Daath
        32
    Daath  
       121 天前
    @lingerr #27 因为你使用 svc 的配置文件写了 nodeport 类型,然后认为每个应用服务得用他们自己 svc 配置 nodeport 暴露出来,那么访问的流量就直接经过他们得 svc 得 nodeport 端口到达各自服务,不过域名这些得自己应用去维护,这是一种解决方式。不过想要方便是就是应用服务得 svc 是用 clusterip 类型,然后让 ingress-controller 来配置通过什么域名,什么路径匹配访问到应用服务得 svc 即可,这样就只需要暴露 ingress-controller 自己的 svc 的 nodeport 或者 lb 类型,通常就暴露 80 和 443 端口,这样就运行 k8s 集群的主机都会接受 80 和 443 端口的流量转到 ingress-controller 里面,这样你域名的配置,以及 tls 证书都是 ingress-controller 来接管
    kennylam777
        33
    kennylam777  
       120 天前
    @lingerr HostPort 跟 HostNetwork 是兩碼事

    HostNetwork 會影響到 networking namespace, 比如說 HostNetwork 的 container 裡面 listen 0.0.0.0:80, 就是用 Host 的所有 IP listen 80, 因為 container 直接用 Host network(名字就說明了), 在 k8s 不定義甚麼也能曝露出去。

    但 HostPort 的話, container 裡面仍然是一個帶 Pod IP 的獨立 network interface, HostPort 只是將指定 Pod 端口在 Host 曝露出去。
    lingerr
        34
    lingerr  
    OP
       120 天前
    @kennylam777 感谢, 我去看看资料
    lingerr
        35
    lingerr  
    OP
       120 天前
    @Daath 感谢, 我去看看资料
    terencelau
        36
    terencelau  
       109 天前   ❤️ 1
    我用的是 [MetalLB]( https://metallb.universe.tf/) 和官方的 [ingress-nginx-controller]( https://kubernetes.github.io/ingress-nginx/) 在 metallb 里配置 External IP 以后(在这里应该是你的机器 A 的 IP ),启动 ingress-nginx 后会有一个 LoadBalancer 的 svc , 之后的所有 svc/ingress 可以就可以配 ClusterIP / 域名,controller 会解决其他问题

    如果想要把三台机器的 IP 都用上,最粗暴的方法是部署三个 ingress-nginx ,metallb 里写三个 ExternalIP ,然后 DNS 指向三个 IP 即可。
    naison
        37
    naison  
       108 天前
    直接使用 kubevpn ,在本地直接访问到集群内部的服务了,不需要这么复杂。https://github.com/kubenetworks/kubevpn
    lingerr
        38
    lingerr  
    OP
       105 天前
    @terencelau
    @naison 感谢, 我看看用法
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5805 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 180ms · UTC 03:16 · PVG 11:16 · LAX 19:16 · JFK 22:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.