本文均为集体工作中的一些了解,可能存在纰漏、忽略、认知谬误的中央,敬请体谅,欢送评论区探讨。
1、序
一般来说,如果说要做容器化,那就是两个方向,docker swarm或者k8s,前者复杂度低一些,易于从docker-compose转换。后者功能完善,然而学习和保护难度很高。
集体认为,如果打算做容器化,目前简直没有什么理由去抉择swarm了。除了ConfigMap、Secret,或者Ingress,k8s好用的性能还有不少,swarm简直没有什么劣势。
不过如果是打算将零散的docker-compose部署的服务疾速聚合起来,对立治理,那swarm 还是能够一用的。
然而我这里为什么要独自把 容器化 和 k8s 离开说呢?因为目前所在的公司,采取的策略就是只做“容器化”:
将服务环境,代码,配置文件等所有依赖项打包为根底容器和Dockerfile,应用docker-compose的形式管制。除此之外,其余所有因素不变。
从服务部署的角度来说,服务的确被打包了,如果须要扩容/迁徙,docker容器天然是比间接在宿主机上部署不便了许多。然而停留在这个阶段,我感觉不合理。
2、当初的“容器化”
简略来说,咱们目前的“容器化”是这么做:
- 将原来的部署文档,整顿转化成一个
dockerfile
+docker-compose.yaml
- 代码仓库配置上CI(jenkins/gitlab-ci,均可),每次代码合并后打包一个新的镜像。
- 应用新打包的镜像将代码和环境一起公布,而非仅公布代码。
咱们也的确有了一些收益:
1、每当服务器扩容时,无需在服务器上配置服务环境,只需装置docker+部署服务,如果后续服务器转做他用,也不必放心是否会有影响。
2、服务一致性失去保障,一样的代码能够失去一样的后果,宿主机很难影响到容器,简直不会呈现同一个版本代码在不同服务器上体现不统一的状况。
然而运行一段时间后,我感觉这样做的收益并没有很高:
1、没有方法纵观全局,观测所有服务,每个服务的运行状态还是须要登录对应的服务器能力看到。这样和不做容器化没有什么区别。
2、nginx配置并不能与容器联动,一旦容器须要更换服务器还是须要手动更新(动态保护,compose写死docker内网IP)
3、尽管配置了服务日志收集,然而一旦服务部署的服务器有变动,还是须要人工批改日志收集的agent。
正如这一段的题目,为什么不持续向前走?做的更多?你上swarm/k8s不就能在master上治理整个集群了吗?
是的,无论是swarm还是k8s,都是能够抉择的,然而因为事实的种种原因,目前只能停留在这一步。
3、现实中的容器化
把代码和环境打包在一起只是容器化的第一步,还须要持续往前走,能力解决残留问题。动态保护容器,其实有点把容器当虚拟机的象征,只不过每个虚拟机里只有一个服务。现实状况下,容器变动导致的路由问题和服务间相互发现/拜访都应该是主动的,而非动态。
无论是间接应用docker,还是用docker swarm还是有很多问题须要人为去解决。而k8s都有计划。
基于我对于k8s通俗的了解,我感觉,推动容器化,应该有以下几个问题要关注和解决:
1、配置和日志:
配置:能够间接用ConfigMap+Secret解决。
日志:Sidecar模式比拟不错,间接在Pod内启动一个agent负责这个Pod内的所有文件日志收集。Pod之间不共享。
日志服务端也有几个可选项,个别用ES,如果日志量很小也能够用loki(日志注释无索引,然而更轻便)。
尽管通过stdout/stderr收集日志也能够,然而这样没有Sidecar形式灵便。而且日志能够通过文件名进行更多辨别。个别还是会抉择Sidecar形式收集日志。
这两个问题解决了,容器就曾经能够根底的运行:
- 从git仓库拉取代码,打包成镜像,通过Deployment公布
- 从ConfigMap+Secret 读取+挂载配置,而且这两者也反对动静更新。
- 每个Pod都应用Pod内的agent收集业务日志,发送到服务端。
2、申请路由和服务发现/服务间的相互申请:
除了上述这个点,还有一些点须要去探讨:容器在调度过程中会产生变动,被杀死或者重启的。
- 如何将内部的申请顺利导入到指标容器?
- 容器间的发现和相互拜访如何实现?
Ingress我感觉能够算是k8s的入口网关了,一个Ingress资源须要一个理论的Ingress Controller能力实现。一般来说,用Ingress-nginx就能够。
其次,Service能够将服务形象,对外提供一个稳固的虚构endpoint,能够用于连贯,对内能够依照label转发申请到Pod上。
这样拜访Service就能够将申请发送到对应的Pod,而不须要间接拜访Pod。
对于服务发现和服务间的申请,coreDNS齐全能够解决。每个Service创立后,都会在DNS内留下记录,其余服务能够间接应用DNS拜访
一般来说,域名全程为:<service-name>.<namespace>.svc.cluster.local
,前面的能够省略,指定<service-name>.<namespace>
就能够确切拜访到服务了,通过这样简略的形式进行服务发现,那么服务间的相互拜访也天然没有太大问题。
这两个问题解决之后,申请能够顺利从内部路由到指标容器,荣期间也能够顺利相互发现/相互拜访。
4、路线还有多远?
那么如果要逾越这一步,实现残缺的容器化,间隔还有多远?还须要解决什么问题?
尽管无奈理论去操作,去将以后的我的项目革新成k8s,然而这并不障碍思考一下,“当初间隔齐全k8s化有多远,还须要解决那些问题。”
先从单个容器来说:
代码配置方面,是在阿里云ACM上,代码间接拉取的。改为ConfigMap应该没有太大问题。
日志收集方面,目前是应用的promtail做为agent,将日志发送到loki。改为Pod内减少一个promtail容器也应该没有太大问题
promtail的配置能够存在ConfigMap上,不同的服务依照命名辨别就能够了。
还有一个要留神的点,就是docker肯定要配置容器日志大小限度,免得docker日志打满。
因为日志会先写服务容器内,再被promtail容器读,不须要保留太多,个别也不须要间接登录容器看文件日志。
服务路由和服务发现方面:
从nginx动态路由改为Ingress-nginx因该也不会有太大艰难,把当初的nginx配置导入,后端转发到Service就能够了。
目前服务发现很简略粗犷,间接拜访其余内网域名(每个服务配置了一个内网域名),从nginx绕一圈。这个改变并不大,只不过从内网域名改成Service域名就能够了。
部署公布方面:
目前应用jenkins+gitlab 来实现代码公布,测试和预公布环境都是分支触发,对应分支有代码提交就会触发部署。(非凡分支只能merge,不容许间接提交)
这部分应该不须要太大改变,只是理论的部署执行步骤须要改一下。
服务监控打点方面:
目前对于服务本人的监控没有太大需要,当初服务本身没有任何打点。
如果要用的化,还是promtheus比拟适合,官网对于java、go都有客户端。自定义打metric难度不大。
目前来说,我感觉这些问题如果都能理论解决,应该就能比拟好的实现迁徙。当然理论过程中必然也会遇到很多问题,不过见招拆招嘛,有问题解决问题就能够了。
5、小结:
在论断局部,我感觉要先强调的一点是:不同人对待问题的角度不同,不能说谁对谁错。
从运维的角度来说,上k8s很好,部署新服务很简略,服务器扩容/缩容也不便了许多,不再强依赖宿主机等等。
然而从全局治理的角度来说,可能会有很多思考:
1、当初的痛点是否能够承受,有没必要马上上k8s,上了之后会不会有什么问题。
2、研发都须要对k8s有肯定了解,每个研发都须要再学习。否则在开发/调试/查问题上有影响。
3、相比于nginx动态配置+动态服务来说,k8s动静的中央多了很多,依赖也多了很多。保护整个零碎须要关注更多的内容(比方etcd)一旦呈现问题须要更多的常识能力考察分明。
简而言之,引入k8s,对于运维角度来说,无疑是大好事,各方面都更好。然而,无论是引入k8s还是引入其余新的技术,都须要综合衡量,能力让服务越来越好。