kubernetes 近期进展 - 1.14-1.19

时间:2022-07-27
本文章向大家介绍kubernetes 近期进展 - 1.14-1.19,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

本文基于 kubernetes v1.19 文档,并主要关注 2019 年 以及之后(v1.14-v1.19)出现或者变化状态(比如 alpha -> beta)的特性

容器与工作负载

容器引擎

  • cri-containerd 已经成熟,在主流的云厂商新建 k8s 集群时大都(如google clout、腾讯云、阿里云)提供了基于 containerd 的创建选项 (另一个选项为 docker)。关于 docker 和 containterd 的关系和区别可以参考这篇文章
  • docker 推荐安装 19.03.11 版本
  • cri-o 在主流的云厂商未见提供选项

runtime-class

  • 和 cri 是关联的
  • v1.16 beta 引入了 scheduling 字段来支持异构集群, 即确保 pod 被调度到支持指定运行时的节点上
  • v1.18 beta 引入了 overhead 字段来支持指定与运行 Pod 相关的开销资源 (比如 pod 带来的 pause、log、kubelet、kernel 额外资源消耗), 例子如下:
kind: RuntimeClass
apiVersion: node.k8s.io/v1beta1
metadata:
    name: kata-fc
handler: kata-fc
overhead:
    podFixed:
        memory: "120Mi"
        cpu: "250m"

cloud-controller-manager

  • 这个特性其实在 1.8 就出现了,在 1.11 beta,通过一种插件机制完成对云 节点、路由、服务 等资源的控制,在很好的和云对接的同时,不改变 kubernetes 的核心逻辑
  • 这个特性虽然不是 1.15 后出现的,却很值得被注意,cloud-controller-manager 以及各种对接云的插件(比如 云 volumn 插件、云网络插件、各种 cloud-provider 配置 等等)使得 kubernetes 变成一个真正的 云原生 产品,在不同的云上通过不同插件适配,核心 api 一致,这是一个所有运行在云上的产品的共同趋势。

pod-readinessGates

  • v1.14 stable 引入了 readinessGates,允许用户向 PodStatus 中注入额外的自定义反馈或者信号. pod 中的所有 container 都 ready 并且所有 readinessGates 中定义的状态都是 'True' 之后 Pod 才会被标记为 ready.
kind: Pod
...
spec:
  readinessGates:
    - conditionType: "www.example.com/feature-1"
status:
  conditions:
    - type: Ready                              # 内置的 Pod 状况
      status: "False"
      lastProbeTime: null
      lastTransitionTime: 2018-01-01T00:00:00Z
    - type: "www.example.com/feature-1"        # 额外的 Pod 状况
      status: "False"
      lastProbeTime: null
      lastTransitionTime: 2018-01-01T00:00:00Z
  containerStatuses:
    - containerID: docker://abcd...
      ready: true

pod-EphemeralContainers

  • Kubernetes v1.16 alpha: 当由于容器崩溃或容器镜像不包含调试工具而导致 kubectl exec 无用时, 临时容器对于交互式故障排查很有用。以前进行类似的 debug 比较麻烦,比如 kubectl-spy 插件, 使用 EphemeralContainers 则更简单有效,参考 kubectl-debug 插件

阻止 Secret/ConfigMap 的自动更新

  • v1.18 alpha:默认 Secret/ConfigMap 被挂载到 pod 内部之后是会被自动更新的 (使用子路径卷挂载的容器不会收到 Secret 更新),启用 ImmutableEmphemeralVolumes 特性开关 并将 Secret 或 ConfigMap 的 immutable 字段设置为 true. 可以阻止这种默认行为
apiVersion: v1
kind: Secret
metadata:
  ...
data:
  ...
immutable: true

PodSecurityPolicy

  • v1.19 beta: Pod 安全策略(Pod Security Policy) 是集群级别的资源,它能够控制 Pod 规约 中与安全性相关的各个方面。 PodSecurityPolicy 对象定义了一组 Pod 运行时必须遵循的条件及相关字段的默认值,只有 Pod 满足这些条件 才会被系统接受。允许管理员控制的安全策略比如: 控制运行特权容器(privileged);控制使用宿主的网络和端口(hostNetwork, hostPorts)等,完整请参考
  • Pod 安全策略实现为一种可选(但是建议启用)的 准入控制器 (admission controller)
  • PodSecurityPolicy 资源被创建时,并不执行任何操作。为了使用该资源,需要对 发出请求的用户或者目标 Pod 的 服务账号 授权,通过允许其对策略执行 use 动词允许其使用该策略。

设备插件的增强

  • v1.15 beta: kubelet 提供了 gRPC 服务来使得正在使用中的设备被发现,并且还未这些设备提供了元数据
  • v1.17 alpha: kubelet 的 拓扑管理器(TopologyManager v1.18 beta) 针对建议提供者所提供的拓扑建议,对请求的资源进行(NUMA)对齐。1.17 同时引入支持 设备插件与拓扑管理器的集成。

