端口说明
使用kubeasz 安装 k8s 后,暴露的端口。会被扫描,需要仅在 集群内部访问
- udp (不需要处理)
1 2 3
| 53 kube-dns-upstream 68 dhclient,服务器自带分配 IP 123 chronyd
|
- tcp (需要处理)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| 111 nfs rpc 179 calico-bird 2379 etcd 2380 etcd 5000 docker-registry 6443 kube-lb, kube-apiserver 9100 node_exporter 9253 kube-dns-upstream 9353 kube-dns-upstream 10248 kubelet 10249 kube-proxy 10250 kubelet 10256 kube-proxy 10257 kube-controller 10259 kube-scheduler 30900 prometheus-kube-prometheus-operator 30901 prometheus-kube-prometheus-prometheus 30902 prometheus-kube-prometheus-alertmanager 30903 prometheus-grafana 55443 harbor(自定) 55080 harbor (自定)
|
- tcp (不需要处理),仅 localhost(127.0.0.1) 访问
1 2 3 4 5
| 1514 docker-proxy (docker节点会有) 9099 calico-felix 42399 containerd (可能不是这个端口,随机)
8080 kube-dns-upstream 绑定到IP 169.254.20.10 仅 169.254.20.10:8080 能访问
|
这里封 raw 链是因为 有docker或者k8s端口,免得区分
1 2 3 4 5 6 7 8 9 10 11 12
| ports="111 179 2379 2380 5000 6443 9100 9253 9353 10248 10249 10250 10256 10257 10259 30900 30901 30902 30903 55443 55080" for port in $ports; do iptables -t raw -I PREROUTING -p tcp --dport $port -j DROP iptables -t raw -I PREROUTING -p tcp -s 192.168.1.0/24 --dport $port -j ACCEPT iptables -t raw -I PREROUTING -p tcp -s 172.20.0.0/16 --dport $port -j ACCEPT iptables -t raw -I PREROUTING -p tcp -s 10.68.0.0/16 --dport $port -j ACCEPT iptables -t raw -I PREROUTING -p tcp -m iprange --src-range 192.168.2.100-192.168.2.200 --dport $port -j ACCEPT iptables -t raw -I PREROUTING -p tcp -s localhost --dport $port -j ACCEPT iptables -t raw -I PREROUTING -p tcp -s 192.168.2.2 --dport $port -j ACCEPT done
iptables-save > /etc/sysconfig/iptables
|
8080 不需要操作
1 2 3 4 5 6 7
| ports="8080" for port in $ports; do iptables -I INPUT -p tcp --dport $port -j DROP iptables -I INPUT -p tcp -d 169.254.20.10 --dport $port -j ACCEPT done
iptables-save > /etc/sysconfig/iptables
|
下面几节反复在 raw、mangle、DOCKER、INPUT 之间试探,原因是同一条规则写在不同位置效果差别很大。把包在 netfilter 里的路径摊开就清楚了:
1 2 3 4 5 6 7 8 9 10
| 网卡收包 │ ├─ raw PREROUTING ← 在连接跟踪之前(NOTRACK 就写在这里) ├─ conntrack ← 连接跟踪在这里建表 ├─ mangle PREROUTING ├─ nat PREROUTING ← DNAT 在这里发生!docker -p / NodePort 就是它做的 │ └─ 路由决策 ├─ 目的是本机 ──→ mangle INPUT → filter INPUT → 本地进程 └─ 需要转发 ──→ mangle FORWARD → filter FORWARD → nat POSTROUTING → 出网卡
|
这张图能解释三件事。
一、为什么 NodePort 和 docker -p 的端口在 INPUT 链上封不住。
nat PREROUTING 里的 DNAT 已经把 --dport 从”你想封的那个端口”改成了容器/Pod 里的端口。等包走到 filter INPUT 时,--dport 30900 这个条件根本匹配不上了(而且如果目的变成了 Pod IP,它走的是 FORWARD 而不是 INPUT,连 INPUT 链都不经过)。所以想按原始端口拦,只能在 DNAT 之前下手,也就是 raw 或 mangle 的 PREROUTING。
反过来,--network host 的容器端口就是宿主端口、没有 DNAT,用 INPUT 完全没问题——这也是下面两节位置不同的根本原因。
二、选 raw 而不是 mangle 是有代价的。
raw 在连接跟踪之前,此时内核还不知道这个包属于哪条连接。好处是最早、最省开销(NOTRACK 正是写在这里);代价是你写不出基于连接状态的规则:
1 2
| -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
|
而 mangle PREROUTING 在 conntrack 之后、DNAT 之前,既躲过了 DNAT 改端口的问题,又能用连接状态做精确放行——“默认拒绝 + 放行已建立连接”这种标准写法只有在这里(或更后面)才写得出来。
三、为什么最后倒向 mangle。
calico 的 felix 会在 raw 表里插入自己的 cali-PREROUTING 链做策略和 NAT 前处理,手工规则和它同处一表,容易被顺序或跳转搅乱;而它对 mangle PREROUTING 的介入相对少。所以文末”建议直接封锁 mangle 链”这个经验判断是有依据的,不是随便选的——查看规则时也建议 iptables -t raw -S 和 iptables -t mangle -S 都看一遍,确认自己的规则没有被别人的链抢先跳走。
一句话总结取舍:要拦 DNAT 之前的原始端口 → 用 mangle PREROUTING;要极致省开销或做 NOTRACK → 用 raw;只是宿主自己的端口 → INPUT 最直观。
允许访问的 IP
localhost,10.68.0.0/16, 172.20.0.0/16, 192.168.1.0/24, 192.168.2.2, 192.168.2.100 - 192.168.2.200
iptables表的优先级:raw>mangle>nat>filter
一般的端口
eg: 80,443 等
1 2 3 4 5 6 7 8 9 10 11 12
| ports="80 443 " for port in $ports; do iptables -I INPUT -p tcp --dport $port -j DROP iptables -I INPUT -p tcp -s 192.168.1.0/24 --dport $port -j ACCEPT iptables -I INPUT -p tcp -s 172.20.0.0/16 --dport $port -j ACCEPT iptables -I INPUT -p tcp -s 10.68.0.0/16 --dport $port -j ACCEPT iptables -I INPUT -p tcp -m iprange --src-range 192.168.2.100-192.168.2.200 --dport $port -j ACCEPT iptables -I INPUT -p tcp -s localhost --dport $port -j ACCEPT iptables -I INPUT -p tcp -s 192.168.2.2 --dport $port -j ACCEPT done
iptables-save > /etc/sysconfig/iptables
|
k8s
1 2 3 4 5 6 7 8 9 10 11 12
| ports="111 179 2379 2380 5000 6443 9100 9253 9353 10248 10249 10250 10256 10257 10259" for port in $ports; do iptables -I INPUT -p tcp --dport $port -j DROP iptables -I INPUT -p tcp -s 192.168.1.0/24 --dport $port -j ACCEPT iptables -I INPUT -p tcp -s 172.20.0.0/16 --dport $port -j ACCEPT iptables -I INPUT -p tcp -s 10.68.0.0/16 --dport $port -j ACCEPT iptables -I INPUT -p tcp -m iprange --src-range 192.168.2.100-192.168.2.200 --dport $port -j ACCEPT iptables -I INPUT -p tcp -s localhost --dport $port -j ACCEPT iptables -I INPUT -p tcp -s 192.168.2.2 --dport $port -j ACCEPT done
iptables-save > /etc/sysconfig/iptables
|
docker 直接使用host 网络的端口(推荐直接使用 raw)
eg 5432 3306
--network host 的容器和宿主共享 netns,它的端口就等于宿主进程的端口,流量走 PREROUTING → INPUT 本地投递,根本不经过 FORWARD 路径上的 DOCKER 链,规则写在 DOCKER 里一条都命中不了,用 INPUT 就行(标题里说的 raw 表 PREROUTING 也一样有效)。
顺带说明:DOCKER 链本身是 dockerd 自己管理的,容器启停、端口发布变化或者 docker 重启时会被重建清空,手工插进去的规则会静默消失。如果要处理的是 bridge 模式下发布出来的端口,规则应该写到 DOCKER-USER 链,那是官方留给用户的位置。
1 2 3 4 5 6 7 8 9 10 11 12
| ports="5432 3306 " for port in $ports; do iptables -I INPUT -p tcp --dport $port -j DROP iptables -I INPUT -p tcp -s 192.168.1.0/24 --dport $port -j ACCEPT iptables -I INPUT -p tcp -s 172.20.0.0/16 --dport $port -j ACCEPT iptables -I INPUT -p tcp -s 10.68.0.0/16 --dport $port -j ACCEPT iptables -I INPUT -p tcp -m iprange --src-range 192.168.2.100-192.168.2.200 --dport $port -j ACCEPT iptables -I INPUT -p tcp -s localhost --dport $port -j ACCEPT iptables -I INPUT -p tcp -s 192.168.2.2 --dport $port -j ACCEPT done
iptables-save > /etc/sysconfig/iptables
|
k8s 网络以及 端口映射的端口
封 raw 链
eg: 30900 30901
1 2 3 4 5 6 7 8 9 10 11 12
| ports="30900 30901" for port in $ports; do iptables -t raw -I PREROUTING -p tcp --dport $port -j DROP iptables -t raw -I PREROUTING -p tcp -s 192.168.1.0/24 --dport $port -j ACCEPT iptables -t raw -I PREROUTING -p tcp -s 172.20.0.0/16 --dport $port -j ACCEPT iptables -t raw -I PREROUTING -p tcp -s 10.68.0.0/16 --dport $port -j ACCEPT iptables -t raw -I PREROUTING -p tcp -m iprange --src-range 192.168.2.100-192.168.2.200 --dport $port -j ACCEPT iptables -t raw -I PREROUTING -p tcp -s localhost --dport $port -j ACCEPT iptables -t raw -I PREROUTING -p tcp -s 192.168.2.2 --dport $port -j ACCEPT done
iptables-save > /etc/sysconfig/iptables
|
建议直接封锁 mangle 链
raw 链等也会被 calico 等 规则改写,查看 mangle 未被操作
使用 calico 可以用 calico 的网络规则,不过需要先安装 各种 crd
1 2 3 4 5 6 7 8 9 10 11 12
| ports="30900 30901" for port in $ports; do iptables -t mangle -I PREROUTING -p tcp --dport $port -j DROP iptables -t mangle -I PREROUTING -p tcp -s 192.168.1.0/24 --dport $port -j ACCEPT iptables -t mangle -I PREROUTING -p tcp -s 172.20.0.0/16 --dport $port -j ACCEPT iptables -t mangle -I PREROUTING -p tcp -s 10.68.0.0/16 --dport $port -j ACCEPT iptables -t mangle -I PREROUTING -p tcp -m iprange --src-range 192.168.2.100-192.168.2.200 --dport $port -j ACCEPT iptables -t mangle -I PREROUTING -p tcp -s localhost --dport $port -j ACCEPT iptables -t mangle -I PREROUTING -p tcp -s 192.168.2.2 --dport $port -j ACCEPT done
iptables-save > /etc/sysconfig/iptables
|
开机自启
- systemd 不推荐 ,docker 服务,k8s 服务未启动时,会自启失败
1 2
| systemctl enable iptables systemctl restart iptables
|
- crontab
手动执行,或者 crontab 添加自动启动
1
| iptables-restore < /etc/sysconfig/iptables
|
重启自启动
1
| (crontab -l|grep -v "@reboot iptables-restore < /etc/sysconfig/iptables";echo "@reboot iptables-restore < /etc/sysconfig/iptables")| crontab
|
推荐使用脚本
/etc/iptables_rule.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| source /etc/profile # 默认的环境变量 /usr/bin:/bin 没有 iptables 命令 export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH
ports="111 179 2379 2380 5000 6443 9100 9253 9353 10248 10249 10250 10256 10257 10259 30900 30901 30902 30903 55443 55080" for port in $ports; do iptables -t raw -I PREROUTING -p tcp --dport $port -j DROP iptables -t raw -I PREROUTING -p tcp -s 10.0.10.0/24 --dport $port -j ACCEPT iptables -t raw -I PREROUTING -p tcp -s 172.20.0.0/16 --dport $port -j ACCEPT iptables -t raw -I PREROUTING -p tcp -s 10.68.0.0/16 --dport $port -j ACCEPT iptables -t raw -I PREROUTING -p tcp -s localhost --dport $port -j ACCEPT done iptables -t raw -I PREROUTING -p tcp -s 172.18.0.0/16 --dport 55443 -j ACCEPT iptables -t raw -I PREROUTING -p tcp -s 172.18.0.0/16 --dport 55080 -j ACCEPT iptables -t raw -I PREROUTING -p tcp -s 172.18.0.0/16 --dport 5000 -j ACCEPT
echo `date` >> /root/reboot.txt echo init_iptables_sucess >> /etc/reboot.txt
|
加入自启
1
| (crontab -l|grep -v "@reboot /bin/sh /etc/iptables_rule.sh";echo "@reboot /bin/sh /etc/iptables_rule.sh")| crontab
|
补充
老版本封锁 harbor 时发现, 使用 docker 无法拉取镜像
systemctl status docker
1 2
| /usr/bin/docker-proxy -proto tcp -host-ip 127.0.0.1 -host-port 55443 -container-ip 172.21.0.2 -container-port 8443 /usr/bin/docker-proxy -proto tcp -host-ip 127.0.0.1 -host-port 55080 -container-ip 172.21.0.2 -container-port 8443
|
harbor-core 会连接 registry 的 5000 端口
harbor 机器新增规则
1 2 3
| iptables -t raw -I PREROUTING -p tcp -s 172.21.0.0/16 --dport 55443 -j ACCEPT iptables -t raw -I PREROUTING -p tcp -s 172.21.0.0/16 --dport 55080 -j ACCEPT iptables -t raw -I PREROUTING -p tcp -s 172.21.0.0/16 --dport 5000 -j ACCEPT
|