1 写在前边
自从公司项目前年上了 OpenShift 3.9 私有云平台,更新部署程序的确变得更加容易了。但是带来了很多复杂性,运维实施人员的学习曲线也陡然上升。
上云之前:在项目没上容器云的早期,应用服务集群往往是由一个Nginx作为负载均衡器,当有集群中有一个节点出现故障时,只需要将 Nginx 上负载均衡块 upstream
块中的故障节点地址移除,刷新 Nginx 即可达到快速响应,也能慢慢收集性能指标进行分析。
上云之后:在云上部署应用,应用容器生命周期由 Deployment 管理,多实例集群由 Service 负载流量 (本文暂时不谈服务网格)。当应用集群中某个Pod出现故障,通过 Deployment 或 Service 并不能直接把某个 Pod 从流量负载中移出,使用存活探针的话基本没办法收集性能指标。(以下是k8s部署简图)
本文目标:给出云平台将故障Pod流量下线通用思路,以及 OpenShift 平台将故障 Pod 流量下线,确保有收集性能指标的机会。相信本文对其他基于 k8s 的云平台也有一定参考价值。
2 梳理思路
一般来讲,Pod 的多副本的流量直接来源是 Service。当应用不可用时,我们需要保留故障 Pod,最简单的办法是只配置就绪探针,但是就绪检测接口无法确保服务的确是就绪状态,那就需要人工介入了。
流量从哪里来?
对于 Pod 而言,流量来自于 Service。初学 K8s 时,都会看到类似下边的图,大意是 Service 是通过 Selector 配置的 Label 来匹配 Pod 的。
那么,Service 直接连接到了 Pod 上么?
这样说并不准确,Service 与 Pod 中间还有一种资源 —— Endpoints,Service 通过 Selector 将匹配到的 IP 地址和端口列表存入 Endpoints。也就是说,当流量到达网络代理(KubeProxy)时,网络代理会从众多 Endpoints 中找出目标 Endpoints 并取出其中一个地址进行转发。
所以,流量能进入 Pod 是因为 Service 的 Selector 匹配到了相同 Label 的 Pod。
如果我修改了故障 Pod 的 Label,不就是可以流量下线了吗?理论可行,开始实践。
3 基于 OpenShift 实践下线故障 Pod
我们的主要目标是将故障 Pod 从流量中移除,所以可以先看看 Service 以哪个 Label 匹配 Pod。
这里以我测试环境的程序举例,通过 Deployment 处的 Actions
- Edit Yaml
打开如下界面:
可以看到 selector 选择的 Label 为 deloymentConfig: bi
,这样我们就能确认 Pod 必须也有这个标签,那么我们去修改故障节点。
退出编辑 yaml 界面,可以看到该 Service 对应的 Pod 列表,这里以 bi-4-7dt6r
作为故障节点演示,点击 bi-4-7dt6r
。
进入 bi-4-7dt6r
Pod 界面,依次点击 Actions
- Edit yaml
,我们找到与 Service 中同样的标签(注意大小写)
修改 deloymentConfig: bi
为 deloymentConfig: bi-debug
,只要标签不同即可,然后 Save
回到 Service 界面,如下图,原来的 bi-4-7dt6r
已经不在负载列表中了
我们再去 Pods 界面查看 bi-4-7dt6r
是否依然存在,如图,原来的 Pod 依然存在。
主要目标——断开流量已经达成,至于为什么会创建了一个新的 Pod 呢?
打开这个应用的 Deployment yaml,我们可以看到:好家伙,原来 Deployment 匹配 Pod 的标签也是 deloymentConfig: bi
!
这也很好解释自动创建新节点的原因了:由于 DeploymentConfig 查询不到它期待的3个Pod副本数,就创建了一个新的!
以上,今天要分享的内容都在这里了。如果本文对你有所启发,请为我送上一个赞吧!如有错漏处,还望评论告知一二!
我是 Hellxz,我们下次再见!