本来在服务器上跑了一台 Nginx 使用了 80 端口, 作为下载服务器。某一天, 我想安装一个 k8s 的开发环境。鉴于我的机器是台老破小, 所以装上了 k3s。当时没太注意, 第二天发现下载服务器全部报 404 了。
虽然现在容器化方便了很多,但这也只是 应用层 上的。而 核心技术和原理 依旧是那些。万事逃不过一个 道理和规则 。 希望大家都能夯实基础, 不要和我一样临阵抓瞎!
一天,发现服务器上 80 端口不能正常访问了, 无论怎么都是 404 page not found
。这就奇怪了。
ssh 登录终端, 查看端口监听情况, nginx 服务器启动的好端端的在那里?
netstat -tunpl |grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1103/nginx: master
tcp 0 0 0.0.0.0:31807 0.0.0.0:* LISTEN 314008/k3s server
tcp6 0 0 :::80 :::* LISTEN 1103/nginx: master
netstat-tunpl.png
这就奇怪了啊?即使使用 curl 127.0.0.1
走本地结果也是 404 page not found
。
即使关闭 nginx, 依然可以 tenlet, 并得到一个 http 服务
stop-nginx-and-telnet-80.png
一时间无数神兽在脑中奔腾而过。怎么路由就过去不去呢?中 内存马 了?
冷静下来, 重新整理一下现象。
一步一步来
在搜索了无数类似 怎么不监听端口但能接受流量, 内存马, 使用 dev 设备开启服务方式 等问题无果之后
冷静下来, 决定一个一个停服。
docker
,问题存在k3s
, 问题消失。那么问题一定在 k3s
上, 至少不是被黑了。
kgs.png
使用命令 kubectl get service -n kube-system
看到 k3s 默认安装中确实又一个和平常使用的方式不一样 traefik LoadBalancer ...
或许这个有关
查找了 k3s 和 traefik 的官方文档, 没有找到和这里相关的信息。
仔细思考, k8s
中网络转发方案大概以下几种 iptables, ipvs, eBPF
。
eBPF
需要开启内核 xxx 功能支持, 而且也不是主流, k3s 默认情况下应该是不会开的。iptables, ipvs
都是需要修改 iptables(netfilter)
规则这里补充以下, 虽然常说
iptables 防火墙
, 但iptables
应该算netfilter
的一个命令行客户端。实际使用iptables
操作的还是内核中netfilter 链/表
规则。
使用 iptables -L -n -t nat
查看, 果然找到了 80 端口相关的信息。
iptables-nL-nat.png
继续跟中,找到了 dameonset/svclb-traefik
下的 pod。
kgp.png
重新把思路聚集回来, 思考
还真被我想到了 PREROUTING
和 POSTROUTING
。翻阅几年前的笔记 iptables 基础知识和基本用法, 还是不得其解。
事后回顾: iptables 基础知识和基本用法[1] 在本问题中是有一定缺陷的。
重新搜索相关 iptables
的相关文档, 找到了一篇还不错的 iptables详解(1):iptables概念[2] 。仔细阅读, 看到 PrrRouting(内核态) 与 application(用户态) 之间的关系之后瞬间茅塞顿开。
netfilter-kernel-and-user-space.png
那么原因就很明显了
PreRouting
链, 将流量转发到 k3s 的 svclb-traefik
服务上。svclb-traefik
服务在根据 ingress
将流量转发到对应的后端服务。3.
中没有命中 ingress
规则而无转发, 因此 traefik
就走默认行为, 影响 404 not found
。netfilter
不能能对 IP
劫持流量, 也能在其他地方行使规则。参考 netfilter hooks[3]
nf-hooks.png
[1]
iptables 基础知识和基本用法: https://tangx.in/2017/08/31/iptables-basic-theory-and-useage/
[2]
iptables详解(1):iptables概念: https://www.zsythink.net/archives/1199
[3]
netfilter hooks: https://wiki.nftables.org/wiki-nftables/index.php/Netfilter_hooks