跳到主要内容

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 , 补全代码