<p>Recently I research how kubelet sync events to apiserver but I can't find where the code is.</p>

kongshuo
<p>The source of kubelet is available <a href="https://github.com/kubernetes/kubernetes/tree/master/pkg/kubelet" rel="nofollow noreferrer">here</a>.</p>

<blockquote>
  <p>Kubelet can obtain Pod configurations required by the local node in multiple ways. The most important way is <strong>Apiserver</strong>. Kubelet can also obtain the Pod configurations by specifying the file directory or accessing the specified HTTP port.</p>
</blockquote>

<p>On the startup of Kubelet, a <code>PodConfig</code> object is created.
Code <a href="https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/config/config.go#L58" rel="nofollow noreferrer">kubernetes/blob/master/pkg/kubelet/config/config.go#L58</a>:</p>

<pre><code>type PodConfig struct {
    pods *podStorage
    mux  *config.Mux

    // the channel of denormalized changes passed to listeners
    updates chan kubetypes.PodUpdate
    ...
}
</code></pre>

<blockquote>
  <p><code>PodConfig</code> is essentially a multiplexer of Pod configurations. The built-in <code>mux</code> can listen on the sources of various Pod configurations (including apiserver, file, and http), and periodically synchronize the Pod configuration status of the sources.</p>
</blockquote>

<p>Code <a href="https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/types/pod_update.go#L80" rel="nofollow noreferrer">kubernetes/blob/master/pkg/kubelet/types/pod_update.go#L80</a>:</p>

<pre><code>type PodUpdate struct {
    Pods   []*v1.Pod
    Op     PodOperation
    Source string
}
</code></pre>

<p>The <code>Op</code> defines the Pod change type. For example those can be values like <code>ADD</code> or <code>REMOVE</code>. In the end all types of <code>PodUpdate</code> will be injected to <code>updates</code> of <code>podConfig</code>. So there is only a need to listen to <code>update</code> channel to get Pod configuration updates of the local node.</p>

<p>Once Kubelet startup is complete, the <code>syncLoop</code> function is executed.
Code <a href="https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/kubelet.go#L1806" rel="nofollow noreferrer">kubernetes/blob/master/pkg/kubelet/kubelet.go#L180</a>:</p>

<pre><code>// syncLoop is the main loop for processing changes. It watches for changes from
// three channels (file, apiserver, and http) and creates a union of them. For
// any new change seen, will run a sync against desired state and running state. If
// no changes are seen to the configuration, will synchronize the last known desired
// state every sync-frequency seconds. Never returns.
    func (kl *Kubelet) syncLoop(updates &lt;-chan kubetypes.PodUpdate, handler SyncHandler) {
        ...
        for {
            ...
            if !kl.syncLoopIteration(updates, handler, syncTicker.C, housekeepingTicker.C, plegCh) {
                break
            }
            ...
    }
</code></pre>

<p>The whole process is explained in detail in the following article: <a href="https://dzone.com/articles/understanding-the-kubelet-core-execution-frame" rel="nofollow noreferrer">Understanding the Kubelet Core Execution Frame</a>.</p>
