【K8S系列】深入解析Pod对象(一)

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 【K8S系列】深入解析Pod对象(一)

1.问题引入

1.1 问题描述

通过上一篇的学习,我们知道Pod,不是容器,而是 Kubernetes 项目中的最小编排单位

将这个设计落实到 API 对象上,容器(Container)就成了 Pod 属性里的一个普通的字段。

那么,我们思考一个问题:

到底哪些属性属于 Pod 对象,而又有哪些属性属于 Container 呢?


2 问题解答

需要明确一个概念,也是上一篇文章提到的:Pod 扮演的是传统部署环境里“虚拟机”的角色。

这样的设计,是为了使用户从传统环境(虚拟机环境)向 Kubernetes(容器环境)的迁移,更加平滑。

所以,我们可以把 Pod 看成传统环境里的“机器”、把容器看作是运行在这个“机器”里的“用户程序”,那么很多关于 Pod 对象的设计是不是就容易理解了?


比如,凡是调度、网络、存储,以及安全相关的属性,基本上是 Pod 级别的。

这些属性的共同特征是,它们描述的是“机器”这个整体,而不是里面运行的“程序”。

比如:

  1. Pod 的网络定义:即-配置这个“机器”的网卡
  2. Pod 的存储定义:即-配置这个“机器”的磁盘
  3. Pod 的安全定义:即-配置这个“机器”的防火墙
  4. Pod 的资源调度:即-这台“机器”运行在哪个服务器之上

下面先介绍 Pod 中几个重要字段的含义和用法

2.1 pod 属性

2.1.1 NodeSelector

NodeSelector是一个供用户将 Pod 与 Node 进行绑定的字段,

用法如下所示:

apiVersion: v1
kind: Pod
……
spec:
 nodeSelector:
   disktype: ssd

这个配置,意味着这个 Pod 永远只能运行在携带了“disktype: ssd”标签(Label)的节点上;否则,它将调度失败。

2.1.2 HostAliases

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

apiVersion: v1
kind: Pod
...
spec:
  hostAliases:
  - ip: "10.1.2.4"
    hostnames:
    - "test1.remote"
    - "test2.remote"
...

在这个 Pod 的 YAML 文件中,设置了一组 IP 和 hostname 的数据。这样,这个 Pod 启动后,/etc/hosts 文件的内容将如下所示:

cat /etc/hosts
# Kubernetes-managed hosts file.
127.0.0.1 localhost
...
10.244.135.10 hostaliases-pod
10.1.2.4 test1.remote
10.1.2.4 test2.remote

其中,最下面两行记录,是通过 HostAliases 字段为 Pod 设置的

需要指出的是,在 Kubernetes 项目中,如果要设置 hosts 文件里的内容,一定要通过这种方法

否则,如果直接修改了 hosts 文件的话,在 Pod 被删除重建之后,kubelet 会自动覆盖掉被修改的内容。

2.1.3 shareProcessNamespace

凡是跟容器的 Linux Namespace 相关的属性,也一定是 Pod 级别的

因为,Pod 的设计,是要让它里面的容器尽可能多地共享 Linux Namespace,仅保留必要的隔离和限制能力。

这样,Pod 模拟出的效果,就跟虚拟机里程序间的关系非常类似了。

举个例子,在下面这个 Pod 的 YAML 文件中,定义了 shareProcessNamespace=true:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  shareProcessNamespace: true
  containers:
  - name: nginx
    image: nginx
  - name: shell
    image: busybox
    stdin: true
    tty: true

这就意味着这个 Pod 里的容器要共享 PID Namespace。

在这个 YAML 文件中,定义了两个容器:

  1. 一个是 nginx 容器,
  2. 一个是开启了 tty 和 stdin 的 shell 容器。

什么是tty 和 stdin,可以直接认为 tty 就是 Linux 给用户提供的一个常驻小程序,用于接收用户的标准输入,返回操作系统的标准输出。

当然,为了能够在 tty 中输入信息,还需要同时开启 stdin(标准输入流)。

这个 Pod 被创建后,就可以使用 shell 容器的 tty 跟这个容器进行交互了。我们一起实践一下:

1. 创建pod:

kubectl create -f nginx.yaml

