31.putatomic
PR #307
All PUTs now atomic, Will do an atomic update if obj's ResourceVersion field is set.
把 resourceVersion 放到jsonBase字段,在SetObj方法中添加 COmpareAndSwap 逻辑
这段代码定义了 EtcdHelper 类的一个方法 SetObj,该方法用于将一个对象序列化为 JSON 字符串并将其存储在 etcd 中的特定键下。这个函数主要有以下几个步骤:
首先,使用 json.Marshal(obj) 将对象 obj 序列化为 JSON 字符串,如果序列化过程中发生错误,就直接返回这个错误。
接下来,尝试从对象 obj 中查找 JSONBase 结构。如果找到了,并且 ResourceVersion 字段的值不为 0,那么使用 etcd 客户端的 CompareAndSwap 方法尝试原子更新键 key 对应的值。在这个过程中,如果发生错误,就直接返回这个错误。
如果对象 obj 中没有找到 JSONBase 结构,或者 ResourceVersion 字段的值为 0,那么使用 etcd 客户端的 Set 方法设置键 key 对应的值。在这个过程中,如果发生错误,就直接返回这个错误。
这段代码的主要作用是在 etcd 中设置键和值。根据 obj 中的 ResourceVersion 字段是否设置,它可能执行原子更新操作。如果 ResourceVersion 字段未设置,那么它将执行普通的设置操作
PR #364
Make poll period and timeout configurable.
PR #351
Use api for pulling images instead of shelling out [使用 docker api 来拉取镜像 ,而不是二进制脚本]
这段代码定义了两个函数:Pull 和 parseImageName,主要用于处理 Docker 镜像。
Pull 函数:这是 dockerPuller 结构的一个方法,用于从 Docker registry 拉取一个指定的 Docker 镜像。它首先使用 parseImageName 函数解析镜像名称和标签,然后构造一个 PullImageOptions 对象,最后使用 Docker 客户端的 PullImage 方法拉取镜像。
parseImageName 函数:这个函数用于解析 Docker 镜像的名称和标签。首先,它通过 "/" 分隔镜像名称,然后通过 ":" 分隔镜像名称和标签。如果镜像名称包含仓库信息,它会将仓库信息和镜像名称拼接在一起。最后,返回解析后的镜像名称和标签。
在这段代码中,Pull 函数用于拉取 Docker 镜像,而 parseImageName 函数则用于解析 Docker 镜像名称,以获取正确的镜像名称和标签,这样才能正确地从 Docker registry 拉取镜像。
PR#371
Accumulate errors during validation [validate 支持同时返回多个]
// A helper for accumulating errors. This could be moved to util if anyone else needs it.
type errorList []error;
func (list *errorList) Append(errs ...error) {
*list = append(*list, errs...)
}
func validateVolumes(volumes []Volume) (util.StringSet, errorList) {
allErrs := errorList{}
allNames := util.StringSet{}
for i := range volumes {
vol := &volumes[i] // so we can set default values
if !util.IsDNSLabel(vol.Name) {
allErrs.Append(makeInvalidError("Volume.Name", vol.Name))
} else if allNames.Has(vol.Name) {
allErrs.Append(makeDuplicateError("Volume.Name", vol.Name))
} else {
allNames.Insert(vol.Name)
}
}
return allNames, allErrs
}
PR #365
add http health checks.
这个 pr 引入了 Livenessprobe 探针,我想熟悉 k8s 的同学一定不会陌生,这个功能主要是用来检测你的 pod 是否正常的运行着,目前只支持 http 探活方式。我们来看看具体代码实现:
// 健康检查者需要实现的接口
type HealthChecker interface {
IsHealthy(container api.Container) (bool, error)
}
type HTTPHealthChecker struct {
client httpDoInterface
}
// http 健康检查
func (h *HTTPHealthChecker) IsHealthy(container api.Container) (bool, error) {
params := container.LivenessProbe.HTTPGet
port := h.findPort(container, params.Port)
if port == -1 {
var err error
port, err = strconv.ParseInt(params.Port, 10, 0)
if err != nil {
return true, err
}
}
var host string
if len(params.Host) > 0 {
host = params.Host
} else {
host = "localhost"
}
url := fmt.Sprintf("http://%s:%d%s", host, port, params.Path)
res, err := h.client.Get(url)
if res != nil && res.Body != nil {
defer res.Body.Close()
}
if err != nil {
// At this point, if it fails, its either a policy (unlikely) or HTTP protocol (likely) error.
return false, nil
}
return res.StatusCode == http.StatusOK, nil
}
// 聚合健康兼职路由器
func MakeHealthChecker() HealthChecker {
return &MuxHealthChecker{
checkers: map[string]HealthChecker{
"http": &HTTPHealthChecker{
client: &http.Client{},
},
},
}
}
type MuxHealthChecker struct {
checkers map[string]HealthChecker
}
func (m *MuxHealthChecker) IsHealthy(container api.Container) (bool, error) {
checker, ok := m.checkers[container.LivenessProbe.Type]
if !ok || checker == nil {
glog.Warningf("Failed to find health checker for %s %s", container.Name, container.LivenessProbe.Type)
return true, nil
}
return checker.IsHealthy(container)
}
在 kubelet 同步 pod 时候,会检测是否健康,如果不健康,kill 掉这个容器
作业:实现一个tcp healthCheck , 补全代码