本文均为我的工做中的一些理解,可能存在纰漏、疏忽、认知错误的地方,敬请谅解,欢迎评论区讨论。java
通常来讲,若是说要作容器化,那就是两个方向,docker swarm或者k8s,前者复杂度低一些,易于从docker-compose转换。后者功能完善,可是学习和维护难度很高。nginx
我的认为,若是计划作容器化,目前几乎没有什么理由去选择swarm了。除了ConfigMap、Secret,或者Ingress,k8s好用的功能还有很多,swarm几乎没有什么优点。
不过若是是计划将零散的docker-compose部署的服务快速聚合起来,统一管理,那swarm 仍是能够一用的。
可是我这里为何要单独把 容器化 和 k8s 分开说呢?由于目前所在的公司,采起的策略就是只作“容器化”:
将服务环境,代码,配置文件等全部依赖项打包为基础容器和Dockerfile,使用docker-compose的方式控制。除此以外,其他全部因素不变。
从服务部署的角度来讲,服务确实被打包了,若是须要扩容/迁移,docker容器天然是比直接在宿主机上部署方便了许多。可是停留在这个阶段,我以为不合理。git
简单来讲,咱们目前的“容器化”是这么作:docker
dockerfile
+docker-compose.yaml
咱们也确实有了一些收益:
一、每当服务器扩容时,无需在服务器上配置服务环境,只需安装docker+部署服务,若是后续服务器转作他用,也不用担忧是否会有影响。
二、服务一致性获得保证,同样的代码能够获得同样的结果,宿主机很难影响到容器,几乎不会出现同一个版本代码在不一样服务器上表现不一致的状况。
可是运行一段时间后,我以为这样作的收益并无很高:
一、没有办法纵观全局,观测全部服务,每一个服务的运行状态仍是须要登陆对应的服务器才能看到。这样和不作容器化没有什么区别。
二、nginx配置并不能与容器联动,一旦容器须要更换服务器仍是须要手动更新(静态维护,compose写死docker内网IP)
三、虽然配置了服务日志收集,可是一旦服务部署的服务器有变更,仍是须要人工修改日志收集的agent。后端
正如这一段的标题,为何不继续向前走?作的更多?你上swarm/k8s不就能在master上管理整个集群了吗?
是的,不管是swarm仍是k8s,都是能够选择的,可是因为现实的种种缘由,目前只能停留在这一步。服务器
把代码和环境打包在一块儿只是容器化的第一步,还须要继续往前走,才能解决残留问题。静态维护容器,其实有点把容器当虚拟机的意味,只不过每一个虚拟机里只有一个服务。理想状况下,容器变更致使的路由问题和服务间互相发现/访问都应该是自动的,而非静态。
不管是直接使用docker,仍是用docker swarm仍是有不少问题须要人为去解决。而k8s都有方案。
基于我对于k8s浅显的理解,我以为,推动容器化,应该有如下几个问题要关注和解决:
一、配置和日志:
配置:能够直接用ConfigMap+Secret解决。
日志:Sidecar模式比较不错,直接在Pod内启动一个agent负责这个Pod内的全部文件日志收集。Pod之间不共享。
日志服务端也有几个可选项,通常用ES,若是日志量很小也能够用loki(日志正文无索引,可是更轻便)。运维
虽然经过stdout/stderr收集日志也能够,可是这样没有Sidecar方式灵活。并且日志能够经过文件名进行更多区分。通常仍是会选择Sidecar方式收集日志。
这两个问题解决了,容器就已经能够基础的运行:ide
二、请求路由和服务发现/服务间的互相请求:
除了上述这个点,还有一些点须要去讨论:容器在调度过程当中会发生变更,被杀死或者重启的。gitlab
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>
就能够确切访问到服务了,经过这样简单的方式进行服务发现,那么服务间的互相访问也天然没有太大问题。
这两个问题解决以后,请求能够顺利从外部路由到目标容器,荣期间也能够顺利互相发现/互相访问。
那么若是要跨越这一步,实现完整的容器化,距离还有多远?还须要解决什么问题?
虽然没法实际去操做,去将当前的项目改形成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难度不大。
目前来讲,我以为这些问题若是都能实际解决,应该就能比较好的完成迁移。固然实际过程当中必然也会遇到不少问题,不过见招拆招嘛,有问题解决问题就能够了。
在结论部分,我以为要先强调的一点是:不一样人看待问题的角度不一样,不能说谁对谁错。
从运维的角度来讲,上k8s很好,部署新服务很简单,服务器扩容/缩容也方便了许多,再也不强依赖宿主机等等。
可是从全局管理的角度来讲,可能会有不少考虑:
一、如今的痛点是否能够接受,有不必立刻上k8s,上了以后会不会有什么问题。
二、研发都须要对k8s有必定理解,每一个研发都须要再学习。不然在开发/调试/查问题上有影响。
三、相比于nginx静态配置+静态服务来讲,k8s动态的地方多了不少,依赖也多了不少。维护整个系统须要关注更多的内容(好比etcd)一旦出现问题须要更多的知识才能调查清楚。
简而言之,引入k8s,对于运维角度来讲,无疑是大好事,各方面都更好。可是,不管是引入k8s仍是引入其余新的技术,都须要综合权衡,才能让服务愈来愈好。