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

1 回复

更多关于golang为Kubernetes容器提供网络覆盖的插件Flannel的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Flannel:Kubernetes容器网络覆盖插件使用指南

Flannel 是 Kubernetes 生态系统中广泛使用的容器网络接口(CNI)插件,它为集群中的 Pod 提供简单高效的网络覆盖解决方案。下面我将详细介绍 Flannel 的工作原理、安装配置和使用方法,并提供相关 Go 代码示例。

Flannel 工作原理

Flannel 通过以下方式为 Kubernetes 集群提供网络功能:

  1. 为每个节点分配一个子网段
  2. 使用覆盖网络(Overlay Network)技术实现跨节点 Pod 通信
  3. 支持多种后端实现: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)
			}
		}
	}
}

常见问题排查

  1. Pod 无法跨节点通信

    • 检查防火墙规则是否放行 VXLAN 端口(通常为 8472/UDP)
    • 确认各节点路由表是否正确
  2. Flannel Pod 崩溃

    • 检查日志: kubectl logs -n kube-system <flannel-pod-name>
    • 确认内核模块是否加载(如 vxlan)
  3. 网络性能问题

    • 考虑切换到 host-gw 后端(如果节点在同一二层网络)
    • 检查 MTU 设置是否合理

最佳实践

  1. 在生产环境使用 VXLAN 后端
  2. 定期监控 Flannel 组件状态
  3. 为大型集群适当调整子网分配大小
  4. 考虑网络策略与 Flannel 的兼容性

Flannel 作为 Kubernetes 网络解决方案,以其简单可靠的特点成为许多集群的基础组件。通过合理配置和运维,可以为容器化应用提供稳定的网络环境。

回到顶部