乐趣区

关于docker:关于容器化以及-k8s-的一点个人思考

本文均为集体工作中的一些了解,可能存在纰漏、忽略、认知谬误的中央,敬请体谅,欢送评论区探讨。

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 还是引入其余新的技术,都须要综合衡量,能力让服务越来越好。

退出移动版