《深入剖析Kubernetes》总结四:Pod解析

Pod

相当于Linux操作系统的进程组

Pod只是一个逻辑概念,是一组共享了某些资源的容器,它的所有容器共享的是同一个 Network Namespace,并且可以声明共享同一个 Volume;
为了让Pod里的多个容器是对等关系而不是拓扑关系,Pod 的实现需要使用一个中间容器,叫作 Infra 容器,在这个 Pod 中,Infra 容器永远都是第一个被创建的容器,而其他用户定义的容器,则通过 Join Network Namespace 的方式,与 Infra 容器关联在一起(否则容器之间互相join的话,总得有一个先启动,就成了拓扑关系了)

对于同一个 Pod 里面的所有用户容器来说,它们的进出流量,可以认为都是通过 Infra 容器完成的

有了这个设计之后,共享 Volume 的实现很简单:把所有 Volume 的定义都设计在Pod 层级即可。

sidecar:容器设计模式
可以在一个 Pod 中,启动一个辅助容器,来完成一些独立于主进 程(主容器)之外的工作。
比如有一个tomcat和war,那么可以把 WAR 包和 Tomcat 分别做成镜像,然后把它们作为一个 Pod 里的两个容器“组合”在一起(tomcat为主容器,war为辅助容器,提供war包而已,类型为init Container,都会比 spec.containers 定义的用户容器先启动。并 且,Init Container 容器会按顺序逐一启动,而直到它们都启动并且退出了,用户容器才会启动),这样等Tomcat 容器启动时,它的 webapps 目录下就一定会存在 war 文件:这个文件正是 WAR 包容器启动时拷贝到 Volume 里面的,而 Volume 是被这两个容器共享的。

对比虚拟机:Pod可以理解为虚拟机本身,容器则是这个虚拟机里的进程

基本概念

  • Pod字段

调度、网络、存储、Linux Namespace以及安全相关的属性基本上是 Pod 级别的

NodeSelector:可以供用户将 Pod 与 Node 进行绑定

NodeName::该字段被赋值则意味着Kubernetes会认为这个 Pod 已经经过了调度,调度的结果就是赋值的节点名字,所以,这个字段一般由调度器负责设置;
用户也可以手动设置它,保证不被调度,一般是在测试或者调试的时候会用到

HostAliases:定义了 Pod 的 hosts 文件(比如 /etc/hosts)里的内容

扫描二维码关注公众号,回复: 11442355 查看本文章

Containers、Init Containers:容器

  • Container字段

Image:镜像

Command:启动命令

workingDir:容器的工作目录

Ports:容器要开发的端口

volumeMounts:容器要挂 载的 Volume

ImagePullPolicy:定义了镜像拉取的策略

Lifecycle:定义了 Container Lifecycle Hooks,也就是在容器状态发生变化时触发一系列“钩子”。

  • Pod生命周期

pod.status.phase,就是 Pod 的当前状态:

  1. Pending:Pod 的 YAML 文件已经提交给了 Kubernetes,API 对象已经被创建并保存在 Etcd 当中;但是,这个 Pod 里有些容器因为某种原因而不能被顺利创建,比如调度不成功
  2. Running:Pod 已经调度成功,跟一个具体的节点绑定;它包含的容器都已经创建成功,并且至少有一个正在运行中
  3. Succeeded:Pod 里的所有容器都正常运行完毕,并且已经退出了。这种情况在运行一次性任务时最为常见
  4. Failed:Pod 里至少有一个容器以不正常的状态(非 0 的返回码)退出;这个状态的出现,意味着得Debug这个容器的应用,比如查看 Pod 的 Events 和日志
  5. Unknown:这是一个异常状态,意味着 Pod 的状态不能持续地被 kubelet 汇报给 kubeapiserver,很有可能是主从节点(Master 和 Kubelet)间的通信出现了问题

Pod 对象的 Status 字段,还可以再细分出一组 Conditions;
这些细分状态的值包 括:PodScheduled、Ready、Initialized,以及 Unschedulable;
它们主要用于描述造成当前 Status 的具体原因是什么;
比如,Pod 当前的 Status 是 Pending,对应的 Condition 是 Unschedulable,这就意味着它的调度出现了问题;
Ready意味着 Pod 不仅已经正常启动(Running 状 态),而且已经可以对外提供服务了;

