
在 Kubernetes 中安装与配置 Flannel 网络插件从 vxlan 到 host-gw 的完整实践【免费下载链接】kubernetes-handbookKubernetes 架构与生态从云原生到 AI 原生基础设施的构建指南项目地址: https://gitcode.com/gh_mirrors/ku/kubernetes-handbookFlannel 是 Kubernetes 中最常用的容器网络插件之一它以 etcd 为存储后端为每个 Node 分配独立的 Pod 子网并通过 vxlan 或 host-gw 等后端实现跨主机 Pod 互通。本文基于 kubernetes-handbook 的 安装 flannel 网络插件 一文完整讲解在所有 Node 节点上通过 yum 安装、配置、启动并验证 flannel 的每一步操作同时结合仓库中的 flanneld.service、flanneld 环境变量配置、docker.service 等真实配置文件深入剖析 flannel 与 etcd、Docker 之间的协作机制帮助你一次上手即可部署出可用的扁平化 Pod 网络。为什么每个 Node 节点都需要网络插件Kubernetes 集群中运行着三类 IP理解它们之间的区别是配置网络插件的前提Node IP宿主机的物理 IP 地址Pod IP由网络插件如 flannel分配的虚拟 IP用于让跨主机的 Pod 相互连通Cluster IPService 的虚拟 IP通过 kube-proxy 注入的 iptables 规则访问。Kubernetes 本身并不实现网络方案而是通过 CNIContainer Network Interface规范对接各类插件详见 容器网络接口CNI。只有所有 Node 节点都安装了网络插件集群中的所有 Pod 才能加入同一个局域网这也是安装 flannel 的出发点。按照本手册的部署顺序Node 节点上的进程遵循flannel - docker - kubelet - kube-proxy的启动次序flannel 是整个链路的第一环。从架构上看运行在每个 Node 上的 flanneld 进程承担两个核心职责为每个 Node 分配独立的 subnet容器启动后自动从该子网中获取 IP维护跨节点路由当有新的 Node 加入网络时为每个 Node 增加指向远端子网的路由条目。安装前准备etcd 集群与 TLS 证书flannel 以 etcd 作为配置和租约存储后端因此安装前必须保证有一个可访问的 etcd 集群本文示例为三节点172.20.0.113/114/115:2379TLS 加密通信每个 Node 上已准备好与 etcd 通信所需的证书文件ca.pem、kubernetes.pem、kubernetes-key.pem位于/etc/kubernetes/ssl/目录与 kube-apiserver 使用的证书一致etcd 集群安装可参考 etcd 集群安装。使用 yum 安装 flanneld建议直接使用 yum 安装 flanneld除非对版本有特殊需求yum install -y flannel在本文写作时默认安装的是0.7.1 版本的 flannel。安装完成后会在系统内生成两个关键文件文件作用/usr/lib/systemd/system/flanneld.serviceflanneld 的 systemd 单元文件定义了启动参数与依赖关系/etc/sysconfig/flanneldflanneld 的环境变量配置文件endpoints、prefix、TLS 等配置 flanneldservice 单元文件解析仓库中完整保存了该单元文件见 systemd/flanneld.service内容与安装后生成的文件一致[Unit] DescriptionFlanneld overlay address etcd agent Afternetwork.target Afternetwork-online.target Wantsnetwork-online.target Afteretcd.service Beforedocker.service [Service] Typenotify EnvironmentFile/etc/sysconfig/flanneld EnvironmentFile-/etc/sysconfig/docker-network ExecStart/usr/bin/flanneld-start \ -etcd-endpoints${FLANNEL_ETCD_ENDPOINTS} \ -etcd-prefix${FLANNEL_ETCD_PREFIX} \ $FLANNEL_OPTIONS ExecStartPost/usr/libexec/flannel/mk-docker-opts.sh -k DOCKER_NETWORK_OPTIONS -d /run/flannel/docker Restarton-failure [Install] WantedBymulti-user.target RequiredBydocker.service逐项拆解这个单元文件可以理解 flannel 与系统各组件的关系Afteretcd.service/Beforedocker.service声明 flanneld 必须在 etcd 之后启动、在 docker 之前启动。这正是先有子网分配、后有 Docker 接入的编排保证RequiredBydocker.service将 docker 反向依赖 flannel确保 docker 启动前 flanneld 已经就绪Typenotifyflanneld 启动完成后会主动向 systemd 发送通知避免过早认为服务就绪EnvironmentFile/etc/sysconfig/flanneld提供核心变量-/etc/sysconfig/docker-network前面的-表示该文件允许不存在ExecStartflanneld-start从环境变量中读取 etcd endpoints 与配置前缀key$FLANNEL_OPTIONS用于透传额外的命令行参数如 TLS 证书、指定网卡ExecStartPostflanneld 启动后立即执行/usr/libexec/flannel/mk-docker-opts.sh它基于 flannel 生成的子网信息生成 Docker 所需的启动参数文件这是 flannel 与 Docker 协作的关键一环下文会展开说明Restarton-failure进程异常退出时自动拉起。配置 /etc/sysconfig/flanneld 环境变量仓库中的 etc/sysconfig/flanneld 完整呈现了该配置文件的典型内容# Flanneld configuration options # etcd url location. Point this to the server where etcd runs FLANNEL_ETCD_ENDPOINTShttps://172.20.0.113:2379,https://172.20.0.114:2379,https://172.20.0.115:2379 # etcd config key. This is the configuration key that flannel queries # For address range assignment FLANNEL_ETCD_PREFIX/kube-centos/network # Any additional options that you want to pass FLANNEL_OPTIONS-etcd-cafile/etc/kubernetes/ssl/ca.pem -etcd-certfile/etc/kubernetes/ssl/kubernetes.pem -etcd-keyfile/etc/kubernetes/ssl/kubernetes-key.pem三个变量的含义如下变量说明FLANNEL_ETCD_ENDPOINTSetcd 集群地址列表多个地址用逗号分隔此处使用 https 表明开启 TLSFLANNEL_ETCD_PREFIXflannel 在 etcd 中使用的配置键前缀本文统一使用/kube-centos/networkFLANNEL_OPTIONS追加的 flanneld 命令行参数。本示例为与启用 TLS 的 etcd 通信指定 CA、客户端证书与私钥多网卡场景如果宿主机有多个网卡例如 vagrant 环境flannel 可能选错出口网卡导致子网无法互通此时需要在FLANNEL_OPTIONS中显式指定对外网卡例如-ifaceeth2。注意FLANNEL_ETCD_ENDPOINTS、FLANNEL_ETCD_PREFIX这两个变量仅供 flanneld 使用而 flannel 生成的 Docker 参数会单独落到/run/flannel/目录见下文。在 etcd 中初始化网络配置flannel 从 etcd 中的配置键读取整个集群的网络规划大网段、子网掩码、后端类型。首先创建配置目录然后写入网络配置etcdctl --endpointshttps://172.20.0.113:2379,https://172.20.0.114:2379,https://172.20.0.115:2379 \ --ca-file/etc/kubernetes/ssl/ca.pem \ --cert-file/etc/kubernetes/ssl/kubernetes.pem \ --key-file/etc/kubernetes/ssl/kubernetes-key.pem \ mkdir /kube-centos/network etcdctl --endpointshttps://172.20.0.113:2379,https://172.20.0.114:2379,https://172.20.0.115:2379 \ --ca-file/etc/kubernetes/ssl/ca.pem \ --cert-file/etc/kubernetes/ssl/kubernetes.pem \ --key-file/etc/kubernetes/ssl/kubernetes-key.pem \ mk /kube-centos/network/config {Network:172.30.0.0/16,SubnetLen:24,Backend:{Type:vxlan}}该 JSON 配置中的三个字段共同决定了整个集群的 Pod 网络形态Network整个集群的 Pod 大网段CIDR所有 Node 的子网都从该网段中划分SubnetLen每个 Node 获得的子网掩码长度示例为24即每个 Node 最多可容纳 254 个 Pod172.30.0.0/16可划分出 256 个/24子网Backend.Type数据面封装/转发模式。示例为vxlanOverlay 隧道如果希望改用host-gw模式直接将vxlan改为host-gw即可例如etcdctl --endpoints${ETCD_ENDPOINTS} \ --ca-file/etc/kubernetes/ssl/ca.pem \ --cert-file/etc/kubernetes/ssl/kubernetes.pem \ --key-file/etc/kubernetes/ssl/kubernetes-key.pem \ mk /kube-centos/network/config {Network:172.30.0.0/16,SubnetLen:24,Backend:{Type:host-gw}}关于 vxlan 与 host-gw 的取舍可参考 网络和集群性能测试 一节该节最终采用了host-gw 模式两者差异详见本文后面的模式选择部分。启动 flannel 并验证配置完成后即可启动 flanneldsystemctl daemon-reload systemctl enable flanneld systemctl start flanneld systemctl status flanneld启动成功后每个 Node 的 flanneld 会向 etcd 注册自己分配到的子网。查询 etcd 可以看到类似如下的内容$etcdctl --endpoints${ETCD_ENDPOINTS} \ --ca-file/etc/kubernetes/ssl/ca.pem \ --cert-file/etc/kubernetes/ssl/kubernetes.pem \ --key-file/etc/kubernetes/ssl/kubernetes-key.pem \ ls /kube-centos/network/subnets /kube-centos/network/subnets/172.30.14.0-24 /kube-centos/network/subnets/172.30.38.0-24 /kube-centos/network/subnets/172.30.46.0-24 $etcdctl --endpoints${ETCD_ENDPOINTS} \ --ca-file/etc/kubernetes/ssl/ca.pem \ --cert-file/etc/kubernetes/ssl/kubernetes.pem \ --key-file/etc/kubernetes/ssl/kubernetes-key.pem \ get /kube-centos/network/config { Network: 172.30.0.0/16, SubnetLen: 24, Backend: { Type: vxlan } } $etcdctl --endpoints${ETCD_ENDPOINTS} \ --ca-file/etc/kubernetes/ssl/ca.pem \ --cert-file/etc/kubernetes/ssl/kubernetes.pem \ --key-file/etc/kubernetes/ssl/kubernetes-key.pem \ get /kube-centos/network/subnets/172.30.14.0-24 {PublicIP:172.20.0.114,BackendType:vxlan,BackendData:{VtepMAC:56:27:7d:1c:08:22}} $etcdctl --endpoints${ETCD_ENDPOINTS} \ --ca-file/etc/kubernetes/ssl/ca.pem \ --cert-file/etc/kubernetes/ssl/kubernetes.pem \ --key-file/etc/kubernetes/ssl/kubernetes-key.pem \ get /kube-centos/network/subnets/172.30.38.0-24 {PublicIP:172.20.0.115,BackendType:vxlan,BackendData:{VtepMAC:12:82:83:59:cf:b8}} $etcdctl --endpoints${ETCD_ENDPOINTS} \ --ca-file/etc/kubernetes/ssl/ca.pem \ --cert-file/etc/kubernetes/ssl/kubernetes.pem \ --key-file/etc/kubernetes/ssl/kubernetes-key.pem \ get /kube-centos/network/subnets/172.30.46.0-24 {PublicIP:172.20.0.113,BackendType:vxlan,BackendData:{VtepMAC:e6:b2:fd:f6:66:96}}以上输出中的每一条 subnet 记录都是一个 Node 的租约PublicIP该 Node 对外的物理 IP示例中 3 个 Node 分别为 114、115、113BackendType当前使用 vxlan 后端BackendData.VtepMAC该 Node 上创建的 VTEP虚拟隧道端点网卡的 MAC 地址vxlan 模式下正是通过这张网卡完成跨主机封包转发。如果能够查询到上述内容说明 flannel 已经安装并运行成功。下一步就可以在该 Node 上安装和配置 docker、kubelet、kube-proxy 等组件完整流程参见 部署 node 节点。深入理解flannel 如何与 Docker 协同工作flannel 安装完成的标志不只是 flanneld 进程运行更关键的是它能否把 Pod 子网信息传导给 Docker。这一过程由单元文件中的ExecStartPost完成ExecStartPost/usr/libexec/flannel/mk-docker-opts.sh -k DOCKER_NETWORK_OPTIONS -d /run/flannel/dockermk-docker-opts.sh的作用是Generate Docker daemon options based on flannel env file根据 flannel 环境文件生成 Docker 守护进程参数。flanneld 启动后它会自动生成两个文件1./run/flannel/docker—— 给 Docker 的启动参数DOCKER_OPT_BIP--bip172.33.68.1/24 DOCKER_OPT_IPMASQ--ip-masqtrue DOCKER_OPT_MTU--mtu1500 DOCKER_NETWORK_OPTIONS--bip172.33.68.1/24 --ip-masqtrue --mtu15002./run/flannel/subnet.env—— flannel 向 etcd 注册的子网信息FLANNEL_NETWORK172.33.0.0/16 FLANNEL_SUBNET172.33.68.1/24 FLANNEL_MTU1500 FLANNEL_IPMASQfalse其中--bip172.33.68.1/24指定了该 Node 上 docker0 网桥的地址也就是 Pod 子网的网关--mtu与 vxlan 隧道 MTU 相匹配--ip-masqtrue则允许容器访问外部网络时进行地址伪装。为了让 Docker 读取这些参数需要修改/usr/lib/systemd/system/docker.service加入环境变量引用。仓库中的 systemd/docker.service 完整保留了推荐配置兼容 yum 与二进制两种安装方式EnvironmentFile-/run/flannel/docker EnvironmentFile-/run/docker_opts.env EnvironmentFile-/run/flannel/subnet.env EnvironmentFile-/etc/sysconfig/docker EnvironmentFile-/etc/sysconfig/docker-storage EnvironmentFile-/etc/sysconfig/docker-network EnvironmentFile-/run/docker_opts.env并且ExecStart中显式拼接了 flannel 生成的三个变量ExecStart/usr/bin/dockerd \ --exec-opt native.cgroupdriversystemd \ $DOCKER_OPT_BIP \ $DOCKER_OPT_IPMASQ \ $DOCKER_OPT_MTU \ -soverlay \ --log-driverjson-file \ ...这样一来只要通过 systemctl 先启动 flannel 再启动 dockerdocker0 就会自动落在 flannel 分配的子网内。实际启动后的 docker 进程参数会呈现为--bip172.33.68.1/24 --ip-masqtrue --mtu1500用ip addr查看宿主机网卡即可印证docker0的地址正是172.33.68.1/24同时存在veth设备将 Pod 容器与 docker0 相连用docker network inspect也能看到 bridge 网络的Subnet/Gateway与 flannel 分配的子网完全一致。这些都是 flannel 与 Docker 成功协同的直接证据。注意无论使用 yum 还是二进制方式安装 flannel向 docker.service 注入上述EnvironmentFile都是必不可少的步骤否则 Docker 无法加入 flannel 创建的虚拟网络。若二进制方式安装tar 包方式还需从 flannel release 中取出mk-docker-opts.sh脚本并执行./mk-docker-opts.sh -i生成环境文件。验证跨节点 Pod 互通flannel 的另一项核心工作是维护宿主机的路由表。Node 节点启动 flannel 后路由表中会出现类似下面的条目示例来自 扁平网络 Flannel172.33.68.0 0.0.0.0 255.255.255.0 U 0 0 0 docker0 172.33.96.0 172.30.118.65 255.255.255.0 UG 0 0 0 eth2第一条是本机子网路由指向 docker0第二条是 flannel 自动添加的远端 Node 子网路由——当有新的 Node 加入集群后每个 Node 的路由表都会同步增加对应条目这也是新增节点即插即用的原因。使用traceroute访问另一台 Node 上的 Pod如172.33.96.3可以看到流量先到达对端 Node 的物理 IP再一跳进入目标 Pod1 172.30.118.65 (172.30.118.65) 0.518 ms 0.367 ms 0.398 ms 2 172.33.96.3 (172.33.96.3) 0.451 ms 0.352 ms 0.223 ms在iptables -L中也能看到 kube-proxy 注入的KUBE-SERVICES、KUBE-FORWARD等 Service 转发规则链说明 Pod 网络与 Service 网络已协同工作。vxlan 与 host-gw 模式如何选择flannel 支持的两种主流后端在数据面实现上差异显著直接决定集群网络的性能上限vxlan 模式Overlay 隧道方案跨主机流量通过 VTEP 封包/解包转发与底层物理网络解耦部署最省心但封装/解封装过程带来明显性能损耗host-gw 模式纯路由方案flannel 直接在宿主机路由表中写入远端 Pod 子网 - 对端 Node IP的路由跨节点流量直接走物理网络转发没有封包开销。两种模式的架构可分别参考下图理解左为 host-gw 路由模型右为 flannel 总体架构仓库中的 网络和集群性能测试 使用 iperf 对同一集群做过对比测试测试命令服务端iperf -s -p 12345 -i 1 -M客户端iperf -c ${server-ip} -p 12345 -i 1 -t 10 -w 20K结果如下场景vxlan 带宽host-gw 带宽宿主机之间基准5.37 Gbits/sec5.37 Gbits/sec不同主机的 Pod 之间3.30 Gbits/sec4.88 Gbits/secNode 与跨主机 Pod 之间3.42 Gbits/sec4.94 Gbits/sec结论是vxlan 模式相对宿主机直连约有 30%40% 的性能损耗而 host-gw 模式损耗仅约 10%。因此如果你的集群位于二层可达的同一网段host-gw 依赖 Node 间三层路由可达且无需跨子网隔离优先选择host-gw模式如果 Node 分布跨网段、物理网络不可直连再退而使用 vxlan。更多关于 Kubernetes 网络模型与 flannel 模式的讨论可参考 Kubernetes 中的网络模式解析 与 CNI 接口说明。常见问题排查etcd 中没有 subnets 租约检查FLANNEL_ETCD_ENDPOINTS与 TLS 证书-etcd-cafile/-etcd-certfile/-etcd-keyfile是否正确并用etcdctl手工读取/kube-centos/network/config确认配置键已写入Pod 子网与外网网段冲突Network字段务必选择不与任何 Node 物理网段重叠的私有网段多网卡选错出口导致跨 Node 不通在FLANNEL_OPTIONS中追加-iface对外网卡名如 vagrant 环境中的eth2Docker 未使用 flannel 子网确认docker.service已包含EnvironmentFile-/run/flannel/docker等环境变量引用并检查systemctl status -l docker中是否出现--bip... --ip-masqtrue --mtu...参数更换后端模式只需更新 etcd 中/kube-centos/network/config的Backend.Type为vxlan或host-gw然后依次重启各 Node 的 flanneld 与 docker。完成 flannel 安装后请继续按照 部署 node 节点 安装 Docker、kubelet 与 kube-proxy使 Node 正式加入 Kubernetes 集群。【免费下载链接】kubernetes-handbookKubernetes 架构与生态从云原生到 AI 原生基础设施的构建指南项目地址: https://gitcode.com/gh_mirrors/ku/kubernetes-handbook创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考