K3s + Harbor 端口冲突问题解决方案(Harbor 使用 80 端口)

K3s + Harbor 端口冲突问题解决方案(Harbor 使用 80 端口)

1. 环境概述

  • 操作系统:Linux(CentOS/Rocky 等)
  • K3s 版本:v1.34.5+k3s1(单节点)
  • Harbor 版本:v2.14.1,通过 Docker Compose 部署
  • Harbor 配置:Nginx 容器直接绑定主机 80 端口
  • K3s 网络插件 :默认使用 Traefik 作为 Ingress Controller,Service 类型为 LoadBalancer

2. 问题现象

完成 Harbor 部署后,在浏览器中访问 http://<主机IP>(例如 http://192.168.100.172),返回页面内容为:

复制代码
404 page not found

此页面为 Traefik 的默认 404 页面,而非 Harbor 的登录界面,说明请求被 Traefik 拦截,未能到达 Harbor 容器。

3. 问题分析

3.1 端口占用情况

通过 ss -antl 查看主机端口监听状态:

复制代码
LISTEN    0    4096    0.0.0.0:80     0.0.0.0:*
LISTEN    0    4096    [::]:80        [::]:*

80 端口确实被 Harbor 的 Nginx 容器占用(通过 docker ps 确认)。但为何访问仍会进入 Traefik?

3.2 K3s 默认 Traefik 行为

K3s 安装时会自动部署 Traefik Ingress Controller,并创建一个 LoadBalancer 类型的 Service:

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: traefik
  namespace: kube-system
spec:
  ports:
  - name: web
    port: 80
    targetPort: web
    nodePort: 31415
  - name: websecure
    port: 443
    targetPort: websecure
    nodePort: 32397
  type: LoadBalancer

K3s 自带的 service loadbalancer 组件(svclb-traefik)会监听主机端口,并通过 iptables 规则 将目标为 EXTERNAL-IP:80 的流量 DNAT 到 Traefik Pod 的 nodePort(如 31415)。这些规则优先级高于 Harbor 直接绑定的端口,导致请求被劫持。

3.3 iptables 规则验证

在主机上执行以下命令,可以看到相关 DNAT 规则:

bash 复制代码
iptables -t nat -L PREROUTING -n -v

输出类似:

复制代码
DNAT       tcp  --  0.0.0.0/0   192.168.100.172   tcp dpt:80 to:10.43.160.149:31415

其中 10.43.160.149 是 Traefik Service 的 ClusterIP,31415 是 NodePort。正是这条规则将原本发往主机 80 端口的流量重定向到了 Traefik Pod,从而绕过了 Harbor 的 Nginx 容器。

4. 解决方案

核心思路:移除或修改 Traefik Service 对主机 80 端口的监听,释放该端口给 Harbor 使用。

由于用户明确要求 Harbor 使用 80 端口且不能修改 Harbor 配置,因此只能调整 Traefik 的暴露方式。

4.1 方案一:将 Traefik 的 web 端口改为其他端口(推荐)

修改 traefik Service,将 web 端口的 port80 改为其他未占用端口(例如 81)。这样 K3s 的 svclb 组件将不再监听主机 80 端口,原有的 iptables DNAT 规则会被自动清理。

4.2 方案二:完全删除 Traefik Service 的 web 端口条目

如果不需要通过 Traefik 暴露任何 HTTP 服务,可以删除 web 端口条目,仅保留 websecure(443)端口。但这样会导致所有 HTTP Ingress 无法工作,一般不建议。

5. 操作步骤(以修改端口为例)

5.1 编辑 Traefik Service

bash 复制代码
kubectl edit service -n kube-system traefik

5.2 修改端口配置

找到 ports 部分,将 web 端口的 port 值从 80 改为 81

yaml 复制代码
ports:
- name: web
  nodePort: 31415
  port: 81          # 原为 80,改为 81
  protocol: TCP
  targetPort: web
- name: websecure
  nodePort: 32397
  port: 443
  protocol: TCP
  targetPort: websecure

保存退出后,K3s 会自动更新 Service 和相关的 iptables 规则。

