跳到主要内容

29.gostyle

PR #321

Use ID instead of Id (go style) everywhere 【代码中都用 ID 哦!】

PR #319

Initial add of an environment variable for the kubernetes master.

从环境变量中获取 apiserver的地址,没有的话,默认是 localhost:8080

PR #277

Add sync behavior to the pod registry.  Expand tests.

  • podStatus 定义枚举
  • 更新 pod 时候,添加同步等待逻辑

type PodStatus string

const (
PodRunning PodStatus = "Running"
PodPending PodStatus = "Pending"
PodStopped PodStatus = "Stopped"
)


func (storage *PodRegistryStorage) Update(obj interface{}) (<-chan interface{}, error) {
pod := obj.(api.Pod)
if len(pod.ID) == 0 {
return nil, fmt.Errorf("id is unspecified: %#v", pod)
}

return apiserver.MakeAsync(func() (interface{}, error) {
err := storage.registry.UpdatePod(pod)
if err != nil {
return nil, err
}
return storage.waitForPodRunning(pod)
}), nil
}

func (storage *PodRegistryStorage) waitForPodRunning(pod api.Pod) (interface{}, error) {
for {
podObj, err := storage.Get(pod.ID)

if err != nil || podObj == nil {
return nil, err
}
podPtr, ok := podObj.(*api.Pod)
if !ok {
// This should really never happen.
return nil, fmt.Errorf("Error %#v is not an api.Pod!", podObj)
}
switch podPtr.CurrentState.Status {
case api.PodRunning, api.PodStopped:
return pod, nil
default:
time.Sleep(storage.podPollPeriod)
}
}
return pod, nil
}

PR #320

Make each pod synchronization in the kubelet an independent thread 【同步pod再也不阻塞了!】

这个方法的流程如下:

打印出期望的配置状态。

定义了一个映射 dockerIdsToKeep,用于记录需要保持运行的 Docker 容器的 ID,以及一个通道 keepChannel 用于并发处理中传递需要保持的 Docker 容器的 ID。同时创建了一个 WaitGroup,用于等待所有并发的操作完成。

遍历配置列表 config 中的所有容器配置,对于每一个配置,都会在一个新的 goroutine 中运行 kl.syncManifest 方法,该方法会检查配置的容器是否已经在运行,如果没有运行则启动它,并将需要保持的 Docker 容器的 ID 发送到 keepChannel 通道中。

在另一个 goroutine 中,从 keepChannel 通道中读取 Docker 容器的 ID,并将其添加到 dockerIdsToKeep 映射中。

等待所有的 kl.syncManifest 操作完成,然后关闭 keepChannel 通道。

调用 kl.getDockerContainers 方法获取当前主机上运行的所有 Docker 容器。

遍历所有的运行中的 Docker 容器,对于 dockerIdsToKeep 映射中不存在的容器 ID,调用 kl.killContainer 方法杀死该容器。

以上步骤完成了对容器的期望状态和当前状态的同步,即启动需要运行但当前没有运行的容器,以及杀死不需要运行但当前正在运行的容器。