golang为Kubernetes容器提供网络覆盖的插件Flannel的使用
Flannel - Kubernetes 容器网络覆盖插件
Flannel 是一个简单易用的为 Kubernetes 设计的三层网络结构解决方案。
Flannel 工作原理
Flannel 在每个主机上运行一个名为 flanneld
的小型单二进制代理,负责从更大的预配置地址空间中为每个主机分配子网租约。Flannel 使用 Kubernetes API 或 etcd 直接存储网络配置、分配的子网和任何辅助数据(如主机的公共 IP)。数据包转发使用多种后端机制之一,包括 VXLAN 和各种云集成。
网络细节
像 Kubernetes 这样的平台假设每个容器(pod)在集群内部都有一个唯一的、可路由的 IP。这种模型的优点是消除了共享单个主机 IP 所带来的端口映射复杂性。
Flannel 负责在集群中的多个节点之间提供三层 IPv4 网络。Flannel 不控制容器如何联网到主机,只控制流量如何在主机之间传输。然而,Flannel 确实为 Kubernetes 提供了一个 CNI 插件,并提供了与 Docker 集成的指导。
在 Kubernetes 上使用 Flannel
手动部署 Flannel
使用 kubectl 部署
对于 Kubernetes v1.17+
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
如果您使用自定义的 podCIDR
(非 10.244.0.0/16
),您需要先下载上述清单并修改网络以匹配您的设置。
使用 helm 部署
# 需要手动创建命名空间以避免 helm 错误
kubectl create ns kube-flannel
kubectl label --overwrite ns kube-flannel pod-security.kubernetes.io/enforce=privileged
helm repo add flannel https://flannel-io.github.io/flannel/
helm install flannel --set podCidr="10.244.0.0/16" --namespace kube-flannel flannel/flannel
安装 CNI 网络插件
Flannel 默认使用 portmap
作为 CNI 网络插件;部署 Flannel 时,确保 CNI 网络插件已安装在 /opt/cni/bin
中,可以使用以下命令下载最新二进制文件:
ARCH=$(uname -m)
case $ARCH in
armv7*) ARCH="arm";;
aarch64) ARCH="arm64";;
x86_64) ARCH="amd64";;
esac
mkdir -p /opt/cni/bin
curl -O -L https://github.com/containernetworking/plugins/releases/download/v1.7.1/cni-plugins-linux-$ARCH-v1.7.1.tgz
tar -C /opt/cni/bin -xzf cni-plugins-linux-$ARCH-v1.7.1.tgz
Flannel 需要 br_netfilter 模块才能启动,从版本 1.30 开始,kubeadm 不检查模块是否安装,如果模块缺失,Flannel 将无法正确启动。
在 Docker 上使用 Flannel
Flannel 也广泛用于 Kubernetes 之外。当在 Kubernetes 之外部署时,etcd 总是用作数据存储。
文档
- 构建(和发布)
- 配置
- 后端
- 运行
- 故障排除
- 与 Flannel 集成的项目
社区
- Slack:
- #k3s on Rancher Users Slack
- #flannel-users on Calico Users Slack
- 规划/路线图: milestones, roadmap
- 问题: issues
社区会议
Flannel 维护者社区每隔一个星期四上午 8:30(PST)举行会议。该会议用于讨论问题、开放拉取请求以及与 Flannel 相关的其他主题(如果需要)。
贡献
请参阅 CONTRIBUTING 了解提交补丁和贡献工作流程的详细信息。
报告问题
请参阅 reporting bugs 了解报告任何问题的详细信息。
许可
Flannel 采用 Apache 2.0 许可证。有关详细信息,请参阅 LICENSE 文件。
更多关于golang为Kubernetes容器提供网络覆盖的插件Flannel的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang为Kubernetes容器提供网络覆盖的插件Flannel的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Flannel:Kubernetes容器网络覆盖插件使用指南
Flannel 是 Kubernetes 生态系统中广泛使用的容器网络接口(CNI)插件,它为集群中的 Pod 提供简单高效的网络覆盖解决方案。下面我将详细介绍 Flannel 的工作原理、安装配置和使用方法,并提供相关 Go 代码示例。
Flannel 工作原理
Flannel 通过以下方式为 Kubernetes 集群提供网络功能:
- 为每个节点分配一个子网段
- 使用覆盖网络(Overlay Network)技术实现跨节点 Pod 通信
- 支持多种后端实现:VXLAN、host-gw、UDP 等
安装 Flannel
前置条件
- 已部署 Kubernetes 集群
- 集群未配置其他 CNI 插件
安装步骤
# 使用 kubectl 部署 Flannel
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
配置 Flannel
Flannel 支持通过 ConfigMap 进行配置。以下是常见配置示例:
apiVersion: v1
kind: ConfigMap
metadata:
name: kube-flannel-cfg
namespace: kube-system
labels:
tier: node
app: flannel
data:
cni-conf.json: |
{
"name": "cbr0",
"cniVersion": "0.3.1",
"plugins": [
{
"type": "flannel",
"delegate": {
"hairpinMode": true,
"isDefaultGateway": true
}
},
{
"type": "portmap",
"capabilities": {
"portMappings": true
}
}
]
}
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "vxlan"
}
}
后端类型比较
Flannel 支持多种后端,各有优缺点:
后端类型 | 性能 | 配置复杂度 | 适用场景 |
---|---|---|---|
VXLAN | 中 | 低 | 通用场景 |
host-gw | 高 | 中 | 同数据中心 |
UDP | 低 | 低 | 测试环境 |
Go 代码示例
以下是一个使用 Go 与 Kubernetes API 交互,检查 Flannel 网络状态的示例:
package main
import (
"context"
"fmt"
"log"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
)
func main() {
// 创建 in-cluster 配置
config, err := rest.InClusterConfig()
if err != nil {
log.Fatalf("创建集群配置失败: %v", err)
}
// 创建 clientset
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
log.Fatalf("创建 clientset 失败: %v", err)
}
// 检查 Flannel DaemonSet 状态
checkFlannelDaemonSet(clientset)
// 检查节点网络信息
checkNodeNetwork(clientset)
}
func checkFlannelDaemonSet(clientset *kubernetes.Clientset) {
ds, err := clientset.AppsV1().DaemonSets("kube-system").Get(
context.TODO(), "kube-flannel-ds", metav1.GetOptions{})
if err != nil {
log.Printf("获取 Flannel DaemonSet 失败: %v", err)
return
}
fmt.Printf("Flannel DaemonSet 状态:\n")
fmt.Printf("期望 Pod 数: %d\n", ds.Status.DesiredNumberScheduled)
fmt.Printf("当前 Pod 数: %d\n", ds.Status.CurrentNumberScheduled)
fmt.Printf("就绪 Pod 数: %d\n", ds.Status.NumberReady)
}
func checkNodeNetwork(clientset *kubernetes.Clientset) {
nodes, err := clientset.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{})
if err != nil {
log.Printf("获取节点列表失败: %v", err)
return
}
for _, node := range nodes.Items {
fmt.Printf("\n节点: %s\n", node.Name)
for _, addr := range node.Status.Addresses {
if addr.Type == "InternalIP" {
fmt.Printf("IP 地址: %s\n", addr.Address)
}
}
}
}
常见问题排查
-
Pod 无法跨节点通信
- 检查防火墙规则是否放行 VXLAN 端口(通常为 8472/UDP)
- 确认各节点路由表是否正确
-
Flannel Pod 崩溃
- 检查日志:
kubectl logs -n kube-system <flannel-pod-name>
- 确认内核模块是否加载(如 vxlan)
- 检查日志:
-
网络性能问题
- 考虑切换到 host-gw 后端(如果节点在同一二层网络)
- 检查 MTU 设置是否合理
最佳实践
- 在生产环境使用 VXLAN 后端
- 定期监控 Flannel 组件状态
- 为大型集群适当调整子网分配大小
- 考虑网络策略与 Flannel 的兼容性
Flannel 作为 Kubernetes 网络解决方案,以其简单可靠的特点成为许多集群的基础组件。通过合理配置和运维,可以为容器化应用提供稳定的网络环境。