首页 > 代码库 > flannel源码分析(一) 概述
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 SIGTERM26 log.Info("Installing signal handlers")27 sigs := make(chan os.Signal, 1)28 signal.Notify(sigs, os.Interrupt, syscall.SIGTERM)29 // 设置可以cancle的context30 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 <-sigs58 // unregister to get default OS nuke behaviour in case we don‘t exit cleanly59 signal.Stop(sigs)60 log.Info("Exiting...")61 62 // 收到信号后,掉用cancle函数, 取消所有相关的子context63 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源码分析(一) 概述
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。