关于kubernetes:使用Kubernetes健康检查

7次阅读

共计 2161 个字符,预计需要花费 6 分钟才能阅读完成。

前言

我最近看到了很多无关 Kubernetes 健康检查以及如何应用它们的问题,对此我将尽力解释它们以及运行状况查看的类型之间的差别以及每种查看将如何影响你的应用程序。

Liveness Probes

Kubernetes 健康检查分为存活探针和就绪探针,存活探针的目标是查看你的应用程序是否正在运行。通常状况下,你的应用程序可能会解体,而 Kubernetes 会看到该应用程序已终止并重新启动,然而存活探测的目标是捕捉应用程序解体或死锁而无奈终止的状况,因而,一个简略的 HTTP 响应就足够了。

这是我常常在 Go 应用程序中应用的运行健康检查的一个简略的例子。

http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {w.Write([]byte("OK"))
}
http.ListenAndServe(":8080", nil)

在 deployment 文件外面的内容是:

livenessProbe:
  # an http probe
  httpGet:
    path: /healthz
    port: 8080
  initialDelaySeconds: 15
  timeoutSeconds: 1

这只是通知 Kubernetes 该利用已启动并正在运行,initialDelaySeconds 通知 Kubernetes 在启动 Pod 之后将运行状况查看提早启动此秒数。如果你的应用程序须要一段时间能力启动,则能够应用此设置来解决问题。timeoutSeconds 通知 Kubernetes 应该期待多长时间能力进行健康检查响应,对于存活探针,这应该不会很长,然而你的确应该给你的利用足够的工夫来响应,即便在负载有余的状况下也是如此。

如果利用从不启动或没有 HTTP 错误代码响应,Kubernetes 将重新启动 Pod,你要竭尽所能地不要在存活探针上做任何花哨的事件,因为如果存活探针检测失败可能会导致应用程序中断。

Readiness Probes

就绪探针与存活探针十分类似,不同之处在于探针探测失败的后果不同。就绪探针旨在查看应用程序是否已筹备好对外提供服务。这与存活探针有轻微的差异,例如,假如你的利用依赖于数据库和内存缓存,如果这两者都须要启动并运行以使你的应用程序可能对外提供服务,那么能够说这两个条件都是应用程序“就绪”所必须的。

如果针对你的应用程序的就绪探针失败,那么将从形成 service 的 endpoints 中删除该 Pod,这使得 Kubernetes 的服务发现机制不会向尚未准备就绪的 Pod 导入流量,这对于启动新的 service、动静伸缩,滚动更新等很有帮忙。“就绪”探针可确保在 Pod 启动和筹备对外提供服务之间的这段时间内,不向 Pod 导入流量。

就绪探针的定义与存活探针雷同,就绪探针定义为 Deployment 的一部分,如下所示:

readinessProbe:
  # an http probe
  httpGet:
    path: /readiness
    port: 8080
  initialDelaySeconds: 20
  timeoutSeconds: 5readinessProbe:
  # an http probe
  httpGet:
    path: /readiness
    port: 8080
  initialDelaySeconds: 20
  timeoutSeconds: 5

你将须要查看就绪探针是否能够连贯到所有应用程序的依赖项,以及要应用依赖于数据库和内存缓存的示例,接下来将查看是否可能同时连贯到这两者。
大略相似这样,在这里,我查看了 memcached 和数据库,如果不可用,则返回 503。

http.HandleFunc("/readiness", func(w http.ResponseWriter, r *http.Request) {
  ok := true
  errMsg = ""

  // Check memcache
  if mc != nil {err := mc.Set(&memcache.Item{Key: "healthz", Value: []byte("test")})
  }
  if mc == nil || err != nil {
    ok = false
    errMsg += "Memcached not ok.¥n"
  }

  // Check database
  if db != nil {_, err := db.Query("SELECT 1;")
  }
  if db == nil || err != nil {
    ok = false
    errMsg += "Database not ok.¥n"
  } 

  if ok {w.Write([]byte("OK"))
  } else {
    // Send 503
    http.Error(w, errMsg, http.StatusServiceUnavailable)
  }
})
http.ListenAndServe(":8080", nil)

更强壮的利用

Liveness 和 Readiness 探针的确有助于进步应用程序的稳定性,它们有助于确保流量仅流向已准备就绪的实例,并在应用程序无响应时自愈。对于我的共事 Kelsey Hightower 所说的 12 Fractured Apps),它们是更好的解决方案。通过适当的运行健康检查,你能够按任何程序部署应用程序,而不用放心依赖关系或者简单的 endpoints 脚本,应用程序准备就绪后将开始提供流量,主动伸缩和滚动更新也将顺利进行。

正文完
 0