本文笔记记录对 Pod 的理解。为了更好的部署运行应用,Pod 是如何设计的,Pod为什么这么设计,如何更好的使用Pod,以及一些API核心字段的使用实例。
一、Pod 的设计思想
Q:为什么要有 Pod ?
为了更好地在 Kubernetes 中部署运行应用
Q:为什么 Pod 能更好的运行应用 ?
- 首先看应用:
一个运行在虚拟机中的应用通常是一组进程,而不是一个进程。同时进程之间可能有密切的“协作关系”,使得他们必须部署在同一台机器上。这里就有2个重要的点,即应用是一组进程(或者包含很多组件),同时进程间存在密切关系。 - 然后看 Pod :
Pod 其实是 一组共享了某些资源的容器。这里也就有2点,“一组容器” 和 “共享了某些资源”。
(1)为什么是“一组容器”
由于容器受限于“单进程模型”(虽然不是只能运行一个进程,但却只能管理一个进程),所以 Kubernetes 中需要一种“进程组”的映射,也就是 Pod,来管理一组相互协作的容器。
(2)为什么“共享了某些资源”
多个密切合作的进程/应用之所以需要部署在一台机器上,是因为他们需要访问共同的资源(比如网络、存储、安全等操作系统层面的资源)。所以 Pod 实际上扮演了传统基础设施里“虚拟机”的角色,让 Pod 里的所有容器共享同一个Network Namespace,并且可以声明共享同一个 Volume 等。
二、Pod 使用的思考方式
-
“应用”从传统环境到容器环境
一个运行在虚拟机里的应用,哪怕再简单,也是被管理在 systemd 或者 supervisord 之下的一组进程,而不是一个进程。这跟本地物理机上应用的运行方式其实是一样的。这也是为什么,从物理机到虚拟机之间的应用迁移,往往并不困难。
可是对于容器来说,一个容器永远只能管理一个进程。更确切地说,一个容器,就是一个进程。这是容器技术的“天性”,不可能被修改。所以,将一个原本运行在虚拟机里的应用,“无缝迁移”到容器中的想法,实际上跟容器的本质是相悖的。 -
“应用”容器化地描述为一个 Pod 里的多个容器
Pod 组织“超亲密关系”容器的设计思想,实际上就是希望,当用户想在一个容器里跑多个功能并不相关的应用时,应该优先考虑它们是不是更应该被描述成一个 Pod 里的多个容器。 -
Pod 扮演着“机器/虚拟机”角色
Pod,实际上是在扮演传统基础设施里“机器/虚拟机”的角色;而容器,则是这个机器里运行的用户程序。所以,当需要把一个运行在虚拟机里的应用迁移到 Docker 容器中时,一定要仔细分析到底有哪些进程(组件)运行在这个虚拟机里。
同时把虚拟机想象成 Pod,所以一些描述”机器“的属性配置就在 Pod 级别进行设置,而不是 Container。比如,配置这个“机器”的网卡(即:Pod 的网络定义),配置这个“机器”的磁盘(即:Pod 的存储定义),配置这个“机器”的防火墙(即:Pod 的安全定义)。更不用说,这台“机器”运行在哪个服务器之上(即:Pod 的调度)。
三、Pod API 的使用
首先要理解:Pod 既然是 Kubernetes 中实际是一种管理应用的”编排对象“,使用设计会落实到 Pod 的 API 设计上,使用起来也自然是 YAML 文件的形式。所以在了解了 Pod 使用的思考方式之后,想要实际使用 Pod 就需要掌握 Pod YAML 字段的含义和用法了。另外,Kubernetes 体系中各种控制器也会利用 API 进行 Pod 管理。
Pod API 核心字段:
(Pod API 对象主要是Metadata、Spec 和 Status 三部分。 可以参考 Kubernetes types.go源码 中的 type Pod struct)
- Pod 与 Node 相关:NodeSelector、NodeName
- Pod 内的容器共享 Linux Namespace相关:shareProcessNamespace、hostNetwork、hostIPC、hostPID
- 最重要的字段 cantainers 配置多个容器:Image(镜像)、Command(启动命令)、workingDir(容器的工作目录)、Ports(容器要开发的端口),以及 volumeMounts(容器要挂载的 Volume)都是构成 Kubernetes 项目中 Container 的主要字段,还有ImagePullPolicy(镜像拉取策略)、Lifecycle(定义容器状态发生变化时触发一系列“钩子”,postStart、preStop)、livenessProbe(探针,可以定时执行指定命令进行健康检查然后反馈)
- Pod 的 hosts 文件配置 HostAliases
- Pod 的数据持久化 Volumes:普通的有 emptyDir 或者 hostPath 类型,还有”投射数据卷“ projected 类型(一共四种,secret、configMap、downwardAPI,还有一个特殊的secret,ServiceAccountToken,用来保存授权信息和文件)
- Pod 的恢复机制:restartPolicy(Pod 中容器异常时的恢复策略)
另外,Pod 预设置:
PodPreset 对象,这其中定义的内容会在 Pod 对象被创建之前追加在这个 Pod YAML 字段之上。
参考:
1、《深入剖析Kubernetes | 极客时间》张磊,容器编排和Kubernetes作业管理 前三讲
2 、https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/api/core/v1/types.go