1、Pod容器钩子最终目的

之前在生产环境中使用dubbo框架,由于服务更新的过程中,容器直接被停止了,部分请求仍会被分发到终止的容器,导致有用户会访问服务出现500错误,这部分错误请求数据占用的比较少,因为Pod是滚动一对一更新。由于这个问题出现了,考虑使用优雅的终止方式,将错误请求将至到最低,直至滚动更新完全不会影响到用户。

简单分析一下优雅的停止Pod

微服务中,网关会把流量分配给每个Pod节点,如:我们线上更新Pod的时候

1、如果我们直接把Pod给杀死,那这部分流量就无法得到正确的处理,会影响到部分用户访问,一般来说网关或者注册中心会将我们的服务保持一个心跳,过了心跳超时后就会自动摘除我们的服务,但是有一个问题就是超时时间可能是10s、30s、甚至是60s,虽然不会大规模的影响我们业务系统,但是一定会对用户产生轻微的抖动。

2、如果我们在停止服务前执行一条命令,通知网关或注册中心这台Pod,即服务进行下线,那么注册中心就会标记这个Pod/服务已经下线,不进行流量转发,用户也就不会有任何的影响,这就是优雅停止,将滚动更新的影响最小化。

2、何为Pod容器钩子

Kubernetes最小调度单位为Pod,它为Pod中的容器提供了生命周期钩子,钩子能够使得容器感知其生命周期内的所有事件,并且当相应的生命周期的钩子被调用时运行执行的代码,而Pod 钩子是由Kubelet发起的。

容器钩子两类触发点:

  • PostStart:容器创建后
  • PreStop:容器终止前

PostStart

这个钩子在容器创建后立即执行。

但是,并不能保证钩子将在容器ENTRYPOINT之前运行。

没有参数传递给处理程序。

容器ENTRYPOINT和钩子执行是异步操作。

如果钩子花费太长时间以至于容器不能运行或者挂起, 容器将不能达到running状态

PreStop

这个钩子在容器终止之前立即被调用。

它是阻塞的,意味着它是同步的, 所以它必须在删除容器的调用发出之前完成

如果钩子在执行期间挂起, Pod阶段将停留在running状态并且永不会达到failed状态。

如果PostStart或者PreStop钩子失败, 容器将会被kill。

用户应该使他们的钩子处理程序尽可能的轻量。

3、基于PostStart演示

如果PostStart或者PreStop钩子失败,它会杀死容器。所以我们应该让钩子函数尽可能的轻量。当然有些情况下,长时间运行命令是合理的,比如在停止容器之前预先保留状态。

1.我们echo一段话追加到/tmp/message,在Pod启动前操作

cat >>hook_test.yaml<<EOF
apiVersion: v1
kind: Pod
metadata:
name: hook-demo1
spec:
containers:
- name: hook-demo1
image: nginx
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo 1 > /tmp/message"]
EOF

2.应用hook_test.yaml

$ kubectl apply -f  hook_test.yaml

3.可以通过下面查看结果

$ kubectl get pods | grep hook-demo1
hook-demo1 1/1 Running 0 49s $ kubectl exec -it hook-demo1 /bin/bash
root@hook-demo1:/# cat /tmp/message
1

4、基于PreStop演示

下面示例中,定义一个Nginx Pod,设置了PreStop钩子函数,即在容器退出之前,优雅的关闭Nginx。

cat >>hook_test.yaml<<EOF
apiVersion: v1
kind: Pod
metadata:
name: hook-demo2
spec:
containers:
- name: hook-demo2
image: nginx
lifecycle:
preStop:
exec:
command: ["/usr/sbin/nginx","-s","quit"]
EOF

5、优雅停止Java应用

我们都知道java应用的启动和停止都需要时间,为了更加优雅的停止,可以通过pidof获取到java进程ID,循环通过kill命令往PID发送SIGTERM信号。

    lifecycle:
preStop:
exec:
command: ["/bin/bash","-c","PID=`pidof java` && kill -SIGTERM $PID && while ps -p $PID > /dev/null;do sleep 1; done;"]

最新文章

  1. iOS-常见问题
  2. Linux生产服务器Shell脚本分享
  3. Python Twisted介绍
  4. Codeforces Round #268 (Div. 2)
  5. Java 数组的三种创建方法
  6. WordPress FunCaptcha插件跨站脚本漏洞
  7. Wordpress prettyPhoto插件跨站脚本漏洞
  8. Linux 下如何安装软件?
  9. SNS团队Beta阶段第三次站立会议(2017.05.24)
  10. Django-rest-framework源码分析----认证
  11. SQLServer之锁简介
  12. scws安装
  13. SeaJS之use方法
  14. nginx部署dotnet core站点
  15. 2.Odoo产品分析 (一) – 一切为零
  16. Jmeter的安装与使用
  17. easyui datagrid编辑
  18. redis 多实例 连接 加密码
  19. Cortex_M3——存储器系统学习笔记
  20. android4.4 重启的开机不播放开机铃声,按power键的开机播放开机铃声

热门文章

  1. HDFS NameNode详解
  2. 高可用Keepalived+LVS搭建流程
  3. 使用ajax提交登录
  4. python装饰器见解笔记
  5. C++ 按行读取文件并打印
  6. 关于使用 Laravel 服务容器的优势介绍
  7. 【Weiss】【第03章】练习3.21:单数组模拟双栈
  8. 记一次Maven发布Jar包中文乱码解决方法
  9. IntelliJ IDEA 2018.1.4 x64安装创建maven项目等
  10. C语言结构体实现类似C++的构造函数