共享进程命名空间

  • v1.17 stable: pod.spect.shareProcessNamespace=true

Konnectivity

  • todo

调度相关

基于污点的驱逐

pod-topologySpreadConstraints

  • v1.16 alpha: 用来控制一组(用 labelSelector 描述) Pods 在集群内多个故障域(用 topologyKey 描述)(例如地区,区域,节点和其他用户自定义拓扑域)之间的分布。
  • 和 PodAffinity/PodAntiAffinity 的区别
kind: Pod
apiVersion: v1
metadata:
  name: mypod
  labels:
    foo: bar
spec:
  topologySpreadConstraints:
  - maxSkew: 1
    topologyKey: zone
    whenUnsatisfiable: DoNotSchedule
    labelSelector:
      matchLabels:
        foo: bar
  containers:
  - name: pause
    image: k8s.gcr.io/pause:3.1

daemonset-pod 调度

  • v1.19 stable 从 1.12 开始默认禁用 daemonsetController 来调度 pod,具体的来说:以前 daemonsetController 会直接设置 podSpec.nodeName; 而现在只会设置 nodeAffinity,然后交给 defaultScheduler 来调度

Pod 优先级与抢占

  • v1.14 stable: 要使用优先级和抢占特性:
    1. 添加一个或多个 PriorityClasses 对象; 优先级值越大,优先级越高
    2. 创建 Pod 时设置其 priorityClassName 为所添加的 PriorityClass 之一, 或在一个集合对象(如 Deployment)的 Pod 模板中添加 priorityClassName
  • Kubernetes 1.15 及之后版本中,如果特性门控 NonPreemptingPriority 被启用, 则 PriorityClass 对象可以选择设置 preemptionPolicy: Never, 来阻止该 PriorityClass 的 pod 抢占其他 Pod。这样的 pod 在调度队列中会被放在低优先级的 Pod 的前面,但是它们不可以抢占其他 Pod
  • 抢占能力是通过 kube-scheduler 的标志 disablePreemption 来控制的,该标志默认为 false

RequestedToCapacityRatioResourceAllocation

  • 1.16 alpha: 使用 RequestedToCapacityRatioResourceAllocation 优先级函数,可以将 kube-scheduler 配置为支持包含扩展资源在内的资源装箱操作。 优先级函数可用于根据自定义需求微调 kube-scheduler 。

新的调度框架

  • v1.15 alpha: 在原有的调度流程中, 定义了丰富扩展点接口,开发者可以通过实现扩展点所定义的接口来实现插件,将插件注册到扩展点。以前使用 Scheduler Extender 或者 Multiple schedulers 的方式来扩展,未来的 scheduler 扩展插件应该采用新的调度框架来实现.

scheduler 性能相关

  • percentageOfNodesToScore:v1.14 beta 引入用于控制调度器做调度选择的时候是否覆盖所有的 Node 还是部分 Node

网络

kube-proxy 代理

  • 在大部分云厂商都提供了 iptable 和 ipvs (在 1.8 stable) 两个选项,部分云厂商(如阿里云)已经将 ipvs 作为默认选项。

备注:网络/存储等相关的能力有很大的 云厂商相关性,kubernetes 文档也在丰富这方面的文档,同一特性在不同云厂商的支持方式也在被添加到文档

IPv6DualStack

  • v1.16 alpha:IPv4/IPv6 双协议栈能够将 IPv4 和 IPv6 地址分配给 Pod 和 Service。

Service 拓扑

  • v1.17 alpha: 增加的 service 转发的亲和性能力,通过设置 topologyKeys 和 node 的相关 label 做匹配,支持让 service 转发到特定的节点,比如 访问 service ip (非 headless) 的时候转发到同一个 zone 的其他节点.

Endpoint Slice

  • v1.17 beta: Endpoint API 增强版,通过将 endpoint 做数据分片来解决大规模 endpoint 的性能问题,并且可以携带更多的信息,包括 endpoint 所在节点的拓扑信息

ServiceAppProtocol

  • v1.18 alpha: 支持自定义的 protocol 而不是仅有的 tcp/http 等

Ingress

  • v1.19 stable: ingress 出现历史已经比较久了,在 1.18 引入了 IngressClass 用于替代以前的 kubernetes.io/ingress.class 注解

存储

Volume

  • local: v1.14 stable 支持 local 卷kind: Pod apiVersion: v1 metadata: name: my-csi-app spec: containers: - name: my-frontend image: busybox volumeMounts: - mountPath: "/data" name: my-csi-inline-vol command: [ "sleep", "1000000" ] volumes: - name: my-csi-inline-vol csi: driver: inline.storage.kubernetes.io volumeAttributes: foo: bar
  • subPath 支持变量 即subPathExpr:v1.15 beta
  • CSI 容器存储接口 是 1.9 引入/1.10 beta/ 1.13 ga 的新的标准存储接口(以前是 FlexVolume ),新的存储插件基本以这种方式进行扩展. csi 卷类型不支持来自 Pod 的直接引用,只能通过 PersistentVolumeClaim 对象在 Pod 中引用.
    • CSI 原始块卷支持: v1.14 beta
    • CSI临时卷: v1.16 beta, 此功能使 CSI 卷可以直接嵌入 Pod 规范中,而不是 PersistentVolume 中。 以这种方式指定的卷是临时的,不会在 Pod 重新启动后持续存在。如下面的例子。

