【kubernetes/k8s源码分析】kube-dns 源码解析之dnsmasq-nanny

github地址:https://github.com/kubernetes/dns

dnsmasq简介Dnsmasq是一款小巧的DNS配置工具

● 通过kubedns容器获取DNS规则,在集群中提供DNS查询服务

● 提供DNS缓存,提高查询性能

● dnsmasq通过参数—server=127.0.0.1#10053指定upstream为kubedns。

/dnsmasq-nanny 

-v=2 

-logtostderr 

-configDir=/etc/k8s/dns/dnsmasq-nanny 

-restartDnsmasq=true -

- -k 

--cache-size=1000 

--log-facility=- 

--server=/cluster.local/127.0.0.1#10053 

--server=/in-addr.arpa/127.0.0.1#10053 

--server=/ip6.arpa/127.0.0.1#10053

结构和kubernetes的代码结构类似:首先看cmd/dnsmasq-nanny/main.go

一 dnsmasq-nanny启动流程


1 main函数

NewFileSync文件同步机制,同kube-dns一样的方式-configDir=/etc/k8s/dns/dnsmasq-nanny

func main() {
   parseFlags()
   glog.V(0).Infof("opts: %v", opts)

   sync := config.NewFileSync(opts.configDir, opts.syncInterval)

   dnsmasq.RunNanny(sync, opts.RunNannyOpts)
}

2 RunNanny函数

主要是配置并且启动Start

// RunNanny runs the nanny and handles configuration updates.
func RunNanny(sync config.Sync, opts RunNannyOpts) {
   defer glog.Flush()

   currentConfig, err := sync.Once()
   if err != nil {
      glog.Errorf("Error getting initial config, using default: %v", err)
      currentConfig = config.NewDefaultConfig()
   }

   nanny := &Nanny{Exec: opts.DnsmasqExec}
   nanny.Configure(opts.DnsmasqArgs, currentConfig)
   if err := nanny.Start(); err != nil {
      glog.Fatalf("Could not start dnsmasq with initial configuration: %v", err)
   }

   configChan := sync.Periodic()

   for {
      select {
      case status := <-nanny.ExitChannel:
         glog.Flush()
         glog.Fatalf("dnsmasq exited: %v", status)
         break
      case currentConfig = <-configChan:
         if opts.RestartOnChange {
            glog.V(0).Infof("Restarting dnsmasq with new configuration")
            nanny.Kill()
            nanny = &Nanny{Exec: opts.DnsmasqExec}
            nanny.Configure(opts.DnsmasqArgs, currentConfig)
            nanny.Start()
         } else {
            glog.V(2).Infof("Not restarting dnsmasq (--restartDnsmasq=false)")
         }
         break
      }
   }
}

3 Start函数

可以看到简单粗暴执行exec.Command,/usr/sbin/dnsmasq -k --cache-size=1000 --log-facility=- --server=/cluster.local/127.0.0.1#10053 --server=/in-addr.arpa/127.0.0.1#10053 --server=/ip6.arpa/127.0.0.1#10053

// Start the nanny.
func (n *Nanny) Start() error {
   n.cmd = exec.Command(n.Exec, n.args...)
   stderrReader, err := n.cmd.StderrPipe()
   if err != nil {
      return err
   }

   stdoutReader, err := n.cmd.StdoutPipe()
   if err != nil {
      return err
   }

   if err := n.cmd.Start(); err != nil {
      return err
   }

   logToGlog := func(stream string, reader io.Reader) {
      bufReader := bufio.NewReader(reader)
      for {
         bytes, err := bufReader.ReadBytes('\n')
         if len(bytes) > 0 {
            glog.V(1).Infof("%v", string(bytes))
         }
         if err == io.EOF {
            glog.V(1).Infof("%v", string(bytes))
            glog.Warningf("Got EOF from %v", stream)
            return
         } else if err != nil {
            glog.V(1).Infof("%v", string(bytes))
            glog.Errorf("Error reading from %v: %v", stream, err)
            return
         }
      }
   }

   go logToGlog("stderr", stderrReader)
   go logToGlog("stdout", stdoutReader)

   n.ExitChannel = make(chan error)
   go func() {
      n.ExitChannel <- n.cmd.Wait()
   }()

   return nil
}

4 Kill函数

可以看到简单粗暴执行kill

// Kill the running Nanny.
func (n *Nanny) Kill() error {
   glog.V(0).Infof("Killing dnsmasq")
   if n.cmd == nil {
      return fmt.Errorf("Process is not running")
   }

   if err := n.cmd.Process.Kill(); err != nil {
      glog.Errorf("Error killing dnsmasq: %v", err)
      return err
   }

   n.cmd = nil

   return nil
}

猜你喜欢

转载自blog.csdn.net/zhonglinzhang/article/details/80986583