pod 中的应用随时可能被杀死.
17.2.1 应用必须预料到会被杀死或者重新调度
曾经遇到应用被 k8s 杀死, 但不知道原因的情况.
预料到本地 IP 和主机名会发生变化
预料到写入磁盘的数据会消失
如果不使用持久卷, pod 删除后, 容器中的数据也被删除.

kubelet 不会一个容器运行多次, 而是重新创建一个容器.
使用存储卷来跨容器持久化数据

注意存储卷上的旧数据可能会导致新 pod 继续崩溃.
17.2.2 重新调度死亡的或者部分死亡的 pod

ReplicaSet 只关心 pod 数量是否正确, 而不关心是否正确运行:

17.2.3 以固定顺序启动 pod
pod 之间的依赖关系.
了解 pod 是如何启动的
k8s 无法保证 pod 的启动顺序.
init 容器介绍
- 一个 pod 可以拥有任意数量的 init 容器
- init 容器顺序执行
- init 容器启动完毕后才去启动主容器
将 init 容器加入 pod
spec.initContainers:

最开始是 init 容器启动:

查看 init 容器的日志:

处理 pod 内部依赖的最佳实践
- 构建一个不需要它所依赖的服务都准备好后才能启动的应用
- 添加 Readiness 探针
17.2.4 增加生命周期钩子
- 启动后 (Post-start) 钩子
- 停止前 (Pre-stop) 钩子
作用于容器, 而 init 容器作用于 pod.
使用启动后容器生命周期钩子
可以让你在不改动应用的情况下,运行 一 些额外的命令
创建启动后钩子:

- 命令 echo 、 sleep 和 exit 是在容器创建时和容器的主进程一 起执行的
使用停止前容器生命周期钩子
k8s 停止 pod 时会执行 http get 请求:

在应用没有收到 SIGTERM 信号时使用停止前钩子
如果你的容器镜像配置是通过执行一个 shell 进程 , 然后在 shell 进程内部执行应用进程,那么这个信号就被这个 shell进程吞没了,这样就不会传递给子进程 。
- 在这种情况下,合理的做法是让 shell 进程传递这个信号给应用进程 , 而不是添加 一个停止前钩子来发送信号给应用进程
了解生命周期钩子是针对容器而不是 pod
容器的生命周期到了, 可能是因为崩溃, pod 的生命周期到了, 可能是因为 ReplicaSet 的配置变了
17.2.5 了解 pod 的关闭
对理解如何干净地关闭 pod 中运行的应用很重要。

事件的顺序:

指定终止宽限期
spec.terminationGracePeriodPeriods 字段, 默认 30s
在命令行中指定:
$ kubectl delete po mypod --grace-period=5# 立即删除$ kubectl delete po mypod --grace-period=0 --force
在应用中合理地处理容器关闭操作
- 响应 SIGTERM 信号
将重要的关闭流程替换为专注于关闭流程的 pod
用 一 个专门的持续运行中的 pod 来持续检查是否存在孤立的数据。当这个 pod 发现孤立的数据的时候,它就可以把它们迁移到仍存活的 pod 。当然不一定是 一个持续运行的 pod ,也可以使用 CronJob 资源来周期性地运行这个 pod 。