5.3 验证修改结果

bash 复制代码
kubectl get service -n kube-system traefik

输出应显示:

复制代码
NAME      TYPE           CLUSTER-IP      EXTERNAL-IP       PORT(S)                      AGE
traefik   LoadBalancer   10.43.160.149   192.168.100.172   81:31415/TCP,443:32397/TCP   127m

此时主机 80 端口已不再被 Traefik 占用,仅 Harbor Nginx 容器监听:

bash 复制代码
ss -antl | grep :80

应只显示 Harbor 的监听。

6. 验证结果

在浏览器中访问 http://192.168.100.172(或你的主机 IP),应看到 Harbor 的登录页面,而非 Traefik 的 404 页面。若仍无法访问,检查 Harbor 容器状态及防火墙规则。

7. 原理说明

7.1 K3s 的 LoadBalancer 实现

K3s 使用内置的 service loadbalancer 组件(由 svclb Pod 实现)为 LoadBalancer 类型的 Service 分配外部 IP。该组件在每个节点上运行一个 Pod,该 Pod 通过 netlinkiptables 在主机上创建规则,将发往 Service 外部 IP 的流量 DNAT 到 Service 的 ClusterIP 或 NodePort。对于 traefik Service,这些规则会拦截所有目的端口为 80 和 443 的流量,并转发到 Traefik Pod。

7.2 端口冲突的根本原因

  • 直接绑定 :Harbor 的 Nginx 容器通过 Docker 的 -p 80:8080 直接绑定主机 80 端口,这是用户空间的端口监听。
  • 内核空间劫持 :iptables 规则位于内核的 PREROUTING 链,优先级高于用户空间进程的监听。当请求到达主机时,内核首先检查 iptables 规则,匹配的流量会被直接 DNAT 到目标地址,用户空间的应用程序(如 Harbor Nginx)根本收不到数据包。

因此,尽管 ss 显示 80 端口被 Harbor 占用,实际上流量在进入应用层之前已被重定向。

7.3 解决方法的核心

通过修改 Traefik Service 的 port 值,使 K3s 的 svclb 不再创建针对主机 80 端口的 iptables 规则。原有的 DNAT 规则会在 Service 更新后被自动删除,从而让流量正常流入 Harbor 容器。

8. 注意事项

  • 修改 Traefik Service 后,所有原本通过 HTTP(80端口)访问的 Ingress 资源将无法通过默认的 80 端口访问。如果需要继续使用 HTTP Ingress,可以考虑:
    • 将 Ingress 的端口改为 81(即访问 http://<IP>:81),但需在 Ingress 规则中指定。
    • 或者使用 HTTPS(443)替代 HTTP。
  • 如果未来需要恢复 Traefik 对 80 端口的监听,只需再次编辑 Service,将 port 改回 80 即可。
  • 确保防火墙(如 firewalld、iptables)没有额外限制 80 端口。Harbor 容器正常监听后,应能正常访问。

9. 总结

通过调整 K3s 中 Traefik Service 的端口映射,成功释放了主机 80 端口给 Harbor 使用,解决了因 iptables 规则优先级导致的端口冲突问题。该方法无需修改 Harbor 配置,保持了 Harbor 使用 80 端口的原意,且操作简单、可回滚,适用于单节点 K3s 环境。

相关推荐
SelectDB13 小时前
Litefuse 开源并推出单进程轻量模式,25 秒就能跑起来的 Agent 可观测与评估平台
运维·后端·自动化运维
XIAOHEZIcode2 天前
Linux系统鼠标偏移常见原因以及修复方案
linux·运维·游戏
用户0328472220703 天前
如何搭建本地yum源(上)
运维
大树886 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠6 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质6 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
Inhand陈工6 天前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
酣大智6 天前
ARP代理--工作原理
运维·网络·arp·arp代理
shushangyun_6 天前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化
施努卡机器视觉6 天前
SNK施努卡侧滑门锁上滑轮总成自动化装配线,从零件到组件,全流程精密制造方案
运维·自动化·制造