Kubernetes生态体系落地过程中的选型和误区
发布时间:2021-06-07 12:55:39 所属栏目:云计算 来源:互联网
导读:开源节流,是企业提升利润的两大方向;中台战略或基础结构体系常常肩负了节流的重任。无论大小企业,容器化都被认为可以大幅度地提升效率,增加运维标准化和资源利用率。但是此类事情一旦做不好很容易造成花了大量成本而效果得不到认可的尴尬结果。本次分享从
开源节流,是企业提升利润的两大方向;中台战略或基础结构体系常常肩负了节流的重任。无论大小企业,容器化都被认为可以大幅度地提升效率,增加运维标准化和资源利用率。但是此类事情一旦做不好很容易造成花了大量成本而效果得不到认可的尴尬结果。本次分享从团队的实际经验出发,聊一下容器化生态体系落地中的一些事情。
监控
容器环境一般是提供一整套解决方案的,监控可以分为三种:指标监控、业务监控、调用链监控。
业务监控和调用链监控更多的取决于业务开发部门的选型,如skywalking等。
容器环境下,指标监控非Prometheus莫属,通过Service Discovery机制中的Kubernetes plugin获得scrape路径,之后的链路就比较通畅了。
使用Prometheus过程中一个绕不开的问题是持久化存储,WAL中保存的数据不宜过多,否则内存和加载速度都会产生很大问题,官方支持的remote read/write列表中,我们考查了InfluxDB和TiDB这两个,实践中两者占用的内存都非常大,建议在集群外的物理机中进行部署,如果使用InfluxDB,如果集群中Pod创建频繁(例如使用了cronjob)可能会触发key数量限制。
日志
日志分为两种:std系列日志和文件日志,它们的区别主要在于收集方式不同,一般来说,收集上来的日志都会并进入ELK体系,后面的处理就都差不多了。
std系列日志因其属于Linux模型,可以统一从Docker数据目录中予以收集,一种部署方式是使用DaemonSet部署Fluentd并挂载hostPath。
文件形态的日志略显复杂,NFS/CephFS等分布式存储肯定不适合存放日志,我们通过emptyDir形式实现目录共享,然后新增filebeat sidecar对共享目录中的日志文件进行收集,入ELK体系。
如何与持续交付对接
这里我们关注持续交付部署部分的方案,Kubernetes的部署本质上就是不同类型的资源对象以yaml格式应用,在自研与使用开源方案之间,我们选用了Helm作为部署阶段中,持续交付与Kubernetes的沟通桥梁。通过Helm我们可以把部署配置变成一个JSON对象,辅以标准化的部署模版,实现部署的标准化,同时自带了资源状态监测,应用管理等功能。
作为一个toB性质的服务,我们不应该只关注服务本身的可用性和性能,更应该从最终用户体验维度进行自查改进。例如Kubernetes官方的Benchmark工具中提到Pod平均启动时间,但是对项目来说更加关注的是Pod平均ready时间,而探针的结果是受到项目依赖,数据库等因素的影响的。对于特定项目,很多数值是稳定的,我们可以在报警系统中进行一些统计学方面的处理。
如何正确地添加Sidecar
刚刚的日志章节,提到了使用Filebeat Sidecar来收集日志,持续交付对接过程中提到了使用模版来生成项目的yaml文件。这就意味着,日志Sidecar容器必须在项目部署配置中予以体现,与项目进行耦合。这带来了很大的复杂度,也令日志系统的配置变更流程非常复杂。毕竟稳定的项目一般不会去更新部署配置,日志系统要一直兼容老版本的规则文件。因而需要一种手段,把日志配置和项目配置进行隔离。
我们找到的办法是Kubernetes的动态准入控制(Mutating Admission Webhook)来实现sidecar injection。通过这一机制,所有的资源在操作(增删改)同步到etcd前,都会请求Webhook,Webhook可以通过或否决(allow/reject),也可以响应一个JSON Patch,修改对象的部分资源。
事实上,常常会发现我们定义的Pod中会被默认注入default service account,就是Kubernetes中内置Admission的作用产物,现在非常火的Istio,其劫持流量的原理为修改每个Pod的网络规则,也是通过这种机制注入init-container,从而在Pod中修改iptables来实现。
通过这一机制,还可以针对诸如hostPort,hostPath,探针规范作出安全审计,可以说提供了相当丰富的想象空间。风险点是Webhook必须稳定可靠,延时较长不是问题,1.14+提供了timeoutSeconds,但如果返回一个不能被apply的patch,会导致资源创建失败。
在日志应用场合,我们注册了Pod对象的Create动作,项目只需要通过annotation传入几个简单配置,就可以自动生成一个自定义的Filebeat Sidecar,非常干净和方便。
如何实现自定义PodIP
Kubernetes中每次Pod的创建都会分配一个新的IP,社区的目的是希望用户使用Service+DNS的机制实现通信,但实际上,在一些基础组件的容器化过程中,由于软件兼容性,我们会希望某些业务容器的IP固化,不因重启而变更。
这里以Redis举例要用到稳定的IP的场景:
在Redis集群模式中,“cluster meet”命令只支持IP格式,不支持域名解析配置,社区中有人提出过这个issue结果被拒了。虽说Redis集群中任意一个节点的IP变更都可以在Redis集群内自动识别(因为Instance ID不变),但是如果因为意外情况导致所有Redis集群节点同时发生重启,集群内节点两两无法发现彼此,那就只能由运维人工介入,重新让节点发现彼此,此外IP的变更也会导致有缓存的Redis客户端产生错误。
在Kubernetes中,Service相关资源由kube-proxy负责,主要体现在iptables或IPVS规则中,而PodIP是由CNI负责分配,具体体现在eth-pair和路由表中。我们选用了Calico作为CNI插件,通过cni.projectcalico.org/ipAddrs这个annotation将预期的IP传递给Calico。
相对于对CNI进行二次开发自行实现IPAM来说,这种方法的开发成本较小。
![]() (编辑:西双版纳站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |