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

 

 

转载于:https://www.cnblogs.com/arnold0617/p/6114945.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值