K8s概述(三):最佳实践

如何配置pod

pod的生命周期:

  • Pending:etcd已经保存了Pod的状态,但是这个Pod还没有被scheduled,还没拉取image
  • Running:Pod已经schedule到node上,kubelet已经创建了所有的容器
  • Succeeded:Pod中所有容器被终止,不再重启
  • Failed:Pod中所有容器被终止,至少有一个容器是因为失败而终止
  • Unknown:API server与Pod的通信中断,通常是因为与kubelet的通信中断

pod

init container时做一些启动容器的准备工作,比如拉取数据、建数据库表、等待其他server启动等。可以设置多个init container,所有操作成功后容器才会启动。

永远需要livenessProbe和readinessProbe,前者用于让deployment决定何时需要重启,或者滚动升级的时候是否成功,后者用于决定该Pod何时开始可以接收流量。如果不设置,那么有可能丢失流量
livenessProbe。

许多应用程序经过长时间运行,最终过渡到无法运行的状态,除了重启,无法恢复。通常情况下,K8S会发现应用程序已经终止,然后重启应用程序/pod。

有时应用程序可能因为某些原因(后端服务故障等)导致暂时无法对外提供服务,但应用软件没有终止,导致K8S无法隔离有故障的pod,调用者可能会访问到有故障的pod,导致业务不稳定。K8S提供livenessProbe来检测应用程序是否正常运行,并且对相应状况进行相应的补救措施。
readinessProbe。

在没有配置readinessProbe的资源对象中,pod中的容器启动完成后,就认为pod中的应用程序可以对外提供服务,该pod就会加入相对应的service,对外提供服务。但有时一些应用程序启动后,需要较长时间的加载才能对外服务,如果这时对外提供服务,执行结果必然无法达到预期效果,影响用于体验。

比如使用tomcat的应用程序来说,并不是简单地说tomcat启动成功就可以对外提供服务的,还需要等待spring容器初始化,数据库连接没连上等等。对于spring boot应用,默认的actuator带有/health接口,可以用来进行启动成功的判断。

在postStart和preStop hook中正确的初始化或者关闭容器,比如如果不能修改代码但是需要清数据库。当你使用service的时候,需要一段时间让kube-proxy、endpoint完成工作、去掉iptables等,因此正在处理的请求可能会受容器停止的影响。这时候需要在这里处理优雅关机。
--

mysql有状态部署

创建StatefulSet以解决集群中单点故障时数据迁移的问题。

StatefulSet在pod调度的时候可以保证稳定的持久化存储、网络标识、有序部署和有序收缩。

Statefulset在启动的时候,pod的名字是statefulset的名字加上从0开始的序号。

mysql

使用GPU

Kubernetes 提供了Device Plugin 的机制,用于异构设备的管理场景。原理是会为每个特殊节点上启动一个针对某个设备的DevicePlugin pod, 这个pod需要启动grpc服务, 给kubelet提供一系列接口。DevicePlugin 注册一个 socket 文件到 /var/lib/kubelet/device-plugins/ 目录下,kubelet 通过这个目录下的socket文件向对应的 Device plugin 发送grpc请求。

containerd

它主要负责的工作是:

  • 管理容器的生命周期(从容器的创建到销毁)
  • 拉取/推送容器镜像
  • 存储管理(管理镜像及容器数据的存储)
  • 调用runc 运行容器
  • 管理容器的网络接口及网络
    containerd 被设计成嵌入到一个大系统中,而不是给开发人员和终端的设备使用。

libnvidia-container

提供一个库和一个简单的CLI工具,使用这个库可以使NVIDIA GPU被Linux容器使用。

流程

  • nvidia-container-runtime-hook :把docker的default-runtime修改为nvidia-container-runtime-hook
  • 在创建容器前先hook,检查是否需要GPU(是否有NVIDIA_VISIBLE_DEVICES ),如果需要则调用libnvidia-container暴露GPU。
  • K8s通过device-plugin
    • 上报节点GPU数量
    • 分配GPU:把GPU需求转换为NVIDIA_VISIBLE_DEVICES注入容器,并将设备和驱动映射到容器中

gpu

高可用

etcd高可用

三节点etcd做高可用,raft算法。

master高可用

master节点的kube-scheduler、kube-controller-manager和kube-apiserver有单点问题,需要做高可用:

  • 使用k8s leader-elect部署以下两个组件kube-scheduler和kube-controller-manager
  • 使用keepalived+haproxy以VIP访问到不同的kube-apiserver

haproxy

kube-dns高可用

使用k8s anti-affinity部署多个实例在不同节点

监控 - Prometheus

Prometheus

  • Prometheus Server:核心组件,负载收集监控项和存储数据到TSDB
  • Jobs/Exporters:监控并采集指标
  • Pushgateway:针对Short-lived jobs,定时将指标push到Pushgateway
  • Alertmanager:报警组件;
  • Grafana:查看指标或者创建仪表盘

prometheus

应用

  • 监控k8s组件(工作队列长度、QPS、延迟数据等)
  • 监控宿主机数据(负载、CPU、磁盘等)
  • 监控pod、node、容器的数据
  • 监控报警
  • Grafana查看指标

自动扩缩容

  • 传统:CPU、内存阈值
  • Custom metrics
  • 通过service暴露/metrics数据
  • 使用Prometheus收集数据项
comments powered by Disqus