本文主要包括 Pod 的基本概念、使用场景,以及如何在时速云平台上进行 Pod 的编排部署,希望对大家在进行微服务架构实践时有所帮助。
1.我们先来看一下 Pod 的基本特性
Pod 是 Kubernetes 为部署、管理、编排容器化应用提出的概念,也是 Kubernetes 中的最小部署单元,直译过来的意思是“豆荚”,既简单又实用。
Pod 是由一组紧耦合的容器组成的容器组,当然目前最流行的就是 Docker 容器, Pod 就可以作为 1 或者多个 Docker 容器的载体,当然也支持 CoreOS 的 rkt ,并很容易扩展支持更多容器技术。
Pod 中的所用容器会被一致调度、同节点部署,并且在一个“共享环境”中运行。这里的“共享环境”包括以下几点:
1 )所有容器共享一个 IP 地址和端口空间,意味着容器之间可以通过 localhost 高效访问,不能有端口冲突
2 )允许容器之间共享存储卷,通过文件系统交互信息
3 )容器之间可以通过 IPC ( inter-process communication)进行通信(目前这个 feature 还没有实现,主要依赖于 Docker 对容器之间进程通信的支持,在 Docker 社区有 issue track )
所以,如果按照每个 Docker 容器一个 process 的建议, Pod 则是支持多个关系紧密进程很好的方式,更像是一个容器化的虚拟机。
Pod 也提供探针功能,对容器服务进行健康检查,目前有两种方式:
1 ) LivenessProbe,用来检测服务是否正常运行,如果定义的规则失败了,系统就会杀掉这个容器,默认情况下自动创建一个新的容器。
比如一个容器服务对外提供 Restful Service ,服务可能会在某些情况下 hang 或者响应时间变长,我们就可以定义一个 URL 作为 health check ,一旦这个 URL 没有正常响应,就认为需要重启服务,这时候就可以使用 LivenessProbe 。
2 ) ReadinessProbe,用来标识容器是否准备好提供正常服务,如果没有启动完成检测失败,系统会将该服务节点从服务代理的列表中删除,用户的请求就不会路由到该节点了。 Pod 定义和 LivenessProbe 类似:
在 Pod 的生命周期管理中,还提供了在容器启动后(postStart) 和容器停止前(preStop)两个 handler ,方便我们在这两个事件上添加自定义的 hook 操作。
比如我们可以定义在容器创建后,先执行一条命令把自己的应用复制到 tomcat 的 webapps 下,那么直到这个 hook 操作完成,才会进行容器启动等后续操作。
2.接下来,我们看看 Pod 有哪些主要的应用场景
Pod 可以用来承载垂直化的集成应用,比如 LAMP ,但是 Pod 的主要目的还是支持需要一起部署、一起管理的辅助进程,包括:
1 )内容管理系统,文件和数据加载进程,本地 cache 管理进程等
2 )日志压缩、 rotation 、备份、快照等
3 )数据变化监听、日志和监控适配器,事件分发等
4 )控制、管理、配置、升级程序
如果希望了解更多相关解释,推荐一篇关于这种容器组的设计模式的文章,也是微服务架构中很重要的思想:
http://blog.kubernetes.io/2015/06/the-distributed-system-toolkit-patterns.html
下面我们来看几个实际的使用场景:
1 )业务服务需要收集日志
某服务模块已经实现了一些核心的业务逻辑,并且稳定运行了一段时间,日志记录在了某个目录下,按照不同级别分别为 error.log 、 warning.log 、 info.log ,现在希望收集这些日志并发送到统一的日志处理服务器上。
这时我们可以修改原来的服务模块,在其中添加日志收集、发送的服务,但这样可能会影响原来服务的配置、部署方式,从而带来不必要的问题和成本,也会增加业务逻辑和基础服务的藕合度。
如果使用 Pod 的方式,通过简单的编排,既可以保持原有服务逻辑、部署方式不变,又可以增加新的日志收集服务。
而且如果我们对所有服务的日志生成有一个统一的标准,或者仅对日志收集服务稍加修改,就可以将日志收集服务和其他服务进行 Pod 编排,提供统一、标准的日志收集方式。
这里的“核心业务服务”、“日志收集服务”分别是一个 Docker 镜像,运行在隔离的容器环境中。
2 )提供 ssh 、 ftp 访问容器数据的能力
Docker Hub 或者很多第三方的镜像并没有安装 sshd 的服务,不方便我们进入容器进行配置、代码的修改、调试,很多时候需要重新构建镜像、或者在镜像基础上安装 sshd 的服务,这都需要时间和一定的学习成本。
而通过 Pod 的方式,我们就可以将现有镜像和一个 ssh 、 ftp 镜像进行编排,获得操作容器内数据的能力。
3 )代码自动更新
我们部署了一个 node.js 的应用,而且部署了几十、上百个节点,那么我希望这个应用可以定时的同步最新的代码,以便自动升级线上环境。
这时,我们当然也不希望改动原来的 node.js 应用,可以开发一个 Git 代码仓库的自动同步服务,然后通过 Pod 的方式进行编排,并共享代码目录,就可以达到更新 node.js 应用代码的效果。
并且这个同步服务还可以同其他使用 Git 代码仓库的服务编排,实现同样的需求。
4 )适配不同 IaaS 平台的环境
我们开发了一个节点管理的 agent ,这个 agent 需要读取当前部署环境的一些信息,可以通过底层平台的 API 实现。
但是,当部署到 AWS 、阿里云、青云等不同平台时, API 就无法统一了。这样,我们可以实现不同平台的适配服务来获取各自的信息,并且和 agent 通过 Pod 编排部署,在不改变 agent 逻辑的情况下,通过服务组合来适配于不同平台。
其实, Kubernetes 的一些新的功能需求,也会建议先通过 Pod 的编排来解决,而不是直接修改 Kubernetes 的代码,可见 Pod 还是用处多多的。
3.最后,我们一起看看如何在时速云平台上进行 Pod 的编排
1 )登录到时速云公有云平台,通过右侧的导航,选择“服务编排” -> “公有编排”,其中分为” Pod 编排“和“ Stack 编排”两类,点击“ Pod 编排”可以看到官方示例” ubuntu-mysql ”,这个模版会将 ubuntu 和 mysql 两个容器编排在一个 Pod 中。
2 )点击“部署”,可以预览 yaml 格式的编排文件:
其中关键是存储卷的配置,我们需要提前创建这个存储卷,并修改 yaml 中的 disk 属性,以匹配自己的存储卷。
如果我们需要修改存储卷名称,或者对其他镜像进行编排,可以复制这个模版,创建自己的 Pod 编排。注意:目前只有北京 2 区、杭州区支持存储卷功能,所以请在这两个区创建存储和部署 Pod 。
创建成功后,可以在容器服务的列表中看到一个“多容器服务”:
点击“查看所有服务地址”,可以看到对应的 mysql 和 ubuntu 的访问地址。
通过 ssh 登陆到 22 端口对应的服务地址,就可以直接访问到 mysql 的数据了。
并且存储卷中的数据会保存在独立的分布式存储系统中,保证数据的安全和高可用。
详细信息可以参考官方文档:
http://doc.tenxcloud.com/doc/v1/stack/index.html
所以,我们可以在很多实际的部署场景中充分发挥 Pod 的这些特性,将服务进行更细力度的拆分,通过编排增强服务模块,这样既可以减少重复的开发工作,降低服务的藕合度,也可以使我们的系统更轻量、更灵活。
Q&A
1.问:关于“提供 ssh 、 ftp 访问容器数据的能力”, pod 中包含一个业务 container 和一个 ssh 服务 container ,时速云的控制台可以进入到容器内部。那么 ssh 进入的 container 只是提供 ssh 服务的 container ,好像也没办法 ssh 到业务 container 。
答:业务应用 Container 和 ssh 服务 container 共享数据存储,可以通过 ssh 访问共享存储,这样也避免了修改“业务应用”中的不可变运行环境。(参考“不可变基础设施”)
2.问: pod 和 swarm 的最大区别是什么?我感觉差不多,是不是 Pod 更偏上层一些?
答:两者没有可比性。 Pod 只是一种容器的部署、管理方式,是 kubernetes 的最小部署和管理单元,是一组容器的集合; swarm 是容器编排工具,和 kubernetes 属于同一类。
3.问:一个 pod 最好包含几个容器?启动 pod 的配置文件里面能不能定义容器的大小?
答: Pod 里面多少个容器理论上没有特别的限制,目前我们一般是 2-3 个。 Pod 里面定义的容器,基本上就是对 Docker 容器的定义。 Pod 中支持 Docker 容器本身的绝大部分参数,比如 cpu 、 memory 、是否 privilege 、是否 root 等。 Pod 对 Docker 容器基本参数有所删减,但从更高的层面进行了扩展。具体可以查看 kubernetes 文档。
4.问: Pod 中定义容器时包括 pause 吗
答:每个 Pod 都会附带一个 pause 容器, pause 容器不执行实际的业务逻辑,只是对 pod 的网络、 IO 等进行控制。
5.问:时速云对 docker hub 上的镜像部署,也能提供 ssh 到容器内部的功能么?我的理解是,“打开 web 控制台”是 ssh 到容器里。
答:嗯, web 控制台和 ssh 并不一样。如果你使用 scp 、 sftp 传送文件,则需要容器内安装 sshd 服务。
6.问: Pod 没用过,不过用过 docker compose , 它们俩有什么区别?
答: compose 不支持紧耦合的容器组,也不支持容器共享存储。
7.问:能定义容器(磁盘)的大小吗?如果有的话,在哪儿修改?
答: docker daemon 的参数包含磁盘的定义,指定 devicemapper 的 option 来改变默认大小。