【kubernetes/k8s源码分析】list-watch etcd 源码解析

kubelet、kube-controller-manager、kube-scheduler监控资源(pod、service等)的变化,当这些对象发生变化时,kube-apiserver会主动通知这些组件。大概是一个发布-订阅系统


0 结构体

0.1 PodStorage结构体

pkg/registry/core/pod/storage/storage.go

  • 每一类资源(pod、service、depolyments),都会创建Storage对象,如:PodStorage。PodStorage.Pod.Store封装了对etcd的操作

type PodStorage struct {
   Pod         *REST
   Binding     *BindingREST
   Eviction    *EvictionREST
   Status      *StatusREST
   Log         *podrest.LogREST
   Proxy       *podrest.ProxyREST
   Exec        *podrest.ExecREST
   Attach      *podrest.AttachREST
   PortForward *podrest.PortForwardREST
}


1 NewPodStorage函数

func NewStorage(optsGetter generic.RESTOptionsGetter, k client.ConnectionInfoGetter, proxyTransport http.RoundTripper, podDisruptionBudgetClient policyclient.PodDisruptionBudgetsGetter) PodStorage {

   store := &genericregistry.Store{
      NewFunc:                  func() runtime.Object { return &api.Pod{} },
      NewListFunc:              func() runtime.Object { return &api.PodList{} },
      PredicateFunc:            pod.MatchPod,
      DefaultQualifiedResource: api.Resource("pods"),

      CreateStrategy:      pod.Strategy,
      UpdateStrategy:      pod.Strategy,
      DeleteStrategy:      pod.Strategy,
      ReturnDeletedObject: true,

      TableConvertor: printerstorage.TableConvertor{TablePrinter: printers.NewTablePrinter().With(printersinternal.AddHandlers)},
   }
   options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: pod.GetAttrs, TriggerFunc: pod.NodeNameTriggerFunc}
   if err := store.CompleteWithOptions(options); err != nil {
      panic(err) // TODO: Propagate error up
   }

   statusStore := *store
   statusStore.UpdateStrategy = pod.StatusStrategy

   return PodStorage{
      Pod:         &REST{store, proxyTransport},
      Binding:     &BindingREST{store: store},
      Eviction:    newEvictionStorage(store, podDisruptionBudgetClient),
      Status:      &StatusREST{store: &statusStore},
      Log:         &podrest.LogREST{Store: store, KubeletConn: k},
      Proxy:       &podrest.ProxyREST{Store: store, ProxyTransport: proxyTransport},
      Exec:        &podrest.ExecREST{Store: store, KubeletConn: k},
      Attach:      &podrest.AttachREST{Store: store, KubeletConn: k},
      PortForward: &podrest.PortForwardREST{Store: store, KubeletConn: k},
   }
}


3 结构体

3.1 Container结构体

  • Container逻辑上是W


示例 流程分析

0.1 PodStorage结构体

pkg/registry/core/pod/storage/storage.go

  • 网上很好的一个示例图


运行过程中Pod状态变化如下表示: 

流程/Pod状态 PodPhase PodCondition 组件
流程1 - - 用户声明资源数据: 创建deployment,无Pod
流程2~3 Pending - kube-controller-manager: deploy控制器创建Pod
流程4~5 Pending PodScheduled=true Kube-scheduler: 调度器调度Pod成功
流程6~7 Running PodScheduled=true; PodInitialized=true; PodReady=true kubelet: Work node上成功运行容器

A. k8s watch 包详解

staging/src/k8s.io/apimachinery/pkg/watch

watch包中主要包含5个文件:watch.go,mux.go,filter.go,streamwatch.go,util.go。
  1. watch.go 对interface的实现封装
  2. mux.go 事件广播器的实现
  3. filter.go 对事件的过滤
  4. streamwatch.go 对decoder接口实现的封装
  5. util.go 对满足条件时间的过滤

A.a watch.go文件

interface对事件的监听结果和停止监听的方法

