0%

k8s(三)——资源清单

pod详解

资源清单

K8S 中所有的内容都抽象为了资源,资源实例化之后就叫做对象。

在 Kubernetes 系统中,Kubernetes 对象是持久化的实体,Kubernetes 使用这些实体去表示整个集群的状态。特别地,它们描述了如下信息:

  • 哪些容器化应用在运行,以及在哪个 Node 上
  • 可以被应用使用的资源
  • 关于应用运行时表现的策略,比如重启策略、升级策略,以及容错策略

Kubernetes 对象是 “目标性记录” —— 一旦创建对象,Kubernetes 系统将持续工作以确保对象存在。通过创建对象,本质上是在告知 Kubernetes 系统,所需要的集群工作负载看起来是什么样子的,这就是 Kubernetes 集群的期望状态。

分类

  • 工作负载型资源

    • Pod、ReplicaSet、Deployment、StatefulSet、DaemonSet、Job、CronJob
  • 服务发现及负载均衡型资源

    • Service、Ingress
  • 配置与存储型资源

    • Volume、CSI
  • 特殊类型的存储卷

    • ConfigMap、Secret、DownwardAPI
  • 集群级别资源

    • Namespace、Node、Role、ClusterRole、RoleBinding、ClusterRoleBinding
  • 元数据型资源

    • HPA、PodTemplate、LimitRange

常用字段的解释

下面就需要我们熟悉,如何使用 yaml 文件来描述 Kubernetes 对象。

当创建 Kubernetes 对象时,必须提供对象的规约,用来描述该对象的期望状态,以及关于对象的一些基本信息,例如名称。当使用 Kubernetes API 创建对象时,或者直接创建或者基于 kubectl,API 请求必须在请求体中包含 JSON 格式的信息。大多数情况下,需要在 .yaml 文件中为 kubectl 提供这些信息。kubectl 在发起 API 请求时,将这些信息转换成 JSON 格式。

大体的 .yaml 文件格式如下所示,其中包含的都是配置 yaml 文件启动服务必须或者建议配置的字段。

1
2
3
4
5
6
7
8
9
apiVersion: group/api-version # 版本信息
kind: # 资源类别
metadata: # 资源元数据
name: # 元数据对应的名称
namespace: # 元数据所属的命名空间
lables: # 对资源打上便签供后续使用
annotations: # 主要目的是方便用户阅读查找
spec: # 定义期望状态
status: # 设置当前状态

这里有一个 .yaml 示例文件,展示了 Kubernetes Deployment 的必需字段和对象规约。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: app-test
lables:
apps: nginx
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80

使用类似于上面的 .yaml 文件来创建 Deployment,一种方式是使用 kubectl 命令行接口中的 kubectl apply 命令, 将 .yaml 文件作为参数。

1
2
# 创建Deployment服务
kubectl apply -f ./deployment.yaml --record

Pod 的相关知识

什么是 Pod

Pod 封装了应用程序容器或者在某些情况下封装多个容器、存储资源、唯一网络 IP 以及控制容器应该如何运行的选项。

nginx_pod

在最内层是我们的服务 nginx,运行在 container 容器当中, container (容器) 的本质是进程,而 pod 是管理这一组进程的资源。

Pod 是 Kubernetes 应用程序的基本执行单元,即它是 Kubernetes 对象模型中创建或部署的最小和最简单的单元。Pod 封装了应用程序容器或者在某些情况下封装多个容器、存储资源、唯一网络 IP 以及控制容器应该如何运行的选项。其中,Docker 是 Kubernetes Pod 中最常用的容器运行时,但 Pod 也能支持其他的容器运行时。Pod 的两个主要用途如下所示:

  • 运行单个容器的 Pod —— 支持多容器的微服务实例

    • 每个 Pod 一个容器的模型是最常见的使用情况,在这种情况下,可以将 Pod 看作单个容器的包装器,并且 Kubernetes 直接管理 Pod,而不是容器。
  • 运行多个协同工作的容器的 Pod —— 基于多容器微服务模型的分布式应用模型

    • Pod 可能封装由多个紧密耦合且需要共享资源的共处容器组成的应用程序,Pod 将这些容器和存储资源打包为一个可管理的实体。
  • 分布式系统工具包:容器组合的模式 —— 有状态服务水平扩展

    • 即将多个服务同时封装到同一个 Pod 中,对外提供服务,而不再需要用户手动安装其他服务或者工具,真正做到即时即用的便捷效果。
  • 容器设计模式

    • 云原生应用运行的环境都是复杂的分布式环境,在这种情况下,一些有用的设计模式可以起到四两拨千斤的作用。目前 K8s 社区推出的容器设计模式主要分为三大类:单容器管理模式、单节点多容器模式、多节点多容器模式。

