Kubernetes 无状态应用的一般特征
时间:2022-07-25
本文章向大家介绍Kubernetes 无状态应用的一般特征,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
以 12 要素为代表的微服务标准,很好地给微服务的特征做出了指导。然而具体到以容器形式在 Kubernetes 上运行的无状态业务应用上,这个标准是有些高层的——它看重的是方法和架构。如果仅从外在视角来对一个“顺眼”的 Kubernetes 应用进行观察,这个应用应该有什么特征呢?
依赖关系清晰
微服务应用通常会有各种外部依赖,例如数据库、缓存、队列等平台能力,或者业务上的依赖服务等,因此一个健康的微服务组合而成的应用,必须能处理好依赖关系。
微服务的启动顺序不是固定的,并且存在独立更新、重启的可能。而很多应用仅在启动时进行连接,这就要求在 Kubernetes 上运行的应用,首先在启动时,不会因为暂时无法连接依赖服务直接崩溃;同时在运行期间,也有处理这种随时重连的能力。
具备自检能力
存活检测关注的是进程是否活跃,是否应该重新启动;就绪检测代表的是服务能力,是否应该保存在 Service 的负载均衡池中。
在没有设置就绪检测的情况下,Pod 一旦启动成功,K8s 就会把相关服务的请求发给该实例,如果这个实例启动较慢,就有可能对业务造成损失。同理,存活和就绪检测应该分别进行,例如业务阻塞时,暂时将实例摘除,但是无需重启,即可逐步恢复服务能力。
联系到前面的依赖关系问题,在微服务环境中,一个服务的就绪检测应该仅仅关注本应用的情况,检测过程中不应包含对依赖服务的调用——否则所有依赖故障服务的其它服务的就绪检查失败,造成大面积故障。
日志采集和处理
- 应用不应继续把日志输出到本地文件,而应该输出到
stdout
和stderr
; - 集群应该针对容器的
stdout
、stderr
提供统一的日志采集,建议使用 Daemonset 而非 Sidecar; - 进行日志采集的同时,集群应提供 ES、Loki 或其它类似机制来对日志进行处理,并且其处理和存储能力应该有初步预案;
- 应用日志应提供分级开关,保证同一镜像在不同环境中可以输出不同数量和级别的日志信息。
尽量优雅关停
- 容器命令入口应该有能力接收
SIGTERM
,并在需要的情况下传递给业务主进程; - 应用进程接收到
SIGTERM
信号之后,不应立刻关停,而是处理好剩余的在途业务; - 使用
preStop
等 Pod 生命周期手段来完成特定任务; - 避免使用长连接,保持简单负载均衡的有效性。
故障预防和应对
- 避免运行单 Pod 的 Deployment;
- 使用 Pod 软亲和避免同 Deployment 中的不同 Pod 分布在同一节点上;
- 遭遇不可恢复的故障,应该允许应用崩溃,由 K8s 重新启动;
- 定义 PDB(Pod disruption budgets),告知 K8s 为应用提供最低 Pod 数量保障。
资源使用
- 必须定义 CPU 和内存的 Requests;
- 必须定义内存的 Limits;
- 同一集群中的不同微服务,如果有不同 QoS 要求,应该定义不同的
qosClass
,避免被无差别驱逐。
安全相关
- 应清晰掌握并声明应用运行所需的 Linux Capabiltiy;
- 避免使用 Root 身份运行容器;
- 使用只读的 RootFS,所有写入需求应该使用存储卷来完成;
- 避免特权逃逸。
- 如何选择合适的PaaS
- 使用Qt installer framework制作安装包
- Qt Style Sheet实践(三):QCheckBox和QRadioButton
- 堆排序
- 剑指OFFER之旋转数组的最小数字(九度OJ1386)
- Qt Style Sheet实践(四):行文本编辑框QLineEdit及自动补全
- 剑指OFFER之旋转数组的最小数字(九度OJ1386)
- Qt Style Sheet实践(二):组合框QComboBox的定制
- Python基础07 函数
- 剑指OFFER之旋转数组的最小数字(九度OJ1386)
- 5 云安全解决方案的注意事项
- Qt Style Sheet实践(一):按钮及关联菜单
- Python基础06 循环
- js也可以有自定义事件 注入就是这么爽
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法