kubelet主要是和docker交互,每个节点上的常驻进程

kubernetes/cmd/kubelet/kubelet.go  入口

var (
	file               = flag.String("config", "", "Path to the config file")
	etcd_servers       = flag.String("etcd_servers", "", "Url of etcd servers in the cluster")
	syncFrequency      = flag.Duration("sync_frequency", 10*time.Second, "Max seconds between synchronizing running containers and config") //检查频率
	fileCheckFrequency = flag.Duration("file_check_frequency", 20*time.Second, "Seconds between checking file for new data")
	httpCheckFrequency = flag.Duration("http_check_frequency", 20*time.Second, "Seconds between checking http for new data")
	manifest_url       = flag.String("manifest_url", "", "URL for accessing the container manifest")
	address            = flag.String("address", "127.0.0.1", "The address for the info server to serve on")
	port               = flag.Uint("port", 10250, "The port for the info server to serve on")
)

const dockerBinary = "/usr/bin/docker" // 当时默认是docker

func main() {
	flag.Parse() //命令行参数的解析
	rand.Seed(time.Now().UTC().UnixNano())

	// Set up logger for etcd client
	etcd.SetLogger(log.New(os.Stderr, "etcd ", log.LstdFlags))

	endpoint := "unix:///var/run/docker.sock"
	dockerClient, err := docker.NewClient(endpoint)
	if err != nil {
		log.Fatal("Couldn't connnect to docker.")
	}

	my_kubelet := kubelet.Kubelet{
		DockerClient:       dockerClient,
		FileCheckFrequency: *fileCheckFrequency,
		SyncFrequency:      *syncFrequency,
		HTTPCheckFrequency: *httpCheckFrequency,
	}
    // 启动kubelet
	my_kubelet.RunKubelet(*file, *manifest_url, *etcd_servers, *address, *port)

kubernetes/pkg/kubelet/kubelet.go 主体逻辑

主要封装了kubelet对docker的各种操作

代码中有各种监听的代码 比如http监听、文件监听等等,这些都是参考代码的好例子

kubelet源码解析_docker

func (sl *Kubelet) RunKubelet(file, manifest_url, etcd_servers, address string, port uint) {
	// 各种监听 
	fileChannel := make(chan api.ContainerManifest) // 配置监听
	etcdChannel := make(chan []api.ContainerManifest) // etcd监听
	httpChannel := make(chan api.ContainerManifest)
	serverChannel := make(chan api.ContainerManifest)

	go util.Forever(func() { sl.WatchFile(file, fileChannel) }, 20*time.Second)
	if manifest_url != "" {
		go util.Forever(func() { sl.WatchHTTP(manifest_url, httpChannel) }, 20*time.Second)
	}
	if etcd_servers != "" {
		servers := []string{etcd_servers}
		log.Printf("Creating etcd client pointing to %v", servers)
		sl.Client = etcd.NewClient(servers)
		go util.Forever(func() { sl.SyncAndSetupEtcdWatch(etcdChannel) }, 20*time.Second)
	}
	if address != "" {
		log.Printf("Starting to listen on %s:%d", address, port)
		handler := KubeletServer{
			Kubelet:       sl,
			UpdateChannel: serverChannel,
		}
		s := &http.Server{
			// TODO: This is broken if address is an ipv6 address.
			Addr:           fmt.Sprintf("%s:%d", address, port),
			Handler:        &handler,
			ReadTimeout:    10 * time.Second,
			WriteTimeout:   10 * time.Second,
			MaxHeaderBytes: 1 << 20,
		}
		go util.Forever(func() { s.ListenAndServe() }, 0)
	}
	sl.RunSyncLoop(etcdChannel, fileChannel, serverChannel, httpChannel, sl)
}