(二)Pod
Pod 在 Kubernetes 中是最重要的对象之一,Pod 集群中创建和管理的、最小的可部署的计算单元
在 Kubernetes 中部署一个应用时,创建的便是 Pod,一个 Pod 中包含一个或多个容器,这些容器在 Pod 中能够共享网络、存储等环境,然后组成一个应用对外提供服务
我们不必过于关注这些概念,只需要知道,在 Kubernetes 中,是不会直接操作容器的,而是通过 Pod 封装了容器,集群通过管控 Pod ,便可控制容器的存储、网络等资源,实现资源隔离或共享
创建 Pod
以下命令 master 节点上执行
kubectl run nginxtest --image=nginx:latest --port=80
# -o wide 查看更多的 pods 信息
kubectl get pods -o wide
# ip 为 pods 中的 ip,curl 后需要显示 Welcome to nginx
curl {nginx_ip}
# 清除
kubectl delete pod nginxtest
nginxtest 为 Pod 名称,并且为其映射端口为 80,这里创建了一个 nginx 应用,并且 这个 Pod 会被 挂载在 slave 节点上
一般来说,我们会选择 使用 xx.yaml 文件 进行 pod 的创建,以此来发挥 pod 全部能力
# nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginxtest
spec:
containers:
- image: nginx:latest
name: nginxtest
ports:
- containerPort: 80
protocol: TCP
# 应用
kubeclt apply -y nginx.yaml
了解 Pod
Pod 是 Kubernetes 中调度资源的最小单位,一个 Pod 中可以包含多个容器,Pod 中的容器被打包在一起作为一个整体, Pod 中的容器不会被分配到不同节点中,它们一定被部署到同一个节点中
每个 Pod 之间都是隔离的,也就是在 Pod 内无论怎么使用端口,都不会对另一个 Pod 产生影响,但是在 Pod 内,因为各个容器都是共享同一个 Pod 的网络,因此一个 Pod 内,不允许有两个进程占用相同的端口

与 主机相同,在同一主机下,不同的 app 使用的进程、端口,都是不同的,不然就会冲突
Pod 是如何启动
在 Kubernetes 中,当创建 Pod 时,会先启动一个 pause 容器,然后 Pod 中我们定义的容器会以 containerd 模式共享 pause 中的网络,在 Pod 网络中相当于交换机,但是 pause 不只是实现容器的网络互通,还有其它功能
我们的 nginxtest 是挂载在 slave 节点上的,所以需要在 slave 上查看 pause
crictl pods --name nginxtest
crictl images | grep pause

查看 Pod 的信息
以下命令master 节点上执行
# 查看 Pod 配置、状态和事件
kubectl describe pod nginxtest
# 查看容器日志
kubectl logs nginxtest
# 在容器中执行命令
kubectl exec nginxtest -- nginx -v
Pod 常见状态有:
- Pending:尝试启动容器,如果容器正常启动,则进入下一个阶段
- Running:处于运行状态
- Succeeded、Failed:正常结束或故障等导致容器结束
- Unknown:因为某些原因无法取得 Pod 的状态
Pod 被分配到某个节点时, Pod 会一直在该节点运行,直到停止或被终止,Pod 在整个生命周期中只会被调度一次。也就是说 Pod 是一次性的,如果 Pod 故障了,那么如果需要恢复应用的运行,是需要重新创建 Pod 的,而不是重启 Pod
在 Kubernetes 中,Pod 被认为是相对的临时性实体,而不是长期存在的。由于 Pod 本身不具有治愈能力,如果 节点故障或者节点资源耗尽、节点被维护、Pod 被驱逐等,那么 Pod 无法在节点上继续存活。无论 Pod 因为何种原因被删除,在 Pod 中的网络、存储卷等,也会被销毁,新的 Pod 被创建时,相关的网络、存储卷也会被重建
在删除 Pod 时,Kubernetes 会终止 Pod 中的所有容器,会向容器中的进程发生 SIGTERM 信号,等待进程的正常关闭,所以 Pod 可能不会被马上删除,当然如果进程不能正常关闭,Kubernetes 最多等待 30s,然后会使用 SIGKILL 强制杀死进程
容器重启策略
# 一个简单的 pod.yaml 配置
apiVersion: v1
kind: Pod
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx:latest
imagePullPolicy: Always
name: nginx
... ...
restartPolicy: Always
在这个 YAML 中,有两个 *Policy ,取值有 Always、OnFailure 和 Never 三种,它们代表了某种生命周期策略
对于每个容器,都可以设置 imagePullPolicy ,指示在拉取镜像时如果失败,是否进行重试
在 spec 中,有个 restartPolicy 字段,其值默认为 Always,指示 Pod 中所有容器的重启动作,但是在 Deployment、StatefulSet、DaemonSet 等控制器中,restartPolicy 只支持 Always ,不支持 OnFailure 和 Never
容器启动失败,重试间隔会越来越长,kubelet 会在 10s 后重试第一次,如果还是失败,第二次 20s 后再重试;按照 10s、20s、40s、80s ... 的间隔重试,但最长不超过 5 分钟。如果容器被成功运行且运行了 10 分钟以上,那么计时器会被重置,下次出现故障时,按照 10s、20s 的间隔时间重试
如果单独创建 Pod,并且设置了 restartPolicy: Always,那么 Pod 会一直停留在此节点上,如果 容器故障,Pod 可能会无限重试
总结
本章粗略讲了 Pod 的一些基础知识,当然,不可能全部都能进行记忆,最重要的是,存在一个印象,等未来真实使用到这些知识时,你不会胆怯,这样,就足够了
愿诸君顺遂