问题描述

最近在服务器上安装了轻量级 Kubernetes 发行版 K3s,并部署了一个简单的 Nginx 服务,希望通过 http://服务器IP:80 访问。然而,浏览器始终返回 404 Not Found,而 curl localhost:80 却能正常返回 Nginx 的欢迎页面。

经过排查,发现 K3s 默认安装的 Traefik 组件劫持了 80 端口,导致 Nginx 虽然监听 80 端口,但外部请求被 Traefik 拦截,最终返回 404。

问题分析

1. 为什么 Nginx 的 80 端口“失效”?

  • ss -tulnp 显示 Nginx 在监听 80 端口,但外部请求被 Traefik 拦截。
  • Traefik 是 K3s 默认的 Ingress 控制器,它会自动绑定 80 和 443 端口,接管所有 HTTP/HTTPS 流量。
  • Nginx 虽然运行,但 Traefik 优先处理请求,由于没有匹配的 Ingress 规则,返回 404。

2. Traefik 的工作原理

Traefik 是一个 云原生反向代理和 Ingress 控制器,主要功能:

  1. 自动发现 Kubernetes 服务,并根据 Ingress 规则路由流量。
  2. 默认监听 80(HTTP)和 443(HTTPS),拦截所有进入集群的 Web 请求。
  3. 动态配置路由,无需重启即可生效。

在 K3s 中,Traefik 会:

  • 自动创建 LoadBalancer 类型的 Service,绑定 80/443 端口。
  • 如果没有配置 Ingress 规则,访问任何路径都会返回 404

解决方案

方法 1:禁用 Traefik(推荐)

如果不需要 Traefik,可以在安装 K3s 时直接禁用:

curl -sfL https://get.k3s.io | sh -s - --disable traefik

这样 K3s 不会安装 Traefik,80 端口由 Nginx 直接接管。

方法 2:配置 Traefik 路由(适合需要 Ingress 的场景)

如果仍想使用 Traefik,可以创建 Ingress 规则,将流量正确路由到 Nginx:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
spec:
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-service  # 替换为你的 Nginx Service 名称
            port:
              number: 80

然后应用配置:

kubectl apply -f ingress.yaml

最终解决

由于我的需求只是运行一个简单的 Nginx,不需要 Kubernetes Ingress 功能,因此选择 卸载并重装 K3s,禁用 Traefik

# 卸载 K3s
/usr/local/bin/k3s-uninstall.sh

# 重新安装,禁用 Traefik
curl -sfL https://get.k3s.io | sh -s - --disable traefik

安装完成后,Nginx 成功接管 80 端口,浏览器访问正常!

总结

  • K3s 默认安装 Traefik,它会劫持 80/443 端口,导致 Nginx 无法直接接收外部请求。
  • 解决方案

    • 如果不需要 Ingress,安装时加 --disable traefik
    • 如果需要 Traefik,必须配置 Ingress 规则,否则会返回 404。
  • K3s 适合轻量级 Kubernetes,但需注意默认组件的影响

希望这篇博文能帮你解决类似问题!🚀

标签: k3s

评论已关闭