[基础] Kubernetes Pod 101

138 阅读2分钟

概述

Kubernetes 基础的第一篇,从Pod开始,入门部分参考华为云的文档,深入部分参考design proposals和k8s源码。

内容

101笔记

关键字段

  • metadata
  • spec.containers
  • spec.containers.resources.requests/limits
  • spec.containers.env
  • spec.containers.command
  • spec.imagePullSecrets

优雅退出

需要容器内部代码处理信号,进行优雅退出

  1. SIGTERM
  2. SIGKILL

lifecycle

  • spec.containers.lifecycle.postStart
  • spec.containers.lifecycle.preStop

PLEG proposal

Pod Lifecycle Event Generator 提出的目的是取代老kubelet为每个Pod创建一个routine导致的性能和拓展性问题。

Goals

  • 减少不必要的event
  • 降低对Runtime的并发请求
  • 支持不同的Runtime

Overview

pleg.png

  • kubelet监听2个方向的事件,1. api-server的Pod的spec改变;2. Runtime的Pod的status改变
  • PLEG解决的是第2种事件

Details

  • type PodLifecycleEventGenerator interface (pleg.go)
  • type GenericPLEG struct (generic.go)
  • Start流程:
    • go wait.Until 启动周期性 relist
    • 从Runtime获取所有Pod,更新current
    • 产生event
    • 更新cache
    • 更新old:g.podRecords.update(pid)
    • 发送event(chan满了则丢弃事件)
    • 更新cache Time

Pod Cache Proposal

不同于 https://git.k8s.io/kubernetes/pkg/kubelet/container/runtime_cache.go ,runtime-pod-cache是对PodStatus的缓存,而且尽可能做到最新,以便kubelet减少通过CRI获取容器状态的次数。

interface

type Cache interface {
	Get(types.UID) (*PodStatus, error)
	Set(types.UID, *PodStatus, error, time.Time)
	// GetNewerThan is a blocking call that only returns the status
	// when it is newer than the given time.
	GetNewerThan(types.UID, time.Time) (*PodStatus, error)
	Delete(types.UID)
	UpdateTime(time.Time)
}

cache实现

type cache struct {
	// Lock which guards all internal data structures.
	lock sync.RWMutex
	// Map that stores the pod statuses.
	pods map[types.UID]*data
        // cache中所有Pod都是在timestamp之后存入cache的
	timestamp *time.Time
	// Map that stores the subscriber records.
	subscribers map[types.UID][]*subRecord
}

type data struct {
        // 类似于v1.Pod中的ContainerStatus
	status *PodStatus
	// Error got when trying to inspect the pod.
	err error
	// Time when the data was last modified.
	modified time.Time
}

subscribe 和 notify 机制

注意 interface 中有个特殊的方法:GetNewerThan(types.UID, time.Time) (*PodStatus, error)。 它的语义是当UID容器在ts之后更新时,获取到它的status(阻塞式)。

这里就需要注册机制(func (c *cache) subscribe):

  1. 阻塞通过 ch := make(chan *data, 1) 和 <- ch实现
  2. 注册通过 c.subscribers[id] = append(c.subscribers[id], &subRecord{time: timestamp, ch: ch})

notify 机制也不复杂,本质上是一个slice,当ts发生更新时,遍历slice中符合条件的订阅者,向他们发送事件,剩下的slice如果长度大于0,则赋值给slice成员,否则删除这个UID的注册

资料

Pod:Kubernetes中的最小调度对象