卷快照

  • 1.17 beta:卷快照是一个存储系统上卷的快照。VolumeSnapshotContent 是一种快照,从管理员已提供的集群中的卷获取。就像持久卷是集群的资源一样,它也是集群中的资源。VolumeSnapshot 是用户对于卷的快照的请求。它类似于持久卷声明。VolumeSnapshotClass 允许指定属于 VolumeSnapshot 的不同属性。在从存储系统的相同卷上获取的快照之间,这些属性可能有所不同,因此不能通过使用与 PersistentVolumeClaim 相同的 StorageClass 来表示。
  • 一个相关的功能是 卷克隆,通过在 pvc 的 dataSource 字段中指定存在的 PVC, 来表示用户想要克隆的 卷

持久卷

  • CSI 卷的扩充(expand):v1.16 beta,需要 csi 插件支持
  • 卷模式:v1.18 stable 支持 两种卷模式(volumeModes):Filesystem(文件系统) 和 Block(块)

StorageClass

  • volumeBindingMode: 1.17 beta volumeBindingMode 字段控制了卷绑定和动态分配 应该发生在什么时候。

存储容量

  • v1.19 alpha: 存储容量是有限的,并且会因为运行 pod 的节点不同而变化:网络存储可能并非所有节点都能够访问,或者对于某个节点存储是本地的。这个特性有两个 API 扩展接口:
    • CSIStorageCapacity 对象:这些对象由 CSI 驱动程序在安装驱动程序的命名空间中产生。每个对象都包含一个存储类的容量信息,并定义哪些节点可以访问该存储。
    • CSIDriverSpec.StorageCapacity 字段: 设置为 true 时,Kubernetes 调度程序将考虑使用 CSI 驱动程序的卷的存储容量。

通用临时卷

特定于节点的卷数限制

  • 表示各个云供应商可关联至一个节点的最大卷数的限制:v1.17 stable 可以通过设置 KUBE_MAX_PD_VOLS 环境变量的值来自定义限制,对于由已迁移到 CSI 驱动程序的树内插件管理的卷,最大卷数将是 CSI 驱动程序报告的卷数

其他

组件日志

  • 这里指 kubernetes 内部组件的 klog 日志输出,在 v1.19 alpha 支持了 结构化日志/ JSON 日志格式

crd 的功能增强

  • crd 历史已久,最近的几个版本中对 crd 的能力做了很多增强
  • todo 补充更多细节

API 优先级和公平性

  • v1.18 alpha:用于以更细粒度(对比于之前的 命令行标志 --max-requests-inflight 和 --max-mutating-requests-inflight )的方式对请求进行分类和隔离。 它还引入了空间有限的排队机制,因此在非常短暂的突发情况下,API 服务器不会拒绝任何请求。 通过使用公平排队技术从队列中分发请求,这样, 一个行为不佳的 控制器 就不会饿死其他控制器(即使优先级相同)

显式保留的 CPU 列表

  • v1.17 stable:kubernetes 支持,设置 kubelet 为节点保留资源供一些守护程序使用。1.17 增强了这个能力,支持为操作系统守护程序和 kubernetes 系统守护程序定义一个显式 cpuset,比如 --reserved-cpus=0-3

LocalDnsCache

  • v1.14 beta: NodeLocal DNSCache 通过在集群节点上作为 DaemonSet 运行 dns 缓存代理来提高集群 DNS 性能, kubelet 需要打开 --cluster-dns 标志

windows 集成

  • v1.18 stable: GMSA
  • v1.17 beta: windowsOptions-RunAsUserName

kustomize

  • Kustomize 在 v1.14 之后成为 kubectl 的子命令开始被广泛的采用,官方文档也加入了不少相关的内容, 如果还不了解 kustomize 的,可以立刻开始试用一下了。

Telepresence

  • Telepresence 出现了有很长一段时间了(2017 年第一次出现在文档中),以前没有太关注。Telepresence 在远端 k8s 集群部署了一个和本地环境网络互通的 pod,可以选择 VPN 的方式。这个 pod 会将指定的网络流量,环境变量,磁盘等数据转发到本地的服务。且本地服务的 DNS 查询,网络流量,都可以被路由到远端的 k8s 集群。是个很有意思的工具,用于开发和 debug 是不错的方案,值得学习一下。

node-problem-detector

  • node-problem-detector 和其定制版本在各个公司的内部也有不少应用,近期进展可以参考这里