一 背景
公司企业面对不断变化的用户需求,对于应用的快速开发上线提出了新的挑战,一方面在功能性能方面要求越来越高,另一方面对安全性、稳定性、高可用性、可扩展性也越来越苛刻。当云计算重构整体IT产业的同时,也赋予了企业崭新的增长机遇,通过充分利用云计算的能力,释放更多精力专注于自己的业务。以容器为代表的云原生技术正在推动着整个商业世界飞速发展,企业数字化转型过程中,云原生成为企业持续发展和不断创新的必然选择,一款简单易用、灵活扩展、安全可靠的容器平台是众多企业的必由之选。
二 立而不破
2.1 困境
在微服务改造及上线过程并不是一帆风顺,涉及微服务拆分,云原生架构不可变得基础设施,声明式的API,微服务,服务网络,DevOPS等,这些都是传统企业遇到的困境。
- 基础设施维护成本高:对于基础设施如Kubernetes,其存在很多组建及高可用部署模式,内部还又很多特性需要运维人员熟悉精通,再应用或集群出现故障时,能第一时间排障修复,对基础设施维护人员提出了更高的技术要求。
- 架构复杂性高:对于不开发服务但维护服务的团队来说,潜在的复杂性是一个巨大的挑战。他们不是管理几个正在运行的服务,而是管理数十,数百或数千个正在运行的服务。服务越多,沟通越多,潜在的失败风险就越多,对于微服务的拆分也提出了更高的要求。
- DevOPS:传统的DevOPS发不到服务器上,在云原生中需要发布到Kubernetes中,如果实现在云原生中灰度发布,对于DevOPS也提出了更为严格的挑战。
- 监控日志:在容器中需要对服务日志进行监控可视化,并对异常监控进行告警分级,故障处理,对于海量日志的持久化存储分析也提出了更高的要求。
- 服务治理:对于服务直接的调用,如何保障服务器直接的调用安全,以及如何实现服务调用直接的策略等,都需要了解更多的云原生技术来实现。
2.2 破境
对于在云原生背景下,技术的更新迭代,如果让技术转型立而不破,有机结合呢?
对于我们的应用,一路小跑,追求短平快的快速发布模式,快速实错,从工具->单模块单体->多模块单体->微服务架构,基础架构也在不断变更,从IDC物理机房服务器自己完成高可用架构部署->云服务器,利用公有云资源提供的LB及其他SaaS产品完成高可用架构->容器的基础编排基础设施Kubernetes,为满足市场需求不断进行技术革新与演进。
云原生在为我们提供便利的同时,也提出了更多的挑战,如何运用好云原生,加速企业数字化转型,在此我们就需要借助公有云厂商为我们提供的一站式云原生解决方案,腾讯云容器服务(Tencent Kubernetes Engine,TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务。腾讯云容器服务完全兼容原生 kubernetes API ,扩展了腾讯云的云硬盘、负载均衡等 kubernetes 插件,为容器化的应用提供高效部署、资源调度、服务发现和动态伸缩等一系列完整功能,解决用户开发、测试及运维过程的环境一致性问题,提高了大规模容器集群管理的便捷性,帮助用户降低成本,提高效率。容器服务提供免费使用,涉及的其他云产品另外单独计费。
TKE的使用使得我们可以将容器云交由专业团队进行维护,我们自己来专注于自身业务,释放更多经历对自身业务进行创新,助理企业进行数字化转型。
以下是在应用TKE中的一些实战排错案例。
三 实战排错
3.1 部署应用无法查看到日志
问题描述: 部署devlopment类型的前端服务(vue nginx),事件有报错,查看日志为空。
解决方案:日志为容器运行产生日志,创建容器时已报错退出,因此无日志输出可以查看具体事件分析原因。
反思:监控容器日志,将容器日志打印在控制台,采用EFK方案可以在TKE平台查看容器日志,也可以采用filebeat采集容器中持久化文件的日志。
3.2 同vpc内集群网段不能冲突
问题描述:选择Global Router网络类型时,同vpc内集群网段不能冲突
3.3 控制台编写yaml文件未生效
问题描述:修改yaml,没有提示错误,但点击完成后不生效,还是重置为之前的yaml文件
解决方式:kubectl在节点中手动创建,根据报错修改配置。
yaml配置:
3.4 nodeport svc不能被访问
问题描述:nodeport svc不能被访问
解决方式:先在节点内通过curl访问pod,可以正常访问,之后访问service,也可以正常返回信息,判断在node节点上面的云防火墙有限制,查看服务器iptables策略正常,放行安全组放通nodeport端口后正常。
3.5 创建pod出现未找到网络插件错误
问题描述:No networks found in /etc/cni/net.d/multus
解决方式: 查看对应节点10.0.0.8是存在该插件的,重新部署解决。可能是node是新加入的节点,pod创建时网络插件未ready。
3.6 pod调度失败
问题描述:pod 0调度正常, pod1调度报错:
代码语言:javascript复制0/3 nodes are available: 1 node(s) didn't match pod affinity/anti-affinity, 1 node(s) didn't satisfy existing pods anti-affinity rules, 2 Insufficient cpu.
解决方式:由于pod反亲和性podAntiAffinity 配置,pod(master-1)不能调度到已经有pod (app=elasticsearch-master)的node3上,可以修改为preferredDuringScheduling-IgnoredDuringExecution或者考虑再增加一个新node。
3.7 pod中容器时区不一致问题
解决方式:build镜像前,在Dockerfile中配置时区。
代码语言:javascript复制RUN rm -f /etc/localtime
&& ln -sv /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
&& echo "Asia/Shanghai" > /etc/timezone
- 创建elasticsearch应用一直未ready
Readiness probe failed: Waiting for elasticsearch cluster to become ready (request params: "wait_for_status=green&timeout=1s" )
解决方案:需要确保Elasticsearch在升级到有状态集和Kubernetes节点本身期间保持可用,等待集群变green。通过curl 192.168.255.131:9200/_cluster/health?pretty查看状态
3.8 如何规划容器网络service和pod的网络
问题描述:如何规划service和pod该选用哪个ip地址段以及子网掩码长度
解决方案:设计网络时一定要结合业务设置合理的ip地址和子网掩码,防止后期pod和service的ip地址不够使用。
3.9 配置热更新
问题描述:对于在云原生中配置中心,例如configmap和secret对象,虽然可以进行直接更新资源对象,对于引用这些有些不变的配置是可以打包到镜像中的,那可变的配置呢?每次配置更新后,都要重新打包一次,升级应用。镜像版本过多,也给镜像管理和镜像中心存储带来很大的负担。定制化太严重,可扩展能力差,且不容易复用。在K8s中Configmap或Secret使用有两种方式,一种是env系统变量赋值,一种是volume挂载赋值,env写入系统的configmap是不会热更新的,而volume写入的方式支持热更新!
解决方案:
1.业务改造:如果业务自身支持 reload 配置的话,比如nginx -s reload,可以通过 inotify 感知到文件更新,或者直接定期进行 reload(这里可以配合我们的 readinessProbe 一起使用)。
2.基础设施自动滚动升级:目前有个开源工具Reloader,它就是采用这种方式,通过 watch ConfigMap 和 Secret,一旦发现对象更新,就自动触发对 Deployment 或 StatefulSet 等工作负载对象进行滚动升级。
四 反思
TKE助力企业将更多的精力放在迁移平台的逻辑业务开发,提供从基础设施高可用部署,其主要针对容器进行编排管理。
- CI/CD方面,TKE可以非常方便的与业界优秀的持续集成持续部署软件集成,例如Jenkins、Gitlab CI、Tekton、Argo CD等。
- 监控方面:TKE内置了监控系统,可以非常方便的采集监控宿主及容器的监控信息,同时简单配置也可以对部署的业务进行监控告警。
- 服务治理方面:在TKE上可以部署服务网格如Istio或者于腾讯微服务治理平台TSF联动进行微服务治理等。
其于腾讯云LB/CBS等实现联动,提供一整套完善的云原生解决方案,而且TKE也进行了开源,可以私有化进行部署,在这里可以遇到志同道合的友人,一块探讨适合自己业务的云原生之路。