// Interface can be implemented by anything that knows how to watch and report changes.
type Interface interface {
   // Stops watching. Will close the channel returned by ResultChan(). Releases
   // any resources used by the watch.
   Stop()

   // Returns a chan which will receive all the events. If an error occurs
   // or Stop() is called, this channel will be closed, in which case the
   // watch should be completely cleaned up.
   ResultChan() <-chan Event
}

Event结构体,包括事件类型和事件发生的对象,k8s中对象都是runtime.Object。event对象就代表了k8s中某种资源对象(包括各个组件)发生的某种操作。 

type Event struct {
   Type EventType

   // Object is:
   //  * If Type is Added or Modified: the new state of the object.
   //  * If Type is Deleted: the state of the object immediately before deletion.
   //  * If Type is Error: *api.Status is recommended; other types may make sense
   //    depending on context.
   Object runtime.Object
}

master.go文件中三个结构体实现了Interface接口

emptyWatch: 最简单的实现

type emptyWatch chan Event

// NewEmptyWatch returns a watch interface that returns no results and is closed.
// May be used in certain error conditions where no information is available but
// an error is not warranted.
func NewEmptyWatch() Interface {
   ch := make(chan Event)
   close(ch)
   return emptyWatch(ch)
}

FakerWatcher: 线程安全的,包括对k8s的各种事件的操作(ADDED,MODIFIED,DELETED,ERROR)

type FakeWatcher struct {
   result  chan Event
   Stopped bool
   sync.Mutex
}

func NewFake() *FakeWatcher {
   return &FakeWatcher{
      result: make(chan Event),
   }
RaceFreeFakeWatcher:   线程安全
type RaceFreeFakeWatcher struct {
   result  chan Event
   Stopped bool
   sync.Mutex
}

func NewRaceFreeFake() *RaceFreeFakeWatcher {
   return &RaceFreeFakeWatcher{
      result: make(chan Event, DefaultChanSize),
   }
}

A.b mutx.go文件

定义:事件广播器

包括所有的k8s的事件(pod,service,deployment,namespace),创建一个事件广播器,会启动一个goroutine注所有的watcher

定义:broadcastWatcher

事件广播器观察者就是interface的实现,很简单,就是一个resultChan方法和stop

A.b.a Broadcaster结构体

  • Broadcaster很好理解,直接过

type Broadcaster struct {
   // TODO: see if this lock is needed now that new watchers go through
   // the incoming channel.
   lock sync.Mutex

   watchers     map[int64]*broadcasterWatcher
   nextWatcher  int64
   distributing sync.WaitGroup

   incoming chan Event

   // How large to make watcher's channel.
   watchQueueLength int
   // If one of the watch channels is full, don't wait for it to become empty.
   // Instead just deliver it to the watchers that do have space in their
   // channels and move on to the next event.
   // It's more fair to do this on a per-watcher basis than to do it on the
   // "incoming" channel, which would allow one slow watcher to prevent all
   // other watchers from getting new events.
   fullChannelBehavior FullChannelBehavior
}

A.b.b BroadcasterWatcher结构体

  • BroadcasterWatcher处理单个的Broadcaster,设计的也相当简单

type broadcasterWatcher struct {
   result  chan Event
   stopped chan struct{}
   stop    sync.Once
   id      int64
   m       *Broadcaster
}

// ResultChan returns a channel to use for waiting on events.
func (mw *broadcasterWatcher) ResultChan() <-chan Event {
   return mw.result
}

// Stop stops watching and removes mw from its list.
func (mw *broadcasterWatcher) Stop() {
   mw.stop.Do(func() {
      close(mw.stopped)
      mw.m.stopWatching(mw.id)
   })
}


A.c filter.go文件

A.c.a r结构体

  • filteredWatch带有过滤的watch,比broaderwatcher升级了过滤功能,代码也是相当简单明了

type filteredWatch struct {
   incoming Interface
   result   chan Event
   f        FilterFunc
}


猜你喜欢

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