《深入剖析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)里的内容

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 字段会显示正常容器的个数
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Kubernetes 原理剖析与实战应用】 开篇 | 如何深入掌握 Kubernetes? 云原生基石:初识 Kubernetes 01 | 前世今生:Kubernetes 是如何火起来的? 02 | 高屋建瓴:Kubernetes 的架构为什么是这样的? 03 | 集群搭建:手把手教你玩转 Kubernetes 集群搭建 04 | 核心定义:Kubernetes 是如何搞定“不可变基础设施”的? 「关注公众号【云世】,免费获取全系列课程内容」 05 | K8s Pod:最小调度单元的使用进阶及实践 Kubernetes 进阶:部署高可用的业务 06 | 无状态应用:剖析 Kubernetes 业务副本及水平扩展底层原理 07 | 有状态应用:Kubernetes 如何通过 StatefulSet 支持有状态应用? 08 | 配置管理:Kubernetes 管理业务配置方式有哪些? 09 | 存储类型:如何挑选合适的存储插件? 10 | 存储管理:怎样对业务数据进行持久化存储? 11 | K8s Service:轻松搞定服务发现和负载均衡 12 | Helm Charts:如何在生产环境中释放部署生产力? 守护神:业务的日志与监控 「关注公众号【云世】,免费获取全系列课程内容」 13 | 服务守护进程:如何在 Kubernetes 中运行 DaemonSet 守护进程? 14 | 日志采集:如何在 Kubernetes 中做日志收集与管理? 15 | Prometheus:Kubernetes 怎样实现自动化服务监控告警? 16 | 迎战流量峰值:Kubernetes 怎样控制业务的资源水位? 17 | 案例实战:教你快速搭建 Kubernetes 监控平台 安全无忧:集群的安全性与稳定性 18 | 权限分析:Kubernetes 集群权限管理那些事儿 19 | 资源限制:如何保障你的 Kubernetes 集群资源不会被打爆 20 | 资源优化:Kubernetes 中有 GC(垃圾回收)吗? 21 | 优先级调度:你必须掌握的 Pod 抢占式资源调度 22 | 安全机制:Kubernetes 如何保障集群安全? 23 | 最后的防线:怎样对 Kubernetes 集群进行灾备和恢复? 「关注公众号【云世】,免费获取全系列课程内容」 加餐:问题答疑和优秀留言展示 知其所以然:底层核心原理及可扩展性 24 | 调度引擎:Kubernetes 如何高效调度 Pod? 25 | 稳定基石:带你剖析容器运行时以及 CRI 原理 26 | 网络插件:Kubernetes 搞定网络原来可以如此简单? 27 | K8s CRD:如何根据需求自定义你的 API? 28 | 面向 K8s 编程:如何通过 Operator 扩展 Kubernetes API? 特别放送 「关注公众号【云世】,免费获取全系列课程内容」 29 | Kubernetes 中也有定时任务吗? 30 | Kubectl 命令行工具使用秘笈 结束语 结束语 | Cloud Native is Eating the World:时代在召唤云原生 「关注公众号【云世】,免费获取全系列课程内容」
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值