码迷,mamicode.com
首页 > 其他好文 > 详细

flannel源码分析(一) 概述

时间:2016-11-29 21:36:16      阅读:375      评论:0      收藏:0      [点我收藏+]

标签:list   not   服务   handle   out   tde   system   实现   分析   

随着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源码分析(一) 概述

标签:list   not   服务   handle   out   tde   system   实现   分析   

原文地址:http://www.cnblogs.com/arnold0617/p/6114945.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!