【问题标题】:Kubernetes probes fail on TomcatKubernetes 探测在 Tomcat 上失败
【发布时间】:2018-09-21 00:59:51
【问题描述】:

我在 Kubernetes 集群上的 Docker 映像中在 Tomcat 上运行 Java webapp。服务运行良好,我正在尝试设置 liveness 和 readiness 探针。

我还没有找到关于 Tomcat 和 Kubernetes 最佳实践的文档,但我认为遵循 documentation 的 HTTP GET 请求是合适的:

    livenessProbe:
      failureThreshold: 3
      httpGet:
        path: /
        port: 8080
        scheme: HTTP
      initialDelaySeconds: 20
      periodSeconds: 20
      successThreshold: 1
      timeoutSeconds: 3

访问 Tomcat 基本 URL 时,它会返回一个欢迎页面和代码 200 -- OK。但是,liveness 探测失败,这是在 pod 描述中:

Events:
  Type     Reason                 Age               From               Message
  ----     ------                 ----              ----               -------
  Normal   Scheduled              3m                default-scheduler  Successfully assigned xxxxx-service-7f8f76988-lkxdf to kube-03
  Normal   SuccessfulMountVolume  3m                kubelet, kube-03   MountVolume.SetUp succeeded for volume "default-token-b6tps"
  Normal   Created                1m (x3 over 3m)   kubelet, kube-03   Created container
  Normal   Started                1m (x3 over 3m)   kubelet, kube-03   Started container
  Warning  Unhealthy              42s (x7 over 3m)  kubelet, kube-03   Liveness probe failed: Get http://10.233.96.19:8080/: net/http: request canceled (Client.Timeout exceeded while awaiting headers)
  Normal   Pulling                40s (x4 over 3m)  kubelet, kube-03   pulling image "xxxxx:4999/xxxxx/xxxxxservice:v1.3.0"
  Normal   Pulled                 40s (x4 over 3m)  kubelet, kube-03   Successfully pulled image "xxxxx:4999/xxxxx/xxxxxservice:v1.3.0"
  Normal   Killing                40s (x3 over 2m)  kubelet, kube-03   Killing container with id docker://xxxxx-service:Container failed liveness probe.. Container will be killed and recreated.

以相同方式设置就绪探测器时也是如此。 但是,当我停用探针时,服务运行良好。我可以使用/ 以及实际的 webapp 访问 Tomcat 欢迎页面。

因此,我的问题是:我应该如何为 Tomcat webapp 正确设置 Kubernetes liveness/readiness 探针?为什么简单的HTTP GET 方法会失败?

相关问题似乎是由于启动时间比initialDelaySeconds 参数中设置的时间长(例如this),正如错误消息所示。但是,在这种情况下,Tomcat 和 webapp 确实可以在几秒钟后访问,因此启动时间不是这里的问题。

以下是部署规范:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: xxxxx-service
  namespace: xxxxx
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: xxxxx-service
    spec:
      imagePullSecrets:
      - name: regsecret
      containers:
      - image: xxxxxservice:v1.3.0
        imagePullPolicy: Always
        name: xxxxx-service
        ports:
        - containerPort: 8080
          protocol: TCP
        resources:
          limits:
            cpu: "0.2"
            memory: 4Gi

【问题讨论】:

  • 您能说出您的 Tomcat 应用程序的 ContainerPort 值吗?
  • @AntonKostenko 我已经添加了完整的部署规范。端口为 8080(Tomcat 默认)。

标签: tomcat kubernetes


【解决方案1】:

您的配置看起来不错,应该可以工作,但在我看到的事件中:

Get http://10.233.96.19:8080/: net/http: request canceled (Client.Timeout exceeded while awaiting headers)

这意味着kubelet 已连接到您的 pod,但请求被取消,因为在等待标头时超时。

所以,我认为问题出在您的应用程序中,可能是:

  1. 默认路由规则不正确。默认情况下,kubelet 发送的请求没有任何标头(包括 Host),因此应用程序可能只是不知道如何处理该请求。尝试像这样设置Host 标头:

    livenessProbe:
      httpGet:
        httpHeaders:
          Host: <desired.host.of.application.com>
    
  2. 在开始时,应用程序可能会运行得有点慢。在这种情况下,3 秒的超时可能是不够的。您可以尝试增加timeoutSeconds 的值。

【讨论】:

  • 谢谢!我认为可以排除选项2;我将timeoutSeconds 增加到 30 并且错误仍然存​​在。该服务通常会在 name: ...的格式; value: .... 我有点不清楚“期望的主机”应该是什么。
  • 'desired host' 是您在 Ingress 上使用的服务的外部主机名,例如。简而言之 - 这就是您在浏览器中打印的地址以访问您的服务。
【解决方案2】:

我有同样的问题。经过一段时间的调查,我发现我的应用程序中的 tomcat 服务器大约需要 35 秒才能启动。因此,我将 initialDelaySeconds 更改为大于 35 秒。我还将超时秒数增加到 10 秒,将 period_second 增加到 10 秒。然后 Kubernetes 探针完美运行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-05
    • 2021-09-15
    • 2018-07-10
    • 2023-03-11
    • 1970-01-01
    • 2021-02-06
    • 1970-01-01
    • 2022-01-12
    相关资源
    最近更新 更多