kubernetes list-watch(一)

kubernetes的watch包

要理解kuberenetes的list-watch機制,首先應該很熟悉的理解k8s源碼中的watch包中的各種實現以及原理,如果不理解好這個watch包中的內容,在看源碼的過程中,會有很多地方看得雲裏霧裏的。這篇博客主要就是講解watch包,watch包之前是在源碼中的pkg/watch,1.6之後,同一抽取到了apimachinery這個項目下去了。

包文件說明

watch包中主要包含5個文件:watch.go,mux.go,filter.go,streamwatch.go,util.go。對這五個文件作簡單的說明。

  • watch.go 主要是對interface的三種實現封裝。
  • mux.go 主要是事件廣播器的實現。
  • filter.go 主要是對事件的過濾。
  • streamwatch.go 主要是對decoder接口實現的封裝。
  • util.go 主要是對滿足條件時間的過濾。

watch.go文件的解讀

在k8s中說有的event事件統一都實現了interface接口,interface接口的定義如下:

type Interface interface {
    Stop()
    ResultChan() <-chan Event
}


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
}

Event結構體,主要包括了事件類型和事件發生的對象,k8s中所有的對象(比如:pod,service,rc,dp。。。)都是runtime.Object。說白了,event對象就代表了k8s中某種資源對象(包括k8s的各個組件)發生的某種操作。
interface中主要有兩個方法,分別是對事件的監聽結果和停止監聽的方法。interface的實現有三種:

emptyWatch

type emptyWatch chan Event

func NewEmptyWatch() Interface {
    ch := make(chan Event)
    close(ch)
    return emptyWatch(ch)
}

// Stop implements Interface
func (w emptyWatch) Stop() {
}

// ResultChan implements Interface
func (w emptyWatch) ResultChan() <-chan Event {
    return chan Event(w)
}

emptyWatch是最簡單的interface的實現,提供了stop和resultChan的最簡單實現

fakerWatch

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

func NewFake() *FakeWatcher {
    return &FakeWatcher{
        result: make(chan Event),
    }
}

func NewFakeWithChanSize(size int, blocking bool) *FakeWatcher {
    return &FakeWatcher{
        result: make(chan Event, size),
    }
}

// Stop implements Interface.Stop().
func (f *FakeWatcher) Stop() {
    f.Lock()
    defer f.Unlock()
    if !f.Stopped {
        glog.V(4).Infof("Stopping fake watcher.")
        close(f.result)
        f.Stopped = true
    }
}

func (f *FakeWatcher) IsStopped() bool {
    f.Lock()
    defer f.Unlock()
    return f.Stopped
}

// Reset prepares the watcher to be reused.
func (f *FakeWatcher) Reset() {
    f.Lock()
    defer f.Unlock()
    f.Stopped = false
    f.result = make(chan Event)
}

func (f *FakeWatcher) ResultChan() <-chan Event {
    return f.result
}

// Add sends an add event.
func (f *FakeWatcher) Add(obj runtime.Object) {
    f.result <- Event{Added, obj}
}

// Modify sends a modify event.
func (f *FakeWatcher) Modify(obj runtime.Object) {
    f.result <- Event{Modified, obj}
}

// Delete sends a delete event.
func (f *FakeWatcher) Delete(lastValue runtime.Object) {
    f.result <- Event{Deleted, lastValue}
}

// Error sends an Error event.
func (f *FakeWatcher) Error(errValue runtime.Object) {
    f.result <- Event{Error, errValue}
}

// Action sends an event of the requested type, for table-based testing.
func (f *FakeWatcher) Action(action EventType, obj runtime.Object) {
    f.result <- Event{action, obj}
}

fakeWatch封裝了interface的實現,並且是線程安全的,提供了watch的一些基本操作,包括對k8s的各種事件的添加(k8s中總的事件類型:ADDED,MODIFIED,DELETED,ERROR),重置watch,停止watch等。其實watch對事件的添加(ADDED,MODIFIED,DELETED,ERROR)可以統一用這個方法實現。

func (f *FakeWatcher) Action(action EventType, obj runtime.Object) {
    f.result <- Event{action, obj}
}

racefreeWatch

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

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

// Stop implements Interface.Stop().
func (f *RaceFreeFakeWatcher) Stop() {
    f.Lock()
    defer f.Unlock()
    if !f.Stopped {
        glog.V(4).Infof("Stopping fake watcher.")
        close(f.result)
        f.Stopped = true
    }
}

func (f *RaceFreeFakeWatcher) IsStopped() bool {
    f.Lock()
    defer f.Unlock()
    return f.Stopped
}

// Reset prepares the watcher to be reused.
func (f *RaceFreeFakeWatcher) Reset() {
    f.Lock()
    defer f.Unlock()
    f.Stopped = false
    f.result = make(chan Event, DefaultChanSize)
}

func (f *RaceFreeFakeWatcher) ResultChan() <-chan Event {
    f.Lock()
    defer f.Unlock()
    return f.result
}

// Add sends an add event.
func (f *RaceFreeFakeWatcher) Add(obj runtime.Object) {
    f.Lock()
    defer f.Unlock()
    if !f.Stopped {
        select {
        case f.result <- Event{Added, obj}:
            return
        default:
            panic(fmt.Errorf("channel full"))
        }
    }
}

// Modify sends a modify event.
func (f *RaceFreeFakeWatcher) Modify(obj runtime.Object) {
    f.Lock()
    defer f.Unlock()
    if !f.Stopped {
        select {
        case f.result <- Event{Modified, obj}:
            return
        default:
            panic(fmt.Errorf("channel full"))
        }
    }
}

// Delete sends a delete event.
func (f *RaceFreeFakeWatcher) Delete(lastValue runtime.Object) {
    f.Lock()
    defer f.Unlock()
    if !f.Stopped {
        select {
        case f.result <- Event{Deleted, lastValue}:
            return
        default:
            panic(fmt.Errorf("channel full"))
        }
    }
}

// Error sends an Error event.
func (f *RaceFreeFakeWatcher) Error(errValue runtime.Object) {
    f.Lock()
    defer f.Unlock()
    if !f.Stopped {
        select {
        case f.result <- Event{Error, errValue}:
            return
        default:
            panic(fmt.Errorf("channel full"))
        }
    }
}

// Action sends an event of the requested type, for table-based testing.
func (f *RaceFreeFakeWatcher) Action(action EventType, obj runtime.Object) {
    f.Lock()
    defer f.Unlock()
    if !f.Stopped {
        select {
        case f.result <- Event{action, obj}:
            return
        default:
            panic(fmt.Errorf("channel full"))
        }
    }
}

RaceFreeFakeWatcher 封裝了interface的實現,並且是線程安全的,提供了watch的一些基本操作,包括對k8s的各種事件的添加(k8s中總的事件類型:ADDED,MODIFIED,DELETED,ERROR),重置watch,停止watch等,該實現相對fakeWatch更加完善的保證機制,保證在做以上watch的事件操作的時候watch是正常工作的。而fakeWatch在做事件的操作的時候,沒有去判斷watch是否是停止工作,直接進行相關的事件操作,當watch停止工作的時候,該中方式會拋出錯誤。其實watch對事件的添加(ADDED,MODIFIED,DELETED,ERROR)可以統一用這個方法實現。

func (f *RaceFreeFakeWatcher) Action(action EventType, obj runtime.Object) {
    f.Lock()
    defer f.Unlock()
    if !f.Stopped {
        select {
        case f.result <- Event{action, obj}:
            return
        default:
            panic(fmt.Errorf("channel full"))
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章