【问题标题】:Kubernetes health checks fail with custom Nginx webserver configurationKubernetes 健康检查因自定义 Nginx 网络服务器配置而失败
【发布时间】:2020-05-01 12:47:16
【问题描述】:

我的健康检查因以下设置而失败。

nginx.conf

user                            root;
worker_processes                auto;

error_log                       /var/log/nginx/error.log warn;

events {
    worker_connections          1024;
}

http {
    server {
        listen                  80;
        server_name             subdomain.domain.com
        auth_basic              "Restricted";
        auth_basic_user_file    /etc/nginx/.htpasswd;
    }
    server {
        listen                  80;
        auth_basic              off;
    }
    server {
        listen                  2222;
        auth_basic              off;
        location /healthz {
            return 200;
        }
    }
}

码头文件

FROM nginx:alpine
COPY index.html /usr/share/nginx/html/index.html
VOLUME /usr/share/nginx/html
COPY /server/nginx.conf /etc/nginx/
COPY /server/htpasswd /etc/nginx/.htpasswd
CMD ["nginx", "-g", "daemon off;"]
EXPOSE 80
EXPOSE 2222

deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  namespace: my-namespace
  labels:
    app: my-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: my-app
          image: gcr.io/GOOGLE_CLOUD_PROJECT/my-app
          ports:
            - containerPort: 80
            - containerPort: 2222
          livenessProbe:
            httpGet:
              path: /healthz
              port: 2222
          readinessProbe:
            httpGet:
              path: /healthz
              port: 2222

当我删除 nginx.conf 中的“server_name”行并删除第二个服务器块时,它肯定有效。 这可能是入口/负载均衡器的问题,因为我不知道更新需要多长时间(昨天几分钟后,我经历了一个健康的 pod 变得不健康)。使用 Google 自己的入口控制器(不是 NGINX 入口!)在 Google Kubernetes Engine (GKE) 上运行它

我做错了什么?

【问题讨论】:

  • 你能显示失败的日志吗?它是立即失败还是仅在一段时间后失败?
  • 除了日志之外,我们还需要确保当subdomain.domain.com/healthz被定位时,有一个到2222端口的路由。当您删除该行时它会起作用,因为它可能开始将目标视为本地主机。请发布服务和入口 yaml,以便我们进一步调查

标签: docker nginx kubernetes google-kubernetes-engine basic-authentication


【解决方案1】:

问题在于 GKE 的负载平衡器会进行自己的运行状况检查。这些默认情况下查看 / 并期望得到 200 作为回报。只有当部署/pod 中的健康检查声明了另一个路径时,负载均衡器健康检查才会选择这些路径。

负载均衡器是在应用入口 YAML 后配置的。只要负载均衡器运行,部署或入口中的任何影响负载均衡器的更改都不会被接受。这意味着我必须先删除负载均衡器,然后应用部署、服务和入口 YAML(然后入口自动设置负载均衡器)。无需删除负载均衡器,您可以手动输入正确的路径(并等待几分钟)。

由于负载平衡器似乎对每个打开的端口进行健康检查,我删除了我的 2222 端口,并将位置 /healthz 添加到每个服务器块,在 nginx 中使用端口 80 并关闭 auth_basic。

请参阅:https://cloud.google.com/load-balancing/docs/health-check-conceptshttps://stackoverflow.com/a/61222826/2534357https://stackoverflow.com/a/38511357/2534357

新建 nginx.conf

user                            root;
worker_processes                auto;

error_log                       /var/log/nginx/error.log warn;

events {
    worker_connections          1024;
}

http {
    server {
        listen                  80;
        server_name             subdomain1.domain.com;
        root                    /usr/share/nginx/html;
        index                   index.html;
        auth_basic              "Restricted";
        auth_basic_user_file    /etc/nginx/.htpasswd_subdomain1;
        location /healthz {
            auth_basic          off;
            allow               all;
            return              200;
        }
    }
    server {
        listen                  80;
        server_name             subdomain2.domain.com;
        root                    /usr/share/nginx/html;
        index                   index.html;
        auth_basic              "Restricted";
        auth_basic_user_file    /etc/nginx/.htpasswd_subdomain2;
        location /healthz {
            auth_basic          off;
            allow               all;
            return              200;
        }
    }
    server {
        listen                  80;
        server_name             domain.com www.domain.com;
        root                    /usr/share/nginx/html;
        index                   index.html;
        auth_basic              "Restricted";
        auth_basic_user_file    /etc/nginx/.htpasswd_domain;
        location /healthz {
            auth_basic          off;
            allow               all;
            return              200;
        }
    }
    ## next block probably not necessary
    server {
        listen                  80;
        auth_basic              off;
        location /healthz {
            return              200;
        }
    }
}

我的新部署.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  namespace: my-namespace
  labels:
    app: my-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: my-app
          image: gcr.io/GOOGLE_CLOUD_PROJECT/my-app
          ports:
            - containerPort: 80
          livenessProbe:
            httpGet:
              path: /healthz
              port: 80
          readinessProbe:
            httpGet:
              path: /healthz
              port: 80

【讨论】:

    猜你喜欢
    • 2020-12-19
    • 1970-01-01
    • 2018-12-30
    • 2020-03-01
    • 2021-12-18
    • 2019-03-05
    • 2019-05-05
    • 1970-01-01
    • 2016-08-16
    相关资源
    最近更新 更多