文章目录
- 1 入口
- 2 ProxyServer创建及调用
- 3 ProxyServer 核心调用流程
- 4 资源事件处理流程
- 5 代理规则同步处理流程
- 6 数据包路径及链位置
- 7 总结
1 入口
利用Cobra构建CLI接口,并对proxy server进行调用。
kubernetes/cmd/kube-proxy/proxy.go
func main() {
rand.Seed(time.Now().UnixNano())
// 核心调用
command := app.NewProxyCommand()
// TODO: once we switch everything over to Cobra commands, we can go back to calling
// utilflag.InitFlags() (by removing its pflag.Parse() call). For now, we have to set the
// normalize func and add the go flag set by hand.
pflag.CommandLine.SetNormalizeFunc(cliflag.WordSepNormalizeFunc)
pflag.CommandLine.AddGoFlagSet(goflag.CommandLine)
// utilflag.InitFlags()
logs.InitLogs()
defer logs.FlushLogs()
if err := command.Execute(); err != nil {
os.Exit(1)
}
}
2 ProxyServer创建及调用
kubernetes/cmd/kube-proxy/app/server.go
func NewProxyCommand() *cobra.Command {
.....
cmd := &cobra.Command{
......
Run:func(cmd *cobra.Command, args []string) {
......
opts.Run()
}
}
.....
opts.config, err = opts.ApplyDefaults(opts.config)
.....
}
ApplyDefaults中会配置默认的参数。/pkg/proxy/apis中的init方法内,会向SchemeBuilder注册添加默认参数的方法。这里面对于Porxy会注册SetObjectDefaults_KubeProxyConfiguration,最后调用了SetDefaults_KubeProxyConfiguration。其中IPTables.SyncPeriod.Duration,默认值为30S(该值为失败后的尝试retry间隔,可以使用–iptables-sync-period配置,其指定了iptables重刷新的最大间隔)
kubernetes/cmd/kube-proxy/app/server.go
func (o *Options) Run() error {
defer close(o.errCh)
if len(o.WriteConfigTo) > 0 {
return o.writeConfigFile()
}
proxyServer, err := NewProxyServer(o)
if err != nil {
return err
}
if o.CleanupAndExit {
return proxyServer.CleanupAndExit()
}
o.proxyServer = proxyServer
return o.runLoop()
}
注意:这里BounedFrequencyRunner的同步方法为proxier.syncProxyRules,最小时间间隔为minSyncPeriod(可以使用参数--iptables-min-sync-period配置,未配置时,应该就是0),最大时间间隔为1小时,突发数为2,失败重试间隔为proxier.syncPeriod(默认为30秒,可以用参数--iptables-sync-period配置,其指定了iptables重刷新的最大间隔,不允许为0)
3 ProxyServer 核心调用流程
opts.Run()->
o.runLoop()->
o.proxyServer.Run()->
s.Proxier.SyncLoop()
3.1 func (o *Options) Run() err
在构建ProxyCommand时,会在其Run方法内调用该方法
- (1)如kube-proxy命令调用时,传入了–write-config-to参数,则会将kube-proxy的默认配置打印到指定文件,然后退出。
- (2)调用NewProxyServer方法,构建proxyServer
- (3)如果kube-proxy命令调用时传入了–cleanup参数,则会清理iptables及ipvs配置,然后退出
- (4)调用o.runLoop方法。
3.2 func (o *Options) runLoop() error
- (1)如果o.Watcher(用于监听ConfigFile的更新变化)不为空,则调用o.watcher.Run()(这里如果监听到配置文件的写或者rename事件,会导致kube-proxy的退出)
- (2)调用o.proxyServer.Run()
3.3 func (s *ProxyServer) Run() error
- (1)如果启动参数中配置了–oom-score-adj(oom打分调整,OOM killer 会给进程打分,把 oom_score 最大的进程先杀死,如果这个值设置成负数,则表明不优先级杀死它,如果位正数则优先杀死,如果设置为0表明与用户不调整)。则为kube-proxy配置该值
- (2)如果Broadcaster及EventClient不为空,则开启事件记录服务
- (3)如果健康检查服务不会空,则启动
- (4)如果指标绑定地址大于0,则启动服务
- 1)curl 10.19.188.3:10249/proxyMode, 可以获得proxyMode运行模式
- 2)curl curl 10.19.188.3:10249/metrics, 可以获得运行指标信息
- (5)如过contracker会为空,则根据启动参数,配置系统contracker配置。(这里我们会把所有的contracker相关配置设置为0, 即不修改系统原先的conntrack配置)
- 1)首先调用getConntrackMax,如果–conntrack-max-per-core参数不为空,且值大于0(不配置时,默认值为32768),则用其乘以cpu数,获取上限值,如果该值大于配置中的–conntrack-min,则返回该值,否则返回–conntrack-min。否则返回0
- 2)如果max值大于0,则更新系统配置
- 3)如果配置了–conntrack-tcp-timeout-close-wait duration,且其值大于0, 则更新系统值
- 4)如果配置了–conntrack-tcp-timeout-established,且其值大于0,则更新系统中的该值。
- (6)构建kube-proxy监听的server的选择器,及Informer(对于具有service.kubernetes.io/service-proxy-name及service.kubernetes.io/headless label的service不处理),注册service事件处理器,并启动
- (7)如果使用EndpointSlices,则构建endpointsSlice事件处理器,