Shell脚本配置容器网络策略:自动化规则与安全加固实战指南
目录导读
为什么需要Shell脚本管理容器网络?
容器化环境中,网络策略(NetworkPolicy)通常由Kubernetes的CNI插件(如Calico、Cilium)托管,但在裸机Docker、Podman或边缘计算场景中,Shell脚本直接操作iptables/nftables仍是最轻量、最可靠的解决方案。
核心价值:

- 原子化:避免频繁手动输入iptables命令导致规则冲突。
- 可审计:脚本存储于Git,每次变更可追溯。
- 动态适配:根据容器ID或标签自动更新规则。
环境准备:依赖工具与基础概念
执行前确保以下组件就绪:
iptables(或nftables,本文以iptables示例)jq(解析容器元数据)docker或podman命令
关键概念:- 容器网络命名空间:每个Docker容器拥有独立的ns,脚本需通过
nsenter进入操作。 - 策略方向:Ingress(入站)、Egress(出站)、内部东西向流量。
核心脚本:配置iptables/ebtables网络隔离
以下脚本实现“禁止容器A访问容器B的3306端口,但允许80端口”:
#!/bin/bash
set -e
CONTAINER_A="web-app"
CONTAINER_B="mysql-db"
DB_PORT=3306
WEB_PORT=80
# 获取容器IP
IP_A=$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $CONTAINER_A)
IP_B=$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $CONTAINER_B)
# 清空自定义链(避免重复)
iptables -D DOCKER-USER -s $IP_A -d $IP_B -p tcp --dport $DB_PORT -j DROP 2>/dev/null || true
# 添加DROP规则(优先级高于默认ACCEPT)
iptables -I DOCKER-USER 1 -s $IP_A -d $IP_B -p tcp --dport $DB_PORT -j DROP
# 允许Web端口(显式ACCEPT)
iptables -I DOCKER-USER 2 -s $IP_A -d $IP_B -p tcp --dport $WEB_PORT -j ACCEPT
# 持久化规则(保存至文件)
iptables-save > /etc/iptables/rules.v4
执行验证:
# 使用nc测试连接 docker exec -it $CONTAINER_A nc -zv $IP_B 3306 # 应失败 docker exec -it $CONTAINER_A nc -zv $IP_B 80 # 应成功
高级场景:容器间通信规则与CNI插件集成
对于Kubernetes环境,Shell脚本可辅助自定义CNI策略,例如在Calico前添加一条优先级高于策略的规则:
#!/bin/bash
# 假设已安装calicoctl
CONTAINER="nginx-pod"
LABEL="environment=production"
# 生成基于标签的iptables规则
for IP in $(kubectl get pods -l $LABEL -o jsonpath='{.items[*].status.podIP}'); do
iptables -A FORWARD -s $IP -j ACCEPT
echo "规则已添加到Pod IP: $IP"
done
与CNI共存:CNI插件通常使用cali-前缀的链,避免直接修改FORWARD链导致冲突,建议创建独立链SCRIPT-RULES并插入FORWARD首行。
常见问题与最佳实践
Q:脚本执行后规则立即生效,但重启后消失?
A:需配置iptables持久化:
- Ubuntu/Debian:
apt install iptables-persistent - CentOS/RHEL:
service iptables save
Q:动态IP场景下脚本如何更新?
A:结合cronjob或inotify监听/var/lib/docker/containers/目录变化,触发脚本重算。
最佳实践清单:
- 先删除旧规则再添加新规则,避免重复条目塞满iptables。
- 使用set -e捕获中间错误,防止脚本继续执行生成脏规则。
- 添加注释:示例中的规则
-m comment --comment "Allow web port"便于后期排查。
互动问答
问:Shell脚本能否替代Calico的NetworkPolicy?
答:不能完全替代,Shell脚本适合单机或小规模集群的快速策略下发,而Calico支持声明式API、大规模节点同步、服务网格集成,建议混合使用:CNI处理核心策略,Shell作为紧急降级或调试工具。
问:为何我的容器A通过脚本发出请求后,规则不生效?
答:常见原因:
- 容器A本身通过
--net=host共享宿主机网络(此时规则需写在INPUT链而非FORWARD)。 - iptables规则顺序错误:Docker自身的
DOCKER-USER链优先级高于自定义链,需确认规则写入位置。
问:如何用脚本批量清空所有容器自定义规则?
答:
iptables -F DOCKER-USER # 清空自定义链 iptables -X MY-CUSTOM-CHAIN # 删除空链 iptables -F FORWARD # 谨慎使用,会清空所有转发规则
(本文综合Calico官方文档、iptables深度指南及Docker网络实战案例编写,确保术语一致性及操作安全。)