跳到主要内容

第二十三课

PR #197

PR #201

Cleanup handling of config channels in RunSyncLoop

PR #192

Logging + Misc cleanup

// Implement http.ResponseWriter
func (rl *respLogger) Header() http.Header {
return rl.w.Header()
}

// Implement http.ResponseWriter
func (rl *respLogger) Write(b []byte) (int, error) {
return rl.w.Write(b)
}

// Implement http.ResponseWriter
func (rl *respLogger) WriteHeader(status int) {
rl.status = status
if status != http.StatusOK && status != http.StatusAccepted {
// Only log stacks for errors
stack := make([]byte, 2048)
stack = stack[:runtime.Stack(stack, false)]
rl.statusStack = "\n" + string(stack)
} else {
rl.statusStack = ""
}
rl.w.WriteHeader(status)
}

PR #209

Fix boilerplate everywhere + add hook to keep it fixed

PR #975

Refactor kubelet to use http.ServeMux

// ServeHTTP responds to HTTP requests on the Kubelet
func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) {
defer httplog.MakeLogged(req, &w).StacktraceWhen(
httplog.StatusIsNot(
http.StatusOK,
http.StatusNotFound,
),
).Log()
s.mux.ServeHTTP(w, req)
}
// NewServer initializes and configures a kubelet.Server object to handle HTTP requests
func NewServer(host HostInterface, updates chan<- interface{}) Server {
server := Server{
host: host,
updates: updates,
mux: http.NewServeMux(),
}
server.InstallDefaultHandlers()
return server
}

// InstallDefaultHandlers registers the set of supported HTTP request patterns with the mux
func (s *Server) InstallDefaultHandlers() {
s.mux.HandleFunc("/healthz", s.handleHealth)
s.mux.HandleFunc("/container", s.handleContainer)
s.mux.HandleFunc("/containers", s.handleContainers)
s.mux.HandleFunc("/podInfo", s.handlePodInfo)
s.mux.HandleFunc("/stats/", s.handleStats)
s.mux.HandleFunc("/logs/", s.handleLogs)
s.mux.HandleFunc("/spec/", s.handleSpec)
}

这段代码定义了一个 Server 结构体,并实现了一些方法,用来响应 HTTP 请求。下面对这些方法进行解释。

ServeHTTP 方法: 这是实现 http.Handler 接口的方法。这个方法首先使用 httplog.MakeLogged 方法记录 HTTP 请求和响应的日志,然后通过 s.mux.ServeHTTP 方法将 HTTP 请求交由 http.ServeMux 来处理。

NewServer 方法: 这个方法用来初始化一个 Server 对象。方法接受两个参数:host 是一个 HostInterface 对象,它提供了 Server 需要的一些功能;updates 是一个只能发送数据的通道,它可能用于发送一些更新信息。方法首先创建一个 Server 对象,然后调用 InstallDefaultHandlers 方法注册默认的请求处理函数,最后返回这个 Server 对象。

InstallDefaultHandlers 方法: 这个方法为 http.ServeMux 注册一些默认的请求处理函数。每一个请求处理函数都通过 s.mux.HandleFunc 方法注册,方法接受两个参数:第一个参数是 HTTP 请求的路径,第二个参数是处理这个请求的函数。例如,/healthz 请求由 s.handleHealth 方法处理,/container 请求由 s.handleContainer 方法处理,以此类推。

总体来看,这段代码定义了一个 Server 对象,用来处理 HTTP 请求。这个 Server 对象通过 http.ServeMux 来分发和处理 HTTP 请求,可以通过注册不同的请求处理函数来处理不同的 HTTP 请求。

PR#980

Make cloud providers into plugins

/*
Copyright 2014 Google Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cloudprovider

import (
"sync"

"github.com/golang/glog"
)

// Factory is a function that returns a cloudprovider.Interface.
type Factory func() (Interface, error)

// All registered cloud providers.
var providersMutex sync.Mutex
var providers = make(map[string]Factory)

// RegisterCloudProvider registers a cloudprovider.Factory by name. This
// is expected to happen during app startup.
func RegisterCloudProvider(name string, cloud Factory) {
providersMutex.Lock()
defer providersMutex.Unlock()
_, found := providers[name]
if found {
glog.Fatalf("Cloud provider %q was registered twice", name)
}
glog.Infof("Registered cloud provider %q", name)
providers[name] = cloud
}

// GetCloudProvider creates an instance of the named cloud provider, or nil if
// the name is not known. The error return is only used if the named provider
// was known but failed to initialize.
func GetCloudProvider(name string) (Interface, error) {
providersMutex.Lock()
defer providersMutex.Unlock()
f, found := providers[name]
if !found {
return nil, nil
}
return f()
}

这段代码定义了一个云服务提供商(cloud provider)的注册与获取机制。以下是对代码的详解:

Factory 类型:这是一个函数类型,返回一个实现了 Interface 接口的对象以及一个错误对象。这个函数类型用来创建云服务提供商对象。

providers 变量:这是一个全局的私有变量,类型为 map[string]Factory。这个 map 用来保存已注册的云服务提供商的工厂函数。map 的键是云服务提供商的名字,值是创建云服务提供商的工厂函数。

RegisterCloudProvider 函数:这个函数用来注册一个云服务提供商。函数接受两个参数:一个是云服务提供商的名字,另一个是创建这个云服务提供商的工厂函数。函数首先获取 providers 的互斥锁,然后检查云服务提供商是否已经注册,如果已经注册则直接报错并退出。如果没有注册,则在 providers 中添加新的云服务提供商,并在日志中记录一条信息。

GetCloudProvider 函数:这个函数用来获取一个已注册的云服务提供商。函数接受一个参数:云服务提供商的名字。函数首先获取 providers 的互斥锁,然后在 providers 中查找云服务提供商的工厂函数,如果找不到则返回 nil 和 nil。如果找到了工厂函数,则调用工厂函数创建云服务提供商对象并返回。

总的来说,这段代码通过 RegisterCloudProvider 和 GetCloudProvider 两个函数提供了一个全局的云服务提供商注册和获取机制。