经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » Kubernetes » 查看文章
探究kubernetes 探针参数periodSeconds和timeoutSeconds
来源:cnblogs  作者:charlieroro  时间:2024/7/11 11:11:45  对本文有异议

探究kubernetes 探针参数 periodSecondstimeoutSeconds

问题起源

kubernetes probes的配置中有两个容易混淆的参数,periodSecondstimeoutSeconds,其配置方式如下:

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: darwin-app
  5. spec:
  6. containers:
  7. - name: darwin-container
  8. image: darwin-image
  9. livenessProbe:
  10. httpGet:
  11. path: /darwin-path
  12. port: 8080
  13. initialDelaySeconds: 60
  14. periodSeconds: 10
  15. timeoutSeconds: 5
  16. failureThreshold: 3

官方对这两个参数的解释如下:

  • periodSeconds: How often (in seconds) to perform the probe. Default to 10 seconds. The minimum value is 1.
  • timeoutSeconds: Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1.

意思是说periodSeconds表示执行探针的周期,而timeoutSeconds表示执行探针的超时时间。

网上有不少针对这两个参数的讨论(如下),其中涉及到一个问题,如果timeoutSeconds > periodSeconds 会怎么样?

  1. What is the role of timeoutSeconds in kubernetes liveness/readiness probes?
  2. Kubernetes Health Check: timeoutSeconds exceeds periodSeconds
  3. Does periodSeconds in Kubernetes probe configuration count from the last probe time or the last response/failure time?

其中在上面的第3篇中对timeoutSeconds>periodSeconds的情况有如下描述,即在这种情况下,如果探针超时,则探针周期等于timeoutSeconds。那么这种说法是否正确呢?

If you had the opposite (timeoutSeconds=10, periodSeconds=5), then the probes would look as follows:

  1. 0s: liveness probe initiated
  2. 10s: liveness probe times out
  3. 10s: liveness probe initiated again

源码探究

鉴于网上众说纷纭,我们通过源码来一探究竟。

kubernetes的探针机制是由kubelet执行的,目前支持execgrpchttpGettcpSocket这4种探针方式。

探针的代码逻辑并不复杂,以v1.30.2的代码为例,其入口函数如下,可以看到它会启动一个周期为w.spec.PeriodSeconds(即探针中定义的periodSeconds)定时器,周期性地执行探针。

  1. // run periodically probes the container.
  2. func (w *worker) run() {
  3. ctx := context.Background()
  4. probeTickerPeriod := time.Duration(w.spec.PeriodSeconds) * time.Second
  5. ...
  6. probeTicker := time.NewTicker(probeTickerPeriod)
  7. ...
  8. probeLoop:
  9. for w.doProbe(ctx) {
  10. // Wait for next probe tick.
  11. select {
  12. case <-w.stopCh:
  13. break probeLoop
  14. case <-probeTicker.C:
  15. case <-w.manualTriggerCh:
  16. // continue
  17. }
  18. }
  19. }

