kubernetes 源码分析之ingress(二)
来源:互联网 发布:ansys软件培训 编辑:程序博客网 时间:2024/05/16 05:40
先看服务启动过程
func main() { // start a new nginx controller ngx := newNGINXController() // create a custom Ingress controller using NGINX as backend ic := controller.NewIngressController(ngx) go handleSigterm(ic) // start the controller ic.Start() // wait glog.Infof("shutting down Ingress controller...") for { glog.Infof("Handled quit, awaiting pod deletion") time.Sleep(30 * time.Second) }}
这里定义了服务的启动和停止,先创建NewIngressController然后启动ic.Start(),如果停止通过SIGTERM信号关闭,停止的代码很简单,先解决
func handleSigterm(ic *controller.GenericController) { signalChan := make(chan os.Signal, 1) signal.Notify(signalChan, syscall.SIGTERM) <-signalChan glog.Infof("Received SIGTERM, shutting down") exitCode := 0 if err := ic.Stop(); err != nil { glog.Infof("Error during shutdown %v", err) exitCode = 1 } glog.Infof("Exiting with %v", exitCode) os.Exit(exitCode)}
很简单,就是接受SIGTERM调用Stop方法,Stop方法里面把同步queue关闭。讲完关闭,回到开始创建的地方。
func newNGINXController() ingress.Controller { ngx := os.Getenv("NGINX_BINARY") if ngx == "" { ngx = binary } n := &NGINXController{ binary: ngx, configmap: &api.ConfigMap{}, } var onChange func() onChange = func() { template, err := ngx_template.NewTemplate(tmplPath, onChange) if err != nil { // this error is different from the rest because it must be clear why nginx is not working glog.Errorf(`-------------------------------------------------------------------------------Error loading new template : %v-------------------------------------------------------------------------------`, err) return } n.t.Close() n.t = template glog.Info("new NGINX template loaded") } ngxTpl, err := ngx_template.NewTemplate(tmplPath, onChange) if err != nil { glog.Fatalf("invalid NGINX template: %v", err) } n.t = ngxTpl go n.Start() return ingress.Controller(n)}
创建一个Nginx的controller,里没有有两个重要的参数:nginx的二进制文件和configmap。其实还有第三个字段是t(n.t = ngxTpl),它是一个Template结构体,主要负责修改nginx的配置文件
func NewTemplate(file string, onChange func()) (*Template, error) { tmpl, err := text_template.New("nginx.tmpl").Funcs(funcMap).ParseFiles(file) if err != nil { return nil, err } fw, err := watch.NewFileWatcher(file, onChange) if err != nil { return nil, err } return &Template{ tmpl: tmpl, fw: fw, s: defBufferSize, tmplBuf: bytes.NewBuffer(make([]byte, 0, defBufferSize)), outCmdBuf: bytes.NewBuffer(make([]byte, 0, defBufferSize)), }, nil}
加载的是nginx.tmpl的模板文件。那么模板文件是啥呢?
client_header_buffer_size {{ $cfg.ClientHeaderBufferSize }}; large_client_header_buffers {{ $cfg.LargeClientHeaderBuffers }}; http2_max_field_size {{ $cfg.HTTP2MaxFieldSize }}; http2_max_header_size {{ $cfg.HTTP2MaxHeaderSize }}; types_hash_max_size 2048; server_names_hash_max_size {{ $cfg.ServerNameHashMaxSize }}; server_names_hash_bucket_size {{ $cfg.ServerNameHashBucketSize }}; map_hash_bucket_size {{ $cfg.MapHashBucketSize }};
是gotemplate模板,里面有很多变量,当组织好结构后就可以通过替换变量,并且写入到nginx.conf里面。从而更新nginx配置。
然后启动nginx, go n.Start()
func (n *NGINXController) Start() { glog.Info("starting NGINX process...") done := make(chan error, 1) cmd := exec.Command(n.binary, "-c", cfgPath) n.start(cmd, done) for { err := <-done if exitError, ok := err.(*exec.ExitError); ok { waitStatus := exitError.Sys().(syscall.WaitStatus) glog.Warningf(`-------------------------------------------------------------------------------NGINX master process died (%v): %v-------------------------------------------------------------------------------`, waitStatus.ExitStatus(), err) } cmd.Process.Release() cmd = exec.Command(n.binary, "-c", cfgPath) // we wait until the workers are killed for { conn, err := net.DialTimeout("tcp", "127.0.0.1:80", 1*time.Second) if err != nil { break } conn.Close() time.Sleep(1 * time.Second) } // start a new nginx master process n.start(cmd, done) }}
上面代码创建了nginx controller,ingress设计中nginx只是其中一种负载均衡,所以ic := controller.NewIngressController(ngx) 其中ic为ingress controller,在这个方法里面创建了调用k8s api的客户端,最终启动ingress的controller:ic.Start()
func (ic GenericController) Start() { glog.Infof("starting Ingress controller") go ic.ingController.Run(ic.stopCh) go ic.endpController.Run(ic.stopCh) go ic.svcController.Run(ic.stopCh) go ic.nodeController.Run(ic.stopCh) go ic.secrController.Run(ic.stopCh) go ic.mapController.Run(ic.stopCh) go ic.secretQueue.Run(5*time.Second, ic.stopCh) go ic.syncQueue.Run(5*time.Second, ic.stopCh) if ic.syncStatus != nil { go ic.syncStatus.Run(ic.stopCh) } <-ic.stopCh}
这个方法是重点,这里面启动了对ingress、endpoint、service、node、secret、configmap的listwatch。还有两个对列secretQueue和syncQueue。
这样服务就可以启动了。
0 0
- kubernetes 源码分析之ingress(二)
- kubernetes 源码分析之ingress(一)
- kubernetes 源码分析之ingress(三)
- Kubernetes Nginx Ingress Controller源码分析
- kubernetes 源码分析之kubeadm(二)
- Kubernetes对象(网络)之Ingress
- Ingress intel api分析之二
- kubernetes 源码分析之kubeadm(一)
- kubernetes 源码分析之kubeadm(三)
- kubernetes源码分析之RBAC
- kubernetes源码阅读之controller-manager(二)
- kubernetes的service的网络类型ingress的搭建(二)
- kubernetes源码阅读之kubelet(二)
- kubernetes源码阅读之整体架构分析
- kubernetes之kube-proxy源码分析
- Kubernetes Ingress解析
- kubernetes资源对象--ingress
- kubernetes之ingress安装及遇到的rbac问题
- [高分求助]如何用ASP请求Delphi的WebService
- echart怎么让南海诸岛不显示或隐藏部分省市名称
- 【2017.04.20】腾讯HR面面经
- 【Tensorflow】tf.nn.relu函数
- sql parameter 显示已存在该key解决方案
- kubernetes 源码分析之ingress(二)
- Fragment中使用Toolbar
- (43):返回零长度的数组或者集合,而不是null
- winform 项目调用wpf窗口 winform窗口式样发生改变问题
- A程序后台启动的B的Activity后,A程序后台又启动了A的Activity,如何在A的Activity中按返回不显示B的Activity
- 避免索引失效
- IE9网页添加到开始菜单
- WCF在项目实际生产中的引用方式以及一些引用建议及如何把svcutil.exe加载到VS中的tool中
- 玩转log4j