flannel源码分析 概述

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了flannel源码分析 概述相关的知识,希望对你有一定的参考价值。

随着docker社区的不断壮大, CoreOS、Kubernetes、Hashicorp等项目蓬勃发展。 flannel作为一款专为容器打造的开源网络组件, 也吸引了工程师的关注。flannel简单易用, 只需要同属CoreOS家族的etcd作为一致性存储, 便可配置multi-host的网络连接。

 
下图为flanned的网络原理图, 源自https://github.com/coreos/flannel 。
 
 
技术分享

 

 
可以看到flannel为每台host划分了subnet, 这样就保证多台主机上的多个容器都能拥有独立的ip来互相通信。
 
本文参考flannel-0.6.2来分析flannel的具体实现。
 
 

技术分享

 

 
可以看到flannel源码主要包含以下目录:
backend: ip packet转发的具体实现, 包含udp, vxlan, hostgw, gce... , 默认是udp。
network:  确定backend类型, 写本地env文件。
subnet:    与etcd交互, 确定subnet。
这些目录里的source code, 后续都有详细介绍。
 
现在我们就从main.go开始看一下, flannel的启动过程。 
 
 1 func main() {
 2     // glog will log to tmp files by default. override so all entries
 3     // can flow into journald (if running under systemd)
 4     flag.Set("logtostderr", "true")
 5     // now parse command line args
 6     flag.Parse()
 7     if flag.NArg() > 0 || opts.help {
 8         fmt.Fprintf(os.Stderr, "Usage: %s [OPTION]...\\n", os.Args[0])
 9         flag.PrintDefaults()
10         os.Exit(0)
11     }
12     if opts.version {
13         fmt.Fprintln(os.Stderr, version.Version)
14         os.Exit(0)
15     }
16 
17     flagutil.SetFlagsFromEnv(flag.CommandLine, "FLANNELD")
18     
19     // 创建SubnetManager用于划分子网
20     sm, err := newSubnetManager()
21     if err != nil {
22         log.Error("Failed to create SubnetManager: ", err)
23         os.Exit(1)
24     }
25     // Register for SIGINT and SIGTERM
26     log.Info("Installing signal handlers")
27     sigs := make(chan os.Signal, 1)
28     signal.Notify(sigs, os.Interrupt, syscall.SIGTERM)
29     // 设置可以cancle的context
30     ctx, cancel := context.WithCancel(context.Background())
31     var runFunc func(ctx context.Context)
32     if opts.listen != "" {
33         if opts.remote != "" {
34             log.Error("--listen and --remote are mutually exclusive")
35             os.Exit(1)
36         }
37         log.Info("running as server")
38         runFunc = func(ctx context.Context) {
39             remote.RunServer(ctx, sm, opts.listen, opts.remoteCAFile, opts.remoteCertfile, opts.remoteKeyfile)
40         }
41     } else {
42         nm, err := network.NewNetworkManager(ctx, sm)
43         if err != nil {
44             log.Error("Failed to create NetworkManager: ", err)
45             os.Exit(1)
46         }
47         runFunc = func(ctx context.Context) {
48             nm.Run(ctx)
49         }
50     }
51     wg := sync.WaitGroup{}
52     wg.Add(1)
53     go func() {
54         runFunc(ctx)    // 在一个新的goroutine中运行NetworkManager的Run函数
55         wg.Done()
56     }()
57     <-sigs
58     // unregister to get default OS nuke behaviour in case we don‘t exit cleanly
59     signal.Stop(sigs)
60     log.Info("Exiting...")
61     
62     // 收到信号后,掉用cancle函数, 取消所有相关的子context
63     cancel()
64     wg.Wait()
65 }

 

由上述的代码可以看出, 根据参数listen和remote可以设置flannel为server模式或client模式, server模式对外提供服务, 并不能加入到flannel的网络。 client模式下NetworkManager的Run函数是程序执行的入口, 设置flannel的subnet。

下一篇将分析NetworkManager对应的源码。

 

关于go context的用法, 请参考以下两篇博文。

https://segmentfault.com/a/1190000006744213

http://blog.csdn.net/xiaohu50/article/details/49100433

 

 

以上是关于flannel源码分析 概述的主要内容,如果未能解决你的问题,请参考以下文章

flannel源码分析---backend为vxlan

Android 插件化VirtualApp 源码分析 ( 目前的 API 现状 | 安装应用源码分析 | 安装按钮执行的操作 | 返回到 HomeActivity 执行的操作 )(代码片段

Android 逆向整体加固脱壳 ( DEX 优化流程分析 | DexPrepare.cpp 中 dvmOptimizeDexFile() 方法分析 | /bin/dexopt 源码分析 )(代码片段

Android 事件分发事件分发源码分析 ( Activity 中各层级的事件传递 | Activity -> PhoneWindow -> DecorView -> ViewGroup )(代码片段

libMosquitto 源码分析之一:概述

docker flannel网络部署和路由走向分析