Pod 中的容器被自动的安排到集群中的同一物理或虚拟机上,并可以一起进行调度。容器可以共享资源和依赖、彼此通信、协调何时以及何种方式终止它们。Pod 提供了两种共享资源:网络 和 存储。

网络

每个 Pod 分配一个唯一的 IP 地址。Pod 中的每个容器共享网络命名空间,包括 IP 地址和网络端口。Pod 内的容器 可以使用 localhost 互相通信。当 Pod 中的容器与 Pod 之外 的实体通信时,它们必须协调如何使用共享的网络资源,例如端口。

存储

一个 Pod 可以指定一组共享存储卷。Pod 中的所有容器都可以访问共享卷,允许这些容器共享数据。卷还允许 Pod 中的持久数据保留下来,以防其中的容器需要重新启动。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 通过定义清单文件创建Pod
apiVersion: v1
kind: Pod
metadata:
name: pod-demo
namespace: default
labels:
app: myapp
spec:
containers:
- name: myapp-1
image: hub.escapelife.site/library/nginx-test:v1
- name: busybox-1
image: busybox:latest
command:
- "/bin/sh"
- "-c"
- "sleep 3600"

Pod 的使用

我们很少会直接在 kubernetes 中创建单个 Pod。因为 Pod 的生命周期是短暂的,用后即焚的实体。当 Pod 被创建后,都会被 Kubernetes 调度到集群的 Node 上。直到 Pod 的进程终止、被删掉、因为缺少资源而被驱逐、或者 Node 故障之前这个 Pod 都会一直保持在那个 Node 上。

我们需要知道 Pod 本身是不会自愈修复的。如果 Pod 运行的 Node 故障或者是调度器本身故障,这个 Pod 就会被删除。同样的,如果 Pod 所在 Node 因为缺少资源或者 Pod 处于维护状态,那么 Pod 也就会被自动驱逐掉。Kubernetes 使用更高级的称为 Controller 的抽象层,来管理 Pod 实例。虽然可以直接使用 Pod,但是在 Kubernetes 中通常是使用 Controller 来管理 Pod 的。Controller 可以创建和管理多个 Pod,提供副本管理、滚动升级和集群级别的自愈能力。

需要注意的是,重启 Pod 中的容器跟重启 Pod 不是一回事。Pod 只提供容器的运行环境并保持容器的运行状态,重启容器不会造成 Pod 重启。

Kubernetes 使用了一个更高级的称为 控制器 的抽象,由它处理相对可丢弃的 Pod 实例的管理工作。因此,虽然可以直接使用 Pod,但在 Kubernetes 中,更为常见的是使用控制器管理 Pod。

  • Deployment
  • StatefulSet
  • DaemonSet
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80

Pod 的生命周期

Pod 的生命周期才是 Kubernetest 资源清单中的重中之重!

Kubernetes 中的基本组件 kube-controller-manager 就是用来控制 Pod 的状态和生命周期。

了解 Init 容器

Init 容器与普通的容器非常像,但是有两点不同之处。与普通容器的不同之处在于,Init 容器支持应用容器的全部字段和特性,包括资源限制、数据卷和安全设置,但是不支持 Readiness Probe,因为它们必须在 Pod 就绪之前运行完成。

  • 其一就是,Init 容器总是运行到完成为止。
  • 其二就是,每个 Init 容器都必须在下一个 Init 容器启动之前成功完成才会继续运行。

如果 Pod 内设置的 Init 容器运行失败了,那么 Kubernetes 就会不断地重启该 Pod,直到 Init 容器成功为止。

如果为一个 Pod 指定了多个 Init 容器,这些容器会按顺序逐个运行。每个 Init 容器必须运行成功,下一个才能够运行。当所有的 Init 容器运行完成时,Kubernetes 才会为 Pod 初始化应用容器并像平常一样运行。