Running 和 Ready是有区别的, 有Pod(即容器)的状态是 Running,但是应用其实已经停止服务的例子:https://www.dazhuanlan.com/2019/12/16/5df6fd55a05d7/

1. 程序本身有 bug,本来应该返回 200,但因为代码问题,返回的是500;
2. 程序因为内存问题,已经僵死,但进程还在,但无响应;
3. Dockerfile 写的不规范,应用程序不是主进程,那么主进程出了什么问题都无法发现;
4. 程序出现死循环。

进阶

Projected Volume:投射数据卷,是一种特殊的 Volume,存在的意义不是为了存放容器里的数据,也不是用来进行容器和宿主机之间的数据交换,而是为容器提供预先定义好的数据;
所以,从容器的角度来看,这些 Volume 里的信息就是仿佛是被 Kubernetes“投射”(Project)进入容器当中的

支持的Projected Volume种类:Secret、ConfigMap、Downward API、ServiceAccountToken

  • Secret

作用:可以把 Pod 想要访问的加密数据,存放到 Etcd 中。然后就可以通过在 Pod 的容器里挂载 Volume 的方式,访问到这些 Secret 里保存的信息

场景:存放数据库的Credential信息

  • ConfigMap

与Secret类似,区别在于ConfigMap保存的是不需要加密的、 应用所需的配置信息

  • Downward API

作用:让 Pod 里的容器能够直接获取到这个 Pod API 对象本身 的信息。

注意:Downward API 能够获取到的信息,一定是 Pod 里的容器进程启动之前就能够确定下来的信息;
如果想要获取 Pod 容器运行后才会出现的信息,比如,容器进程的 PID,那就肯定不能使用 Downward API 了,而应该考虑在 Pod 里定义一个 sidecar 容器。

  • Service Account(特殊的Secret)

需求:现在有了一个 Pod我能不能在这个 Pod 里安装一个 Kubernetes 的 Client,这样就可以从容器里直接访问并且操作这个 Kubernetes 的 API ?

首先要解决 API Server 的授权问题

Service Account 对象的作用,就是 Kubernetes 系统内置的一种“服务账户”;
它是 Kubernetes 进行权限分配的对象,比如,Service Account A,可以只被允许对 Kubernetes API 进行 GET 操 作,而 Service Account B,则可以有 Kubernetes API 的所有操作的权限

Service Account 的授权信息和文件,实际上保存在它所绑定的一个特殊的 Secret 对象里 的,这个特殊的 Secret 对象,就叫作ServiceAccountToken,任何运行在 Kubernetes 集群上的 应用,都必须使用 ServiceAccountToken 里保存的授权信息,也就是 Token,才可以合法地访问 API Server

Kubernetes已经提供了一个默认的Service Account,Pod 创建完成后,容器里的应用就可以直接从默认 Service Account对应的ServiceAccountToken 的挂载目录里访问到授权信息和文件,只要直接加载这些授权文件,就可以访问并操作 Kubernetes API 了

容器健康检查和恢复机制

可以为 Pod 里的容器定义一个健康检查“探针”(Probe);
这样, kubelet 就会根据这个 Probe 的返回值决定这个容器的状态,而不是直接以容器进行是否运行(来自 Docke 返回的信息)作为依据;
这种机制,是生产环境中保证应用健康存活的重要手段。

pod.spec.restartPolicy字段则用来恢复,值有:

Always:在任何情况下,只要容器不在运行状态,就自动重启容器

OnFailure: 只在容器 异常时才自动重启容器

Never: 从来不重启容器。

其基本设计原理:

  1. 只要 Pod 的 restartPolicy 指定的策略允许重启异常的容器(比如:Always),那么这个 Pod 就会保持 Running 状态,并进行容器重启;
    否则,Pod 就会进入 Failed 状态 。
  2. 对于包含多个容器的 Pod,只有它里面所有的容器都进入异常状态后,Pod 才会进入 Failed 状态;
    在此之前,Pod 都是 Running 状态;
    此时,Pod 的 READY 字段会显示正常容器的个数

猜你喜欢

转载自blog.csdn.net/qq_41594698/article/details/107158428