现在已经找到periodSeconds的用途,下一步需要找到timeoutSeconds

  1. 首先进入doProbe函数,它调用了w.probeManager.prober.probe

    1. // doProbe probes the container once and records the result.
    2. // Returns whether the worker should continue.
    3. func (w *worker) doProbe(ctx context.Context) (keepGoing bool) {
    4. ...
    5. // Note, exec probe does NOT have access to pod environment variables or downward API
    6. result, err := w.probeManager.prober.probe(ctx, w.probeType, w.pod, status, w.container, w.containerID)
    7. if err != nil {
    8. // Prober error, throw away the result.
    9. return true
    10. }
    11. ...
    12. }
  2. 下面的probe函数用于执行一个特定的探针。需要注意的是,它调用了pb.runProbeWithRetries,其中maxProbeRetries值为3,说明在一个周期(periodSeconds)中最多可以执行3次探针命令

    1. // probe probes the container.
    2. func (pb *prober) probe(ctx context.Context, probeType probeType, pod *v1.Pod, status v1.PodStatus, container v1.Container, containerID kubecontainer.ContainerID) (results.Result, error) {
    3. var probeSpec *v1.Probe
    4. switch probeType {
    5. case readiness:
    6. probeSpec = container.ReadinessProbe
    7. case liveness:
    8. probeSpec = container.LivenessProbe
    9. case startup:
    10. probeSpec = container.StartupProbe
    11. default:
    12. return results.Failure, fmt.Errorf("unknown probe type: %q", probeType)
    13. }
    14. ...
    15. result, output, err := pb.runProbeWithRetries(ctx, probeType, probeSpec, pod, status, container, containerID, maxProbeRetries)
    16. ...
    17. }
  3. runProbeWithRetries的注释说明,可能会执行多次探针,直到探针返回成功或全部尝试失败:

    1. // runProbeWithRetries tries to probe the container in a finite loop, it returns the last result
    2. // if it never succeeds.
    3. func (pb *prober) runProbeWithRetries(ctx context.Context, probeType probeType, p *v1.Probe, pod *v1.Pod, status v1.PodStatus, container v1.Container, containerID kubecontainer.ContainerID, retries int) (probe.Result, string, error) {
    4. ...
    5. for i := 0; i < retries; i++ {
    6. result, output, err = pb.runProbe(ctx, probeType, p, pod, status, container, containerID)
    7. ...
    8. }
    9. ...
    10. }
  4. runProbe函数中,最终找到了timeoutSeconds对应的参数p.TimeoutSeconds,其作为各个探针命令的超时参数,如在httpGet类型的探针中,它作为了httpClient的请求超时时间:

    1. func (pb *prober) runProbe(ctx context.Context, probeType probeType, p *v1.Probe, pod *v1.Pod, status v1.PodStatus, container v1.Container, containerID kubecontainer.ContainerID) (probe.Result, string, error) {
    2. timeout := time.Duration(p.TimeoutSeconds) * time.Second
    3. if p.Exec != nil {
    4. command := kubecontainer.ExpandContainerCommandOnlyStatic(p.Exec.Command, container.Env)
    5. return pb.exec.Probe(pb.newExecInContainer(ctx, container, containerID, command, timeout))
    6. }
    7. if p.HTTPGet != nil {
    8. req, err := httpprobe.NewRequestForHTTPGetAction(p.HTTPGet, &container, status.PodIP, "probe")
    9. ...
    10. return pb.http.Probe(req, timeout)
    11. }
    12. if p.TCPSocket != nil {
    13. port, err := probe.ResolveContainerPort(p.TCPSocket.Port, &container)
    14. ...
    15. host := p.TCPSocket.Host
    16. if host == "" {
    17. host = status.PodIP
    18. }
    19. return pb.tcp.Probe(host, port, timeout)
    20. }
    21. if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.GRPCContainerProbe) && p.GRPC != nil {
    22. host := status.PodIP
    23. service := ""
    24. if p.GRPC.Service != nil {
    25. service = *p.GRPC.Service
    26. }
    27. return pb.grpc.Probe(host, service, int(p.GRPC.Port), timeout)
    28. }
    29. ...
    30. }

至此我们可以拼接出periodSecondstimeoutSeconds的关系,其逻辑关系与如下代码类似。

  1. probeTicker := time.NewTicker(periodSeconds)
  2. for {
  3. select {
  4. case <-probeTicker.C:
  5. for i := 0; i < 3; i++ {
  6. if ok:=probe(timeoutSeconds);ok{
  7. return
  8. }
  9. }
  10. }

总结

  • periodSeconds用于启动一个周期性调用探针命令的定时器,而timeoutSeconds作为探针命令的超时参数
  • timeoutSecondsperiodSeconds之间并没有明确的关系。如果timeoutSeconds=10s,periodSeconds=5s,则本次探针周期可能为[5s, 30s)之内的任意值,并不是该文中说的periodSeconds=timeoutSeconds(由于本文写于3年前,经查阅v1.19.10版本代码,逻辑上与现有版本代码相同。)
  • 由于健康检查的逻辑大部分都不会很复杂,如检查某个文件是否存在,检查服务的/hleathz http endpoint是否可以访问等,因此建议将timeoutSeconds设置为一个小于periodSeconds的合理的值。

failureThreshold/successThresholdmaxProbeRetries的关系

  • maxProbeRetries用于定义一次探针周期内探针命令执行的最大尝试次数;
  • 如果在一个探针周期内,探针命令返回成功,则successThreshold 加1,反之failureThreshold加1;

原文链接:https://www.cnblogs.com/charlieroro/p/18294255

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号