2. 进入pod:使用 kubectl attach 命令,连接到 shell 容器的 tty 上

kubectl attach -it nginx -c shell

3. 查看进程:shell 容器里执行 ps 指令,查看所有正在运行的进程:

/ # ps ax
PID   USER     TIME  COMMAND
    1 root      0:00 /pause
    8 root      0:00 nginx: master process nginx -g daemon off;
   14 101       0:00 nginx: worker process
   15 root      0:00 sh
   21 root      0:00 ps ax

可以看到,在这个容器里,不仅看到它本身的 ps ax 指令,还可以看到 nginx 容器的进程,以及 Infra 容器的 /pause 进程。

这就意味着,整个 Pod 里的每个容器的进程,对于所有容器来说都是可见的:它们共享了同一个 PID Namespace

2.1.4 NodeName

NodeName:当Pod 的这个字段被赋值,Kubernetes 项目就会被认为这个 Pod 已经经过了调度,调度的结果就是赋值的节点名字。

所以,这个字段一般由调度器负责设置,但用户也可以设置它来“骗过”调度器,当然这个做法一般是在测试或者调试的时候才会用到。

2.1.5 其他pod属性

凡是 Pod 中的容器要共享宿主机的 Namespace,也一定是 Pod 级别的定义

比如:

  • Network
  • IPC
  • PID
  • Namespace
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  hostNetwork: true
  hostIPC: true
  hostPID: true
  containers:
  - name: nginx
    image: nginx
  - name: shell
    image: busybox
    stdin: true
    tty: true

在这个 Pod 中,定义了共享宿主机的 Network、IPC 和 PID Namespace

这就意味着,这个 Pod 里的所有容器,会直接使用宿主机的网络、直接与宿主机进行 IPC 通信、看到宿主机里正在运行的所有进程

2.2 容器属性

Kubernetes 项目中对 Container 的定义,和 Docker 相比并没有什么太大区别。

  1. Image(镜像)
  2. Command(启动命令)
  3. workingDir(容器的工作目录)
  4. Ports(容器要开发的端口)
  5. volumeMounts(容器要挂载的 Volume)

这些都是构成 Kubernetes 项目中 Container 的主要字段。不过除了这些,还有这么几个属性值得我们额外关注。

2.2.1 ImagePullPolicy

ImagePullPolicy 字段。它定义了镜像拉取的策略。注意事项:

  1. Always:即每次创建 Pod 都重新拉取一次镜像
  2. Never / IfNotPresent:则意味着 Pod 永远不会主动拉取这个镜像,或者只在宿主机上不存在这个镜像时才拉取。
  3. ImagePullPolicy 的值默认是Always
  4. 当容器的镜像是类似于 nginx 或者 nginx:latest 这样的名字时,ImagePullPolicy 也会被认为 Always。


2.2.2 Lifecycle

Lifecycle 字段。它定义的是 Container Lifecycle Hooks。

顾名思义,Container Lifecycle Hooks 的作用,是在容器状态发生变化时触发一系列“钩子”。我们来看这样一个例子:

apiVersion: v1
kind: Pod
metadata:
  name: lifecycle-demo
spec:
  containers:
  - name: lifecycle-demo-container
    image: nginx
    lifecycle:
      postStart:
        exec:
          command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"]
      preStop:
        exec:
          command: ["/usr/sbin/nginx","-s","quit"]

postStart :指在容器启动后,立刻执行一个指定的操作。

另外,postStart 定义的操作,虽然是在 Docker 容器 ENTRYPOINT 执行之后,但它并不严格保证顺序。也就是说,在 postStart 启动时,ENTRYPOINT 有可能还没有结束

当然,如果 postStart 执行超时或者错误,Kubernetes 会在该 Pod 的 Events 中报出该容器启动失败的错误信息,导致 Pod 也处于失败的状态。

preStop: 发生的时机,则是容器被杀死之前(比如,收到了 SIGKILL 信号)

而需要明确的是,preStop 操作的执行,是同步的。

所以,它会阻塞当前的容器杀死流程,直到这个 Hook 定义操作完成之后,才允许容器被杀死,这跟 postStart 不一样。


所以,在上面例子中,它在容器成功启动之后,在 /usr/share/message 里写入了一句“Hello from the postStart handler”(即 postStart 定义的操作)。

