kubelet、kube-controller-manager、kube-scheduler监控资源(pod、service等)的变化,当这些对象发生变化时,kube-apiserver会主动通知这些组件。大概是一个发布-订阅系统
0 结构体
0.1 PodStorage结构体
pkg/registry/core/pod/storage/storage.go
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结构体
示例 流程分析
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.go 对interface的实现封装
- mux.go 事件广播器的实现
- filter.go 对事件的过滤
- streamwatch.go 对decoder接口实现的封装
- 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结构体
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结构体
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结构体
type filteredWatch struct {
incoming Interface
result chan Event
f FilterFunc
}