写点什么

模块八作业

作者:hunk
  • 2022 年 2 月 27 日
  • 本文字数:1771 字

    阅读完需:约 6 分钟

Deployment

deployment controller 生成 rs,rs controller 去启动配置。


apiVersion: apps/v1kind: Deploymentmetadata:  name: httpserver  labels:    app: httpserverspec:  replicas: 1  selector:    matchLabels:      app: httpserver    template:      metadata:        labels:          app: httpserver      spec:        imagePullSecrets:        - name: cloudnative        containers:        - name: httpserver          image:  47.104.179.23/httpserver:1.0          ports:          - containerPort: 8080
复制代码

优雅启动


一个服务刚启动,可能会有一堆东西要加载,比如需要 load 大量数据等等,此时程序启动了,但是并未准备好处理外部请求,所以利用一些探针来测试程序是否启动完成,然后进入下一步


Probe 探针

https://kubernetes.io/zh/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/

Readiness Probe

YAML readinessProbe: httpGet: path: /healthz port: 8080 scheme: HTTP initialDelaySeconds: 5 periodSeconds: 3

initialDelaySeconds 字段告诉 kubelet 在执行第一次探测前应该等待 3 秒

periodSeconds 字段指定了 kubelet 每隔 3 秒执行一次存活探测

Startup Probe 慢启动容器

应用程序在启动时需要较多的初始化时间。 要不影响对引起探测死锁的快速响应,这种情况下,设置存活探测参数是要技巧的。 技巧就是使用一个命令来设置启动探测,针对 HTTP 或者 TCP 检测,可以通过设置 failureThreshold * periodSeconds 参数来保证有足够长的时间应对糟糕情况下的启动时间。

YAMLstartupProbe: httpGet: path: /healthz port: liveness-port failureThreshold: 30 periodSeconds: 10

应用程序将会有最多 5 分钟(30 * 10 = 300s) 的时间来完成它的启动

livenessProbe

YAMLlivenessProbe: exec: command: - cat - /tmp/healthy initialDelaySeconds: 5 periodSeconds: 5livenessProbe: httpGet: path: /healthz port: 8080 httpHeaders: - name: Custom-Header value: Awesome initialDelaySeconds: 3 periodSeconds: 3


init container

通常 pod 有一些初始化操作,创建文件夹,初始化磁盘,检查某些依赖服务是不是正常,这些操作放在代码中会污染代码,写在启动命令中不方便管理,出问题也不方便排查,更优雅的方式是使用 init container


https://kubernetes.io/zh/docs/concepts/workloads/pods/init-containers/


postStart

https://kubernetes.io/zh/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/#%E5%AE%9A%E4%B9%89-poststart-%E5%92%8C-prestop-%E5%A4%84%E7%90%86%E5%87%BD%E6%95%B0


postStart 操作执行完成之前,kubelet 会锁住容器,不让应用程序的进程启动,只有在 postStart 操作完成之后容器的状态才会被设置成为 RUNNING。


优雅中止

https://kubernetes.io/zh/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/


有优雅启动,就有优雅中止,我们先看中止的流程:


容器终止流程

  1. Pod 被删除,状态置为 Terminating。

  2. kube-proxy 更新转发规则,将 Pod 从 service 的 endpoint 列表中摘除掉,新的流量不再转发到该 Pod。

  3. 如果 Pod 配置了 preStop Hook ,将会执行。

  4. kubelet 对 Pod 中各个 container 发送 SIGTERM 信号以通知容器进程开始优雅停止。

  5. 等待容器进程完全停止,如果在 terminationGracePeriodSeconds 内 (默认 30s) 还未完全停止,就发送 SIGKILL 信号强制杀死进程。

  6. 所有容器进程终止,清理 Pod 资源。


SIGTERM & SIGKILL

9 - SIGKILL 强制终端

15 - SIGTEM 请求中断


容器内的进程不能用 SIGTEM 中断的,都不能算优雅中止,所以这里有个常见问题,为什么有些容器 SIGTEM 信号不起作用。


如果容器启动入口使用了 shell,比如使用了类似  /bin/sh -c my-app  或  /docker-entrypoint.sh  这样的 ENTRYPOINT 或 CMD,这就可能就会导致容器内的业务进程收不到 SIGTERM 信号,原因是:

  • 容器主进程是 shell,业务进程是在 shell 中启动的,成为了 shell 进程的子进程。

  • shell 进程默认不会处理 SIGTERM 信号,自己不会退出,也不会将信号传递给子进程,导致业务进程不会触发停止逻辑。

  • 当等到 K8S 优雅停止超时时间 (terminationGracePeriodSeconds,默认 30s),发送 SIGKILL 强制杀死 shell 及其子进程。

发布于: 刚刚阅读数: 3
用户头像

hunk

关注

还未添加个人签名 2019.01.23 加入

还未添加个人简介

评论

发布
暂无评论
模块八作业