而在这个容器被删除之前,则先调用了 nginx 的退出指令(即 preStop 定义的操作),从而实现了容器的“优雅退出”。


3 总结

在这篇文章中,详细讲解了 Pod API 对象,介绍了 Pod 的核心使用方法,并分析了 Pod 和 Container 在字段上的异同。

希望这些讲解能够帮你更好地理解和记忆 Pod YAML 中的核心字段,以及这些字段的准确含义。

最后,Pod API 对象是整个 Kubernetes 体系中最核心的一个概念,后面讲解各种控制器时都会反复提到。

4. 投票


相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
2月前
|
运维 Kubernetes 监控
Kubernetes详解(十九)——Kubernetes Pod控制器
Kubernetes详解(十九)——Kubernetes Pod控制器
51 3
|
14天前
|
Kubernetes Java 应用服务中间件
Kubernetes 上搭建一个 Nginx 的 Pod,并确保传入的 API 请求被均匀地分发到两个 Java 业务 Pod 上
Kubernetes 上搭建一个 Nginx 的 Pod,并确保传入的 API 请求被均匀地分发到两个 Java 业务 Pod 上
10 0
|
18天前
|
Kubernetes Shell API
技术笔记:K8s中大量Pod是Evicted状态,这是咋回事?
技术笔记:K8s中大量Pod是Evicted状态,这是咋回事?
45 0
|
2月前
|
域名解析 Kubernetes 网络协议
【域名解析DNS专栏】云原生环境下的DNS服务:Kubernetes中的DNS解析
【5月更文挑战第29天】本文探讨了Kubernetes中的DNS解析机制,解释了DNS如何将服务名转换为网络地址,促进集群内服务通信。Kubernetes使用kube-dns或CoreDNS作为内置DNS服务器,每个Service自动分配Cluster IP和DNS条目。通过示例展示了创建Service和使用DNS访问的流程,并提出了优化DNS解析的策略,包括使用高性能DNS解析器、启用DNS缓存及监控日志,以实现更高效、可靠的DNS服务。
|
27天前
|
Kubernetes API 调度
Pod无法调度到可用的节点上(K8s)
完成k8s单节点部署后,创建了一个pod进行测试,后续该pod出现以下报错: Warning FailedScheduling 3h7m (x3 over 3h18m) default-scheduler 0/1 nodes are available: 1 node(s) had untolerated taint {node-role.kubernetes.io/control-plane: }. preemption: 0/1 nodes are available: 1 Preemption is not helpful for scheduling..
83 0
|
1月前
|
Kubernetes 应用服务中间件 API
Kubernetes关键组件解析
【6月更文挑战第12天】Kubernetes是一个用于管理容器集群的平台,由Master节点负责集群控制,而Node节点执行管理命令。
|
2月前
|
Kubernetes 算法 调度
k8s群集调度之 pod亲和 node亲和 标签指定
k8s群集调度之 pod亲和 node亲和 标签指定
|
26天前
|
XML Java 数据格式
深度解析 Spring 源码:从 BeanDefinition 源码探索 Bean 的本质
深度解析 Spring 源码:从 BeanDefinition 源码探索 Bean 的本质
28 3
|
11天前
|
存储 安全 Java
深度长文解析SpringWebFlux响应式框架15个核心组件源码
以上是Spring WebFlux 框架核心组件的全部介绍了,希望可以帮助你全面深入的理解 WebFlux的原理,关注【威哥爱编程】,主页里可查看V哥每天更新的原创技术内容,让我们一起成长。
|
12天前
|
关系型数据库 分布式数据库 数据库
PolarDB-X源码解析:揭秘分布式事务处理
【7月更文挑战第3天】**PolarDB-X源码解析:揭秘分布式事务处理** PolarDB-X,应对大规模分布式事务挑战,基于2PC协议确保ACID特性。通过预提交和提交阶段保证原子性与一致性,使用一致性快照隔离和乐观锁减少冲突,结合故障恢复机制确保高可用。源码中的事务管理逻辑展现了优化的分布式事务处理流程,为开发者提供了洞察分布式数据库核心技术的窗口。随着开源社区的发展,更多创新实践将促进数据库技术进步。
18 3

推荐镜像

更多