Kubernetes Ingress (GCE) продолжает возвращать ошибку 502

Я пытаюсь настроить Ingress в GCE Kubernetes. Но когда я посещаю IP-адрес и комбинацию путей, определенные в Ingress, я продолжаю получать следующую ошибку 502:

Ошибка Ingress 502


Вот что я получаю при запуске: kubectl describe ing --namespace dpl-staging

Name:           dpl-identity
Namespace:      dpl-staging
Address:        35.186.221.153
Default backend:    default-http-backend:80 (10.0.8.5:8080)
TLS:
  dpl-identity terminates
Rules:
  Host  Path    Backends
  ----  ----    --------
  *
        /api/identity/*     dpl-identity:4000 (<none>)
Annotations:
  https-forwarding-rule:    k8s-fws-dpl-staging-dpl-identity--5fc40252fadea594
  https-target-proxy:       k8s-tps-dpl-staging-dpl-identity--5fc40252fadea594
  url-map:          k8s-um-dpl-staging-dpl-identity--5fc40252fadea594
  backends:         {"k8s-be-31962--5fc40252fadea594":"HEALTHY","k8s-be-32396--5fc40252fadea594":"UNHEALTHY"}
Events:
  FirstSeen LastSeen    Count   From                SubObjectPath   Type        Reason  Message
  --------- --------    -----   ----                -------------   --------    ------  -------
  15m       15m     1   {loadbalancer-controller }          Normal      ADD dpl-staging/dpl-identity
  15m       15m     1   {loadbalancer-controller }          Normal      CREATE  ip: 35.186.221.153
  15m       6m      4   {loadbalancer-controller }          Normal      Service no user specified default backend, using system default

Я думаю, что проблема dpl-identity:4000 (<none>). Должен ли я видеть IP-адрес службы dpl-identity вместо <none>?

Вот мое описание сервиса: kubectl describe svc --namespace dpl-staging

Name:           dpl-identity
Namespace:      dpl-staging
Labels:         app=dpl-identity
Selector:       app=dpl-identity
Type:           NodePort
IP:             10.3.254.194
Port:           http    4000/TCP
NodePort:       http    32396/TCP
Endpoints:      10.0.2.29:8000,10.0.2.30:8000
Session Affinity:   None
No events.

Кроме того, вот результат выполнения: kubectl describe ep -n dpl-staging dpl-identity

Name:       dpl-identity
Namespace:  dpl-staging
Labels:     app=dpl-identity
Subsets:
  Addresses:        10.0.2.29,10.0.2.30
  NotReadyAddresses:    <none>
  Ports:
    Name    Port    Protocol
    ----    ----    --------
    http    8000    TCP

No events.

Вот мой файл deployment.yaml:

apiVersion: v1
kind: Secret
metadata:
  namespace: dpl-staging
  name: dpl-identity
type: Opaque
data:
  tls.key: <base64 key>
  tls.crt: <base64 crt>
---
apiVersion: v1
kind: Service
metadata:
  namespace: dpl-staging
  name: dpl-identity
  labels:
    app: dpl-identity
spec:
  type: NodePort
  ports:
    - port: 4000
      targetPort: 8000
      protocol: TCP
      name: http
  selector:
    app: dpl-identity
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  namespace: dpl-staging
  name: dpl-identity
  labels:
    app: dpl-identity
  annotations:
    kubernetes.io/ingress.allow-http: "false"
spec:
  tls:
  - secretName: dpl-identity
  rules:
  - http:
      paths:
        - path: /api/identity/*
          backend:
            serviceName: dpl-identity
            servicePort: 4000
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  namespace: dpl-staging
  name: dpl-identity
kind: Ingress
metadata:
  namespace: dpl-staging
  name: dpl-identity
  labels:
    app: dpl-identity
  annotations:
    kubernetes.io/ingress.allow-http: "false"
spec:
  tls:
  - secretName: dpl-identity
  rules:
  - http:
      paths:
        - path: /api/identity/*
          backend:
            serviceName: dpl-identity
            servicePort: 4000
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  namespace: dpl-staging
  name: dpl-identity
  labels:
    app: dpl-identity
spec:
  replicas: 2
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: dpl-identity
    spec:
      containers:
      - image: gcr.io/munpat-container-engine/dpl/identity:0.4.9
        name: dpl-identity
        ports:
        - containerPort: 8000
          name: http
        volumeMounts:
        - name: dpl-identity
          mountPath: /data
      volumes:
      - name: dpl-identity
        secret:
          secretName: dpl-identity

Ответ 1

Ваш бэкэнд k8s-be-32396--5fc40252fadea594 отображается как "UNHEALTHY".

Ingress не будет перенаправлять трафик, если бэкэнд UNHEALTHY, это приведет к ошибке 502, которую вы видите.

Он будет отмечен как НЕСОВЕРШЕННО, потому что он не проходит проверку работоспособности, вы можете проверить настройку проверки работоспособности для k8s-be-32396--5fc40252fadea594, чтобы узнать, подходят ли они для вашего контейнера, может быть опрос URI или порт, который не возвращает ответ 200. Эти параметры можно найти в разделе "Расчет двигателя" > "Проверки работоспособности".

Если они верны, есть много шагов между вашим браузером и контейнером, который может неправильно передавать трафик, вы можете попробовать kubectl exec -it PODID -- bash (или пепел, если используете Alpine), а затем попробуйте скруглить localhost, чтобы узнать, контейнер отвечает так, как ожидалось, если он есть, и проверки работоспособности также настроены правильно, то это сузило проблему, вероятно, с вашей службой, вы могли бы попытаться изменить службу из типа NodePort на LoadBalancer и посмотреть, IP-адрес службы непосредственно из вашего браузера работает.

Ответ 2

У меня была та же проблема, и она сохранялась после того, как я включил livenessProbe, а также readinessPorbe. Это оказалось связано с базовым auth. Я добавил базовый auth к livenessProbe и readinessPorbe, но, оказалось, у балансира нагрузки GCE HTTP (S) нет опции конфигурации для этого.

Кажется, есть еще несколько других проблем, например. установив контейнерный порт на 8080, а служебный порт до 80 не работал с контроллером входа GKE (хотя я бы не стал четко указывать, в чем проблема). И в целом, мне кажется, что очень мало видимости, и запуск собственного входного контейнера - лучший вариант в отношении видимости.

Я выбрал Traefik для моего проекта, он работал из коробки, и я хотел бы включить Let Encrypt интеграции. Единственное изменение, которое я должен был внести в манифесты Traefik, состояло в том, чтобы настроить объект сервиса на запрет доступа к пользовательскому интерфейсу из-за пределов кластера и выставить мое приложение через внешний балансировщик нагрузки (GCE TCP LB). Кроме того, Traefik является более родным для Kubernetes. Я попробовал Heptio Contour, но что-то не получилось из коробки (в следующий раз он выйдет в следующий раз, когда выйдет новая версия).

Ответ 3

Проблема действительно является проверкой работоспособности и показалась "случайной" для моих приложений, где я использовал виртуальные хосты на основе имени для обратного прокси-запроса от входа через домены до двух отдельных бэкэнд-сервисов. Оба были защищены с помощью Lets Encrypt и kube-lego. Мое решение состояло в том, чтобы стандартизировать путь для проверок работоспособности для всех служб, совместно использующих вход, и объявить конфигурации readinessProbe и livenessProbe в моем файле deployment.yml.

Я столкнулся с этой проблемой с облачным кластером Google node version 1.7.8 и нашел эту проблему, которая очень напоминала то, что я испытал:  * https://github.com/jetstack/kube-lego/issues/27

Я использую gce и kube-lego, а мои проверки работоспособности службы backend на / и kube-lego включены /healthz. Похоже, что разные пути для проверок работоспособности с помощью gce ingress могут быть причиной, поэтому может быть полезно обновить бэкэнд-услуги, чтобы они соответствовали шаблону /healthz, поэтому все они одинаковы (или как один комментатор в Github, заявили, что они обновили kube-lego для прохождения на /).

Ответ 4

У меня была такая же проблема. Оказывается, мне пришлось подождать несколько минут до входа, чтобы проверить работоспособность службы. Если кто-то идет к тому же и выполнил все шаги, такие как readinessProbe и linvenessProbe, просто убедитесь, что ваш вход указывает на службу, которая является либо NodePort, и подождите несколько минут, пока желтый предупреждающий значок не превратится в зеленый. Кроме того, проверьте журнал на StackDriver, чтобы лучше понять, что происходит. Мои readinessProbe и livenessProbe находятся на /login для класса gce. Поэтому я не думаю, что это должно быть на /healthz.

Ответ 6

Я решил проблему

  1. Удалить сервис из определения входа
  2. Развернуть ingress kubectl apply -f ingress.yaml
  3. Добавьте сервис к определению входа
  4. Разверните вход снова

По сути, я последовал совету Роя и попытался выключить его и снова включить.