簡體   English   中英

Kubernetes 入口錯誤:服務器遇到臨時錯誤,無法完成您的請求

[英]Kubernetes Ingress Error: The server encountered a temporary error and could not complete your request

在我們的 GKE 中,我們有一項名為php-services 它是這樣定義的:

apiVersion: v1
kind: Service
metadata:
  name: php-services
  labels:
    name: php-services
spec:
  type: NodePort
  ports:
  - port: 80
  selector:
    name: php-services

我可以從集群內部訪問此服務。 如果我在我們的一個 pod(在Default命名空間中)上運行這些命令,我​​會得到預期的結果:

bash-4.4$ nslookup 'php-services'
   Name:      php-services
   Address 1: 10.15.250.136 php-services.default.svc.cluster.local

bash-4.4$ wget -q -O- 'php-services/health'
   {"status":"ok"}

因此該服務已准備就緒並正確響應。 我需要將此服務公開給外國流量。 我正在嘗試使用以下配置在 Ingress 中執行此操作:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-tls
  annotations:
    kubernetes.io/ingress.class: "gce"
    kubernetes.io/tls-acme: "true"
    kubernetes.io/ingress.global-static-ip-name: "kubernetes-ingress"
    kubernetes.io/ingress.allow-http: "false"
    external-dns.alpha.kubernetes.io/hostname: "gke-ingress.goout.net"
  namespace: default
spec:
  tls:
  - hosts:
     - php.service.goout.net
    secretName: router-tls
  rules:
  - host: php.service.goout.net
    http:
      paths:
      - backend:
          serviceName: php-services
          servicePort: 80
        path: /*

但是隨后訪問http://php.service.goout.net/health會出現 502 錯誤:

錯誤:服務器錯誤服務器遇到臨時錯誤,可能
沒有完成您的請求。
請在 30 秒后重試。

我們還有其他具有相同配置的服務,它們運行正常並且可以從外部訪問。

我發現了一個類似的問題,但這也沒有帶來任何足夠的答案。
我也一直在關注調試服務文章,但這也沒有幫助,因為服務本身還可以。

對這個問題的任何幫助都非常感謝。

編輯 TLDR

GKE Loadbalancer 僅接受 HTTP 狀態 200 ,而 Kubernetes 運行狀況檢查接受任何大於或等於 200 且小於 400 的代碼

原答案

好的,所以我們已經弄清楚出了什么問題。

看一下php-services服務部署的yaml定義:(縮短)

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: php-services
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      name: php-services
  template:
    metadata:
      labels:
        name: php-services
    spec:
      containers:
        - name: php-services
          image: IMAGE_TAG
          livenessProbe:
            failureThreshold: 3
            httpGet:
              path: /health
              port: 80
              scheme: HTTP
            initialDelaySeconds: 60
            periodSeconds: 60
            successThreshold: 1
            timeoutSeconds: 10
          readinessProbe:
            failureThreshold: 3
            httpGet:
              path: /health
              port: 80
              scheme: HTTP
            initialDelaySeconds: 60
            periodSeconds: 60
            successThreshold: 1
            timeoutSeconds: 10
          ports:
          - containerPort: 80

圖像中的 Apache 服務器的配置方式是從路徑重定向而沒有尾部斜杠到帶有它的路徑。 因此,當您請求/health您實際上獲得了指向/health/ HTTP 狀態 301,然后響應了 200。

在 Kubernetes 健康檢查的范圍內,這是可以的,因為“ 任何大於或等於 200 且小於 400 的代碼都表示成功。

但是,問題出在 GKE Loadbalancer 上。 它還具有自己的 GKE 運行狀況檢查,這些檢查源自部署定義中的檢查。 重要的區別在於它只接受 HTTP 狀態 200 如果負載均衡器沒有找到健康的后端服務,它就不會將任何外部流量傳遞給它。

因此,我們有兩種選擇來解決這個問題:

  • 使容器內的服務器以 HTTPS 狀態 200 響應/health/health/ (或更准確地說是/health
  • 或者將readinessProbelivenessProbe路徑定義更改為/health/

我們選擇后者,它解決了問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM