第一部分:Pod 是什么?------ 理解其基本概念
1. Pod基础概念
Pod 是 Kubernetes 中的最小部署单元,它代表集群中的一个运行进程。一个 Pod 可以包含一个或多个紧密耦合的容器,这些容器共享网络和存储资源。在 Kubernetes 中,Pod 是管理容器的基础结构,其他如 Deployment、StatefulSet、DaemonSet 等控制器对象都围绕 Pod 进行扩展。
2. Kubrenetes集群中Pod有如下两种使用方式
单容器 Pod: 最常见的用法,一个 Pod 只包含一个容器。这种情况下,Pod 就相当于容器的封装,Kubernetes 管理的是 Pod,而不是容器。
多容器 Pod : 一个 Pod 可以包含多个容器,这些容器通常有共同的资源需求,如共享网络和存储,彼此间可以通过 localhost 进行通信。
3. Pause 容器(基础容器)
在每个 Pod 中,都会有一个特殊的容器被称为 Pause 容器,它的主要职责是提供 Pod 的 Linux 命名空间基础。它使得 Pod 内的所有容器共享网络和存储资源。Pause 容器运行时,它会创建一个 Linux 命名空间,其他容器将共享该命名空间来进行网络通信和存储操作。
第二部分:Pod 如何工作?------ 核心机制详解
4. Pod 中的共享资源
-
网络共享 : 每个 Pod 分配一个唯一的 IP 地址,Pod 内的所有容器共享该 IP 和端口。它们能够通过
localhost进行通信。Pod中的容器与外界通信时,必须分配共享网络资源(例如使用宿主机的端口映射)① 每个pod 分配一个独特IP地址 ② pod 内部所有容器共享这个IP和端口 ,能通过 localhost直接通信 ③ 与外界 通信时, 必须使用宿主机的端口映射
-
存储共享: Pod 可以指定多个共享的 Volume,这些 Volume 可以被 Pod 内的所有容器访问,确保容器重启后数据不会丢失。
① Pod可以指定多个共享的Volume,所有容器都可以访问 ② Volume可以用来持久化存储 ,确保容器重启后数据不会丢失
5.Pod 的使用场景
-
单一进程应用:最常见的用法,一个 Pod 用于运行一个容器。
-
多进程协作:多个容器在同一个 Pod 内共享网络和存储资源,适用于紧密耦合的服务。
6. Pod 的类型
-
自主式 Pod: 这种 Pod 不具备自我修复的能力。如果它所在的节点故障,Pod 会被删除,且不会自动恢复。
-
控制器管理的 Pod: Kubernetes 中通常通过控制器(如 Deployment、StatefulSet)来管理 Pod。控制器提供副本管理、滚动升级、自动修复等功能。
7. Pod容器的分类
7.1 基础容器(infrastructure container)
维护整个 Pod 网络和存储空间
node 节点中操作
启动一个Pod时,k8s会自动启动一个基础容器
7.2 初始化容器(initcontainers)
7.2.1 Init容器启动过程
Init容器必须在应用程序容器启动之前运行完成,而应用程序容器是并行运行的,所以Init容器能够提供了一种简单的阻塞或延迟应用容器的启动的方法。 Init 容器与普通的容器非常像,除了以下两点:
-
Init 容器总是运行到成功完成为止
启动 --》运行 --》 结束 --》 退出 成功 再运行下一个INit
-
每个 Init 容器都必须在下一个 Init 容器启动之前成功完成启动和退出 如果 Pod 的 Init 容器失败,k8s 会不断地重启该 Pod,直到 Init 容器成功为止。然而,如果 Pod 对应的重启策略(restartPolicy)为 Never,它不会重新启动。
7.2.2 Init 的容器作用
因为init容器具有与应用容器分离的单独镜像,其启动相关代码具有如下优势:
-
Init 容器可以包含一些安装过程中应用容器中不存在的实用工具或个性化代码。例如,没有必要仅为了在安装过程中使用类似 sed、 awk、 python 或 dig 这样的工具而去FROM 一个镜像来生成一个新的镜像。 独立使用的工具
-
Init 容器可以安全地运行这些工具,避免这些工具导致应用镜像的安全性降低。
-
应用镜像的创建者和部署者可以各自独立工作,而没有必要联合构建一个单独的应用镜像。
-
Init 容器能以不同于Pod内应用容器的文件系统视图运行。因此,Init容器可具有访问 Secrets 的权限,而应用容器不能够访问。
-
由于 Init 容器必须在应用容器启动之前运行完成,因此 Init 容器提供了一种机制来阻塞或延迟应用容器的启动,直到满足了一组先决条件。一旦前置条件满足,Pod内的所有的应用容器会并行启动。
第三部分:Pod 的配置与策略
8. 配置的核心部分
8.1 Pod 的镜像拉取策略
Pod 中的容器需要通过指定镜像来启动,镜像拉取策略有以下几种:
-
IfNotPresent(默认):如果本地已有镜像,不会拉取新的镜像,仅在本地缺失时拉取。 -
Always:每次启动 Pod 时都会拉取镜像。 -
Never:不拉取镜像,仅使用本地镜像。
bash
1)创建测试案例
mkdir /opt/demo
cd /opt/demo
vim pod1.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-test1
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: Always
command: [ "echo", "SUCCESS" ]
kubectl create -f pod1.yaml
kubectl edit pod pod-test1
kubectl get pods -o wide
pod-test1 0/1 CrashLoopBackOff 4 3m33s
//此时 Pod 的状态异常,原因是 echo 执行完进程终止,容器生命周期也就结束了
kubectl describe pod pod-test1
......
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m10s default-scheduler Successfully assigned default/pod-test1 to 192.168.80.11
Normal Pulled 46s (x4 over 119s) kubelet, 192.168.80.11 Successfully pulled image "nginx"
Normal Created 46s (x4 over 119s) kubelet, 192.168.80.11 Created container
Normal Started 46s (x4 over 119s) kubelet, 192.168.80.11 Started container
Warning BackOff 19s (x7 over 107s) kubelet, 192.168.80.11 Back-off restarting failed container
Normal Pulling 5s (x5 over 2m8s) kubelet, 192.168.80.11 pulling image "nginx"
//可以发现 Pod 中的容器在生命周期结束后,由于 Pod 的重启策略为 Always,容器再次重启了,并且又重新开始拉取镜
//修改 pod1.yaml 文件
cd /opt/demo
vim pod1.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-test1
spec:
containers:
- name: nginx
image: nginx:1.14 #修改 nginx 镜像版本
imagePullPolicy: Always
#command: [ "echo", "SUCCESS" ] #删除
//删除原有的资源
kubectl delete -f pod1.yaml
//更新资源
kubectl apply -f pod1.yaml
//查看 Pod 状态
kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS
pod-test1 1/1 Running 0 10m 10.244.2.24 node02 <none> <none>
//在任意 node 节点上使用 curl 查看头部信息
curl -I http:// 10.244.2.24
HTTP/1.1 200 OK
Server: nginx/1.14.2
......
8.2 Pod 的重启策略(restartPolicy)
Pod 的重启策略定义了容器退出后 Kubernetes 如何处理容器的重启。主要有以下三种策略:
-
Always:无论容器的退出状态如何,都会重新启动。 -
OnFailure:只有容器非正常退出(即退出码非 0)时,才会重启容器。 -
Never:容器退出后不会重启。
bash
vim pod3.yaml
apiVersion: v1
kind: Pod
metadata:
name: foo
spec:
containers:
- name: busybox
image: busybox
args:
- /bin/sh
- -c
- sleep 30; exit 3
kubectl apply -f pod3.yaml
//查看Pod状态,等容器启动后30秒后执行exit退出进程进入error状态,就会重启次数加1
kubectl get pods
NAME READY STATUS RESTARTS AGE
foo 1/1 Running 1 50s
vim pod3.yaml
apiVersion: v1
kind: Pod
metadata:
name: foo
spec:
containers:
- name: busybox
image: busybox
args:
- /bin/sh
- -c
- sleep 30; exit 3
restartPolicy: Never
#注意:跟container同一个级别
kubectl apply -f pod3.yaml
//容器进入error状态不会进行重启
kubectl get pods -w
#注意:K8S 中不支持重启 Pod 资源,只有删除重建