Kubernetes 更新服务目标时,我在5到60秒内有502个错误

Kubernetes 更新服务目标时,我在5到60秒内有502个错误,kubernetes,service,google-kubernetes-engine,Kubernetes,Service,Google Kubernetes Engine,我想手动将一个web服务器(GKE上的Helm部署)重新路由到另一个 为此,我有3个头盔部署: 应用程序X 应用程序Y 应用程序X上的入口 所有工作正常,但如果我启动Helm更新,且Ingress chart唯一地更改了我目标服务的选择器,则我有502个错误:( 服务来源: apiVersion: v1 kind: Service metadata: name: {{ .Values.Service.Name }}-https labels: app: {{ .Values.

我想手动将一个web服务器(GKE上的Helm部署)重新路由到另一个

为此,我有3个头盔部署:

  • 应用程序X
  • 应用程序Y
  • 应用程序X上的入口
所有工作正常,但如果我启动Helm更新,且Ingress chart唯一地更改了我目标服务的选择器,则我有502个错误:(

服务来源:

apiVersion: v1
kind: Service
metadata:
  name: {{ .Values.Service.Name }}-https
  labels:
    app: {{ .Values.Service.Name }}
    type: svc
    name: {{ .Values.Service.Name }}
    environment: {{ .Values.Environment.Name }}
  annotations:
    cloud.google.com/neg: '{"ingress": true}'
    beta.cloud.google.com/backend-config: '{"ports": {"{{ .Values.Application.Port }}":"{{ .Values.Service.Name }}-https"}}'
spec:
  type: NodePort
  selector:
    name: {{ .Values.Application.Name }}
    environment: {{ .Values.Environment.Name }}
  ports:
    - protocol: TCP
      port: {{ .Values.Application.Port }}
      targetPort: {{ .Values.Application.Port }}
---
apiVersion: cloud.google.com/v1beta1
kind: BackendConfig
metadata:
  name: {{ .Values.Service.Name }}-https
spec:
  timeoutSec: 50
  connectionDraining:
    drainingTimeoutSec: 60
  sessionAffinity:
    affinityType: "GENERATED_COOKIE"
    affinityCookieTtlSec: 300
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: {{ .Values.Service.Name }}-https
  labels:
    app: {{ .Values.Service.Name }}
    type: ingress
    name: {{ .Values.Service.Name }}
    environment: {{ .Values.Environment.Name }}
  annotations:
    kubernetes.io/ingress.global-static-ip-name: {{ .Values.Service.PublicIpName }}
    networking.gke.io/managed-certificates: "{{ join "," .Values.Service.DomainNames }}"
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  backend:
    serviceName: {{ $.Values.Service.Name }}-https
    servicePort: 80
  rules:
  {{- range .Values.Service.DomainNames }}
    - host: {{ . | title | lower }}
      http:
        paths:
          - backend:
              serviceName: {{ $.Values.Service.Name }}-https
              servicePort: 80
  {{- end }}
从一个调用到另一个调用的唯一变化是“{{.Values.Application.Name}”的值,所有其他值都是完全相同的

目标POD始终处于启动和运行状态,所有POD都使用“kubectl”端口转发测试响应200

以下是我的所有命名空间对象的状态:

NAME                                           READY   STATUS    RESTARTS   AGE
pod/drupal-dummy-404-v1-pod-744454b7ff-m4hjk   1/1     Running   0          2m32s
pod/drupal-dummy-404-v1-pod-744454b7ff-z5l29   1/1     Running   0          2m32s
pod/drupal-dummy-v1-pod-77f5bf55c6-9dq8n       1/1     Running   0          3m58s
pod/drupal-dummy-v1-pod-77f5bf55c6-njfl9       1/1     Running   0          3m57s

NAME                                    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
service/drupal-dummy-v1-service-https   NodePort    172.16.90.71    <none>        80:31391/TCP                 3m49s

NAME                                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/drupal-dummy-404-v1-pod   2/2     2            2           2m32s
deployment.apps/drupal-dummy-v1-pod       2/2     2            2           3m58s

NAME                                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/drupal-dummy-404-v1-pod-744454b7ff   2         2         2       2m32s
replicaset.apps/drupal-dummy-v1-pod-77f5bf55c6       2         2         2       3m58s

NAME                                                         AGE
managedcertificate.networking.gke.io/d8.syspod.fr            161m
managedcertificate.networking.gke.io/d8gfi.syspod.fr         128m
managedcertificate.networking.gke.io/dummydrupald8.cnes.fr   162m

NAME                                               HOSTS                                                ADDRESS          PORTS   AGE
ingress.extensions/drupal-dummy-v1-service-https   d8gfi.syspod.fr   34.120.106.136   80      3m50s
这里还有服务转储:

root@c55834fbdf1a:/# k get service/drupal-dummy-v1-service-https -o json
{
    "apiVersion": "v1",
    "kind": "Service",
    "metadata": {
        "annotations": {
            "beta.cloud.google.com/backend-config": "{\"ports\": {\"80\":\"drupal-dummy-v1-service-https\"}}",
            "cloud.google.com/neg": "{\"ingress\": true}",
            "cloud.google.com/neg-status": "{\"network_endpoint_groups\":{\"80\":\"k8s1-4846660e-e1-drupal-dummy-v1-service-https-80-36c11551\"},\"zones\":[\"europe-west3-a\",\"europe-west3-b\"]}",
            "meta.helm.sh/release-name": "drupal-dummy-v1-service",
            "meta.helm.sh/release-namespace": "e1"
        },
        "creationTimestamp": "2020-06-23T18:50:45Z",
        "labels": {
            "app": "drupal-dummy-v1-service",
            "app.kubernetes.io/managed-by": "Helm",
            "environment": "e1",
            "name": "drupal-dummy-v1-service",
            "type": "svc"
        },
        "name": "drupal-dummy-v1-service-https",
        "namespace": "e1",
        "resourceVersion": "3982781",
        "selfLink": "/api/v1/namespaces/e1/services/drupal-dummy-v1-service-https",
        "uid": "722d3a99-b582-11ea-9df2-42010a000006"
    },
    "spec": {
        "clusterIP": "172.16.103.181",
        "externalTrafficPolicy": "Cluster",
        "ports": [
            {
                "nodePort": 32396,
                "port": 80,
                "protocol": "TCP",
                "targetPort": 80
            }
        ],
        "selector": {
            "environment": "e1",
            "name": "drupal-dummy-v1-pod"
        },
        "sessionAffinity": "None",
        "type": "NodePort"
    },
    "status": {
        "loadBalancer": {}
    }
}
和入口一:

root@c55834fbdf1a:/# k get ingress.extensions/drupal-dummy-v1-service-https -o json
{
    "apiVersion": "extensions/v1beta1",
    "kind": "Ingress",
    "metadata": {
        "annotations": {
            "ingress.gcp.kubernetes.io/pre-shared-cert": "mcrt-a15e339b-6c3f-4f23-8f6b-688dc98b33a6,mcrt-f3a385de-0541-4b9c-8047-6dcfcbd4d74f",
            "ingress.kubernetes.io/backends": "{\"k8s1-4846660e-e1-drupal-dummy-v1-service-https-80-36c11551\":\"HEALTHY\"}",
            "ingress.kubernetes.io/forwarding-rule": "k8s-fw-e1-drupal-dummy-v1-service-https--4846660e8b9bd880",
            "ingress.kubernetes.io/https-forwarding-rule": "k8s-fws-e1-drupal-dummy-v1-service-https--4846660e8b9bd880",
            "ingress.kubernetes.io/https-target-proxy": "k8s-tps-e1-drupal-dummy-v1-service-https--4846660e8b9bd880",
            "ingress.kubernetes.io/ssl-cert": "mcrt-a15e339b-6c3f-4f23-8f6b-688dc98b33a6,mcrt-f3a385de-0541-4b9c-8047-6dcfcbd4d74f",
            "ingress.kubernetes.io/target-proxy": "k8s-tp-e1-drupal-dummy-v1-service-https--4846660e8b9bd880",
            "ingress.kubernetes.io/url-map": "k8s-um-e1-drupal-dummy-v1-service-https--4846660e8b9bd880",
            "kubernetes.io/ingress.global-static-ip-name": "gkxe-k1312-e1-drupal-dummy-v1",
            "meta.helm.sh/release-name": "drupal-dummy-v1-service",
            "meta.helm.sh/release-namespace": "e1",
            "networking.gke.io/managed-certificates": "dummydrupald8.cnes.fr,d8.syspod.fr",
            "nginx.ingress.kubernetes.io/rewrite-target": "/"
        },
        "creationTimestamp": "2020-06-23T18:50:45Z",
        "generation": 1,
        "labels": {
            "app": "drupal-dummy-v1-service",
            "app.kubernetes.io/managed-by": "Helm",
            "environment": "e1",
            "name": "drupal-dummy-v1-service",
            "type": "ingress"
        },
        "name": "drupal-dummy-v1-service-https",
        "namespace": "e1",
        "resourceVersion": "3978178",
        "selfLink": "/apis/extensions/v1beta1/namespaces/e1/ingresses/drupal-dummy-v1-service-https",
        "uid": "7237fc51-b582-11ea-9df2-42010a000006"
    },
    "spec": {
        "backend": {
            "serviceName": "drupal-dummy-v1-service-https",
            "servicePort": 80
        },
        "rules": [
            {
                "host": "dummydrupald8.cnes.fr",
                "http": {
                    "paths": [
                        {
                            "backend": {
                                "serviceName": "drupal-dummy-v1-service-https",
                                "servicePort": 80
                            }
                        }
                    ]
                }
            },
            {
                "host": "d8.syspod.fr",
                "http": {
                    "paths": [
                        {
                            "backend": {
                                "serviceName": "drupal-dummy-v1-service-https",
                                "servicePort": 80
                            }
                        }
                    ]
                }
            }
        ]
    },
    "status": {
        "loadBalancer": {
            "ingress": [
                {
                    "ip": "34.98.97.102"
                }
            ]
        }
    }
}

我在kubernetes事件中看到了这一点(仅当我将服务选择器重新配置为针对第一次或第二次部署时)

切换到不可分割页面(3秒502):

切换回应用程序(15秒502->从不相同的持续时间):

我可以检查NEG事件是否在502错误结束前出现,我怀疑当我们更改服务定义时,会实现一个新的NEG,但时间不是立即的,在我们等待它的过程中,仍然没有启动旧服务,并且在这段时间内没有服务:(


没有“滚动更新”关于服务定义?

根本没有解决方案,即使有两个服务并且只升级入口。在GCP支持下,GKE将始终销毁然后重新创建一些不可能在没有停机的情况下对服务或入口进行滚动更新的内容。他们建议有两个完整的筒仓,然后使用DNS,我们选择了另一个解决方案,只有一个部署,只需对部署进行简单的滚动更新,更改引用的docker映像。在目标系统中不是这样,但它可以工作…

通常,当这两个k8s部署都定义了不同的运行状况检查时,我会发生这种情况。在这种情况下,我通常要做的是从GKE入口中删除主机,然后重新创建It在GCP中删除健康检查后返回。您可能已经检查了此问题,但请检查健康检查是否返回200,而服务端口80上没有任何重定向。请检查上面给出的建议,并让我们知道它是否对您有帮助。似乎没有解决问题,我已从头开始重新发布我的两个部署,然后在主端口上添加服务第一,当我发布服务更新时,仅更改选择器(应用程序名称)的结果相同,前3到5秒为02,当我切换回时,在这里大约30秒的时间内又有502。更新POST以显示完整的应用程序部署YAML(两个部署相同,仅更改映像).对于端口转发测试,两个部署的所有POD在“/”上返回200。您是否考虑过为第二个应用程序创建另一个服务,并更新入口目标,而不是更改选择器?我相信停机时间会少得多。
root@c55834fbdf1a:/# k get service/drupal-dummy-v1-service-https -o json
{
    "apiVersion": "v1",
    "kind": "Service",
    "metadata": {
        "annotations": {
            "beta.cloud.google.com/backend-config": "{\"ports\": {\"80\":\"drupal-dummy-v1-service-https\"}}",
            "cloud.google.com/neg": "{\"ingress\": true}",
            "cloud.google.com/neg-status": "{\"network_endpoint_groups\":{\"80\":\"k8s1-4846660e-e1-drupal-dummy-v1-service-https-80-36c11551\"},\"zones\":[\"europe-west3-a\",\"europe-west3-b\"]}",
            "meta.helm.sh/release-name": "drupal-dummy-v1-service",
            "meta.helm.sh/release-namespace": "e1"
        },
        "creationTimestamp": "2020-06-23T18:50:45Z",
        "labels": {
            "app": "drupal-dummy-v1-service",
            "app.kubernetes.io/managed-by": "Helm",
            "environment": "e1",
            "name": "drupal-dummy-v1-service",
            "type": "svc"
        },
        "name": "drupal-dummy-v1-service-https",
        "namespace": "e1",
        "resourceVersion": "3982781",
        "selfLink": "/api/v1/namespaces/e1/services/drupal-dummy-v1-service-https",
        "uid": "722d3a99-b582-11ea-9df2-42010a000006"
    },
    "spec": {
        "clusterIP": "172.16.103.181",
        "externalTrafficPolicy": "Cluster",
        "ports": [
            {
                "nodePort": 32396,
                "port": 80,
                "protocol": "TCP",
                "targetPort": 80
            }
        ],
        "selector": {
            "environment": "e1",
            "name": "drupal-dummy-v1-pod"
        },
        "sessionAffinity": "None",
        "type": "NodePort"
    },
    "status": {
        "loadBalancer": {}
    }
}
root@c55834fbdf1a:/# k get ingress.extensions/drupal-dummy-v1-service-https -o json
{
    "apiVersion": "extensions/v1beta1",
    "kind": "Ingress",
    "metadata": {
        "annotations": {
            "ingress.gcp.kubernetes.io/pre-shared-cert": "mcrt-a15e339b-6c3f-4f23-8f6b-688dc98b33a6,mcrt-f3a385de-0541-4b9c-8047-6dcfcbd4d74f",
            "ingress.kubernetes.io/backends": "{\"k8s1-4846660e-e1-drupal-dummy-v1-service-https-80-36c11551\":\"HEALTHY\"}",
            "ingress.kubernetes.io/forwarding-rule": "k8s-fw-e1-drupal-dummy-v1-service-https--4846660e8b9bd880",
            "ingress.kubernetes.io/https-forwarding-rule": "k8s-fws-e1-drupal-dummy-v1-service-https--4846660e8b9bd880",
            "ingress.kubernetes.io/https-target-proxy": "k8s-tps-e1-drupal-dummy-v1-service-https--4846660e8b9bd880",
            "ingress.kubernetes.io/ssl-cert": "mcrt-a15e339b-6c3f-4f23-8f6b-688dc98b33a6,mcrt-f3a385de-0541-4b9c-8047-6dcfcbd4d74f",
            "ingress.kubernetes.io/target-proxy": "k8s-tp-e1-drupal-dummy-v1-service-https--4846660e8b9bd880",
            "ingress.kubernetes.io/url-map": "k8s-um-e1-drupal-dummy-v1-service-https--4846660e8b9bd880",
            "kubernetes.io/ingress.global-static-ip-name": "gkxe-k1312-e1-drupal-dummy-v1",
            "meta.helm.sh/release-name": "drupal-dummy-v1-service",
            "meta.helm.sh/release-namespace": "e1",
            "networking.gke.io/managed-certificates": "dummydrupald8.cnes.fr,d8.syspod.fr",
            "nginx.ingress.kubernetes.io/rewrite-target": "/"
        },
        "creationTimestamp": "2020-06-23T18:50:45Z",
        "generation": 1,
        "labels": {
            "app": "drupal-dummy-v1-service",
            "app.kubernetes.io/managed-by": "Helm",
            "environment": "e1",
            "name": "drupal-dummy-v1-service",
            "type": "ingress"
        },
        "name": "drupal-dummy-v1-service-https",
        "namespace": "e1",
        "resourceVersion": "3978178",
        "selfLink": "/apis/extensions/v1beta1/namespaces/e1/ingresses/drupal-dummy-v1-service-https",
        "uid": "7237fc51-b582-11ea-9df2-42010a000006"
    },
    "spec": {
        "backend": {
            "serviceName": "drupal-dummy-v1-service-https",
            "servicePort": 80
        },
        "rules": [
            {
                "host": "dummydrupald8.cnes.fr",
                "http": {
                    "paths": [
                        {
                            "backend": {
                                "serviceName": "drupal-dummy-v1-service-https",
                                "servicePort": 80
                            }
                        }
                    ]
                }
            },
            {
                "host": "d8.syspod.fr",
                "http": {
                    "paths": [
                        {
                            "backend": {
                                "serviceName": "drupal-dummy-v1-service-https",
                                "servicePort": 80
                            }
                        }
                    ]
                }
            }
        ]
    },
    "status": {
        "loadBalancer": {
            "ingress": [
                {
                    "ip": "34.98.97.102"
                }
            ]
        }
    }
}
81s         Normal    Attach                    service/drupal-dummy-v1-service-https           Attach 1 network endpoint(s) (NEG "k8s1-4846660e-e1-drupal-dummy-v1-service-https-80-36c11551" in zone "europe-west3-b")
78s         Normal    Attach                    service/drupal-dummy-v1-service-https           Attach 1 network endpoint(s) (NEG "k8s1-4846660e-e1-drupal-dummy-v1-service-https-80-36c11551" in zone "europe-west3-a")
7s          Normal    Attach                    service/drupal-dummy-v1-service-https           Attach 1 network endpoint(s) (NEG "k8s1-4846660e-e1-drupal-dummy-v1-service-https-80-36c11551" in zone "europe-west3-a")
7s          Normal    Attach                    service/drupal-dummy-v1-service-https           Attach 1 network endpoint(s) (NEG "k8s1-4846660e-e1-drupal-dummy-v1-service-https-80-36c11551" in zone "europe-west3-b")