《Pod 详解》系列,共包含以下几篇文章:
- Pod 的概念、使用方法、容器类型
- Pod 的生命周期(一):Pod 阶段与状况、容器的状态与重启策略
- Pod 的生命周期(二):Pod 的健康检查之容器探针
- Pod 状态速查表
- Pod 的调度策略
- Pod 资源调度之亲和性调度
- Pod 驱逐
- Pod 的配置管理(一):ConfigMap
- Pod 的配置管理(二):Secret
😊 如果您觉得这篇文章有用 ✔️ 的话,请给博主一个一键三连 🚀🚀🚀 吧 (点赞 🧡、关注 💛、收藏 💚)!!!您的支持 💖💖💖 将激励 🔥 博主输出更多优质内容!!!
Pod 的概念、使用方法、容器类型
Kubernetes 通过一个抽象的逻辑单元 Pod 将应用的容器组合在一起,从而使得应用更容易被发现和管理。Pod 是 Kubernetes 的核心。
1.什么是 Pod
Pod 是 Kubernetes 中的一个 逻辑单位,它代表集群中正在运行的一个进程,是 Kubernetes 集群中的一个应用实例,由一个或者多个容器组成。在 Pod 中还可以包含数据的持久化存储、网络配置等资源。Pod 支持多种容器的执行环境,而 Docker 则是 Pod 最常见的 执行环境。Pod 也支持用其他容器引擎作为执行环境。
🚀 Pod 是 Kubernetes 项目的原子调度单位,关于 Pod 最重要的一个事实是:它只是一个逻辑概念。也就是说,Kubernetes 真正处理的,还是宿主机操作系统上 Linux 容器的 Namespace 和 Cgroups,而并不存在一个所谓的 Pod 的边界或者隔离环境。
在 Kubernetes 中,主要有两种使用 Pod 的方式。
- 单容器的 Pod:最常见的使用 Pod 的方式,即在 Pod 中只运行一个容器,Kubernetes 通过 Pod 来管理这个容器。
- 多容器的 Pod:当应用需要多个容器一起协同工作时,Pod 中可以运行多个容器,从而满足应用的要求。Kubernetes 的调度器会保证这些容器都运行在同一台物理主机或虚拟主机上,从而达到容器之间的资源共享。
🚀 由于这些容器运作在同一个宿主机上,因此它们可以通过
localhost
互相访问。不过,除非是具有强耦合关系的容器,否则不推荐使用这种方式。
Kubernetes 使用 Pod 来管理容器具有以下优点:
- Pod 作为最小的 逻辑部署单元,简化了应用部署的难度,同时也极大地方便了应用的管理。
- Pod 作为独立运行的 服务单元,可以方便地进行 部署、水平扩展 / 收缩、调度管理 与 资源分配。
- Pod 中的容器共享命名空间和网络地址,方便进行统一的资源管理与资源分配。
2.Pod 的基本使用方法
通过使用 YAML 文件可以描述一个 Pod。
Pod 的配置信息包含以下几部分。其中最重要的部分是 metadata
和 spec
。
apiVersion
:创建该对象所使用的 Kubernetes APl 的版本。kind
:指定对象的类型,即 Pod。metadata
:设置 Pod 的元信息,包括对象的名称、ID 及命名空间等。spec
:设置 Pod 的规约信息。status
:设置 Pod 运行时的状态。
下面是 Pod 的一个示例文件 firstpod.yaml
:
apiVersion: v1
kind: Pod
metadata:
name: first-pod
labels:
app: demo
type: bash
spec:
replicas: 2
containers:
- name: busybox-container
image: busybox
command: ['sh', '-c', 'echo Hello Kubernetes Pod! && sleep 1000']
- 使用
firstpod.yaml
方式创建 Pod
kubectl create -f firstpod.yaml
- 查看正在运行的 Pod 信息
kubectl get pod first-pod -o yaml
- 查看 Pod 的标准输出日志
kubectl logs first-pod
输出日志如下:
Hello Kubernetes Pod!
如果在 Pod 中有多个容器,则在查看某个容器的日志时需要指定容器的名称,例如:kubectl logs pod-name -c container-name
。
- 显示 Pod 的标签
kubectl get pods --show-labels
标签 Label 是 Kubernetes 管理 Pod 的重要属性,我们可以在 YAML 文件的 metadata 配置参数中指定,也可以通过命令行指定。
- 根据标签查询 Pod
kubectl get pods -l app=demo --show-labels
- 通过命令给 Pod 增加标签
kubectl label pod first-pod side=frontend
- 通过命令行修改 Pod 的标签
kubectl label pod first-pod side=unknown --overwrite
- 也可以将标签显示为列
kubectl get pods -L app,type,side
3.Pod 中的容器
Pod 由一个或多个容器组成。这里的容器通常指运行应用的业务容器。在 Pod 中,除业务容器外,还有 基础容器、初始化容器 和 临时容器。
3.1 基础容器
基础容器(Infrastructure Container)负责维护整个 Pod 的 网络空间。这种类型的容器对用户是 透明的,用户不能操作这种容器。
在 node 节点上,通过 docker ps
命令可以查看基础容器。
基础容器将使用 pause
镜像来创建和维护 Pod 的网络环境。
3.2 初始化容器
初始化容器 晚于基础容器运行,但先于业务容器运行。如果 Pod 的初始化容器运行失败,则默认情况下 Kubernetes 会不断尝试重启 Pod,直到初始化容器运行成功。如果将 Pod 的配置参数 restartPolicy
设置为 Never
,则 Kubernetes 不会执行重启动作。
如果要将 Pod 中的容器指定为初始化容器,则需要在 spec
中添加 initContainers
字段。一个 Pod 可以指定多个初始化容器,它们会按顺序逐个运行:一个初始化容器运行成功,下一个才能够运行。当所有的初始化容器运行完成后,Kubernetes 才会执行业务容器从而运行应用。
下面是一个初始化容器的示例。
- 创建
initcontainer.yaml
文件,并在其中输入以下内容。
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox:1.28
command: ['sh', '-c', 'echo The app running! && sleep 5']
initContainers:
- name: init-myservice
image: busybox:1.28
command: ['sh', '-c', 'echo The init-myservice running! && sleep 5']
- name: init-mydb
image: busybox:1.28
command: ['sh', '-c', 'echo The init-mydb running! && sleep 5']
- 执行以下语句创建 Pod
kubectl apply -f initcontainer.yaml
- 在 Pod 创建成功后,使用
describe
命令查看输出信息
kubectl describe -f initcontainer.yaml
Kubernetes 会先启动了两个初始化容器(init-myservice
和 init-mydb
),之后启动了业务容器(myapp-container
)。
初始化容器与业务容器是分离的,具有以下优势:
- 🚀 在初始化容器中可以提前安装在业务容器中要使用的工具,或者运行一些初始化的脚本。
- 🚀 将应用依赖的工具和脚本分离到初始化容器中,可以避免这些工具降低应用镜像的安全性。
- 🚀 开发人员可以进行组件镜像的独立创建和部署,而不需要将所有的组件构建成一个大的应用镜像。
- 🚀 初始化容器可以独立访问 Kubernetes 中的一些敏感信息,如 Secret。
- 🚀 由于初始化容器必须在业务容器之前执行完成,因此,可以利用初始化容器来阻塞或延迟业务容器的启动,从而进行先决条件的检查。
3.3 临时容器
临时容器 是一种特殊的容器。它在现有的 Pod 中临时运行,以完成用户发起的操作(例如 故障排查 和 性能诊断 等)。由于临时容器没有端口要配置,且资源分配是不可变的,所以它不适合用来构建应用。
临时容器的最大用途是 调试其他的容器。因为,当 Pod 中的容器异常退出,或者容器镜像不包含调试工具时(例如没有 shell
),会导致 kubectl exec
命令无法使用。这时临时容器对于交式故障排查就很有用了。
下面是 Kubernetes 官方提供的一个临时容器的示例。
- 使用
k8s.gcr.io/pause:3.1
镜像创建一个 Pod。
kubectl run ephemeral-demo --image=k8s.gcr.io/pause:3.1 --restart=Never
🚀 这里使用
k8s.gcr.io/pause:3.1
镜像是因为它不包含任何调试程序。
- 使用
kubectl exec
命令创建 shell 进入容器。
kubectl exec -it ephemeral-demo -- sh
由于该镜像不包含任何调试程序,因此会出现以下错误信息:
OCI runtime exec failed: exec failed: container_linux.go:346: starting container process caused "exec: \"sh\": executable file not found in $PATH": unknown
- 使用
kubectl debug
命令为ephemeral-demo
容器添加一个临时容器,以达到调试的目的。
kubectl debug -it ephemeral-demo --image=busybox --target=ephemeral-demo
这里使用 busybox
的镜像来创建临时容器,Kubernetes 将自动启动临时容器的控制台。在临时容器启动后,会输出如下信息:
Defaulting debug container name to debugger-8xzrl.
If you don't see a command prompt, try pressing enter.
/#
3.4 业务容器
业务容器(Containers)是实际运行应用的容器,如第 2 节中创建的 busybox-container
容器。