Force_https не работает с GCP Ingress

У меня есть экземпляр Kubernetes в GCP. Всё кажется в порядке, но somehow force_https не принуждает к редиректу, и сайт всё ещё доступен по http://.

Мое текущее решение — добавить этот блок в app.yml:

    - replace:
        filename: /etc/nginx/conf.d/discourse.conf
        from: '    add_header ETag "";'
        to: |
                  add_header ETag "";
                  if ($thescheme = "http") {
                    return 301 https://$host$request_uri;
                  }

(И я бы с удовольствием понял, как заставить pups правильно отступать вставленные строки, но это уже отступление.)

После этого изменения контроллер Ingress, похоже, перестал обслуживать сайт, хотя он работал и корректно перенаправлял трафик как минимум некоторое время.

Очевидно, это относится к категории unsupported-install, но если у кого-то есть идея, куда посмотреть дальше, буду признателен.

Вы используете HTTP-балансировщик нагрузки или TCP-балансировщик нагрузки? Если HTTP, то протокол, видимый на входе, может быть помещён в нестандартный заголовок, который Discourse не ищет.

Похоже, что полностью управляемая настройка выглядит следующим образом:

$ gcloud compute addresses create discourse-ip-address --global
#                                 ^~~~~~~~~~~~~~~~~~~~ пользовательское имя
# ПРЕДУПРЕЖДЕНИЕ: резервирование IP-адреса без его использования влечет за собой штраф в размере 0,010 USD/час
---
apiVersion: networking.gke.io/v1beta1
kind: ManagedCertificate
metadata:
  name: discourse-cert
spec:
  domains:
    - discourse.example.com  # настройте под себя
---
apiVersion: extensions/v1beta1
# если версия v1.14 или новее:
# apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: discourse-web-ingress
  annotations:
    networking.gke.io/managed-certificates: discourse-cert
    kubernetes.io/ingress.global-static-ip-name: discourse-ip-address
spec:
  backend:
    serviceName: discourse-web  # убедитесь, что это верно
    servicePort: 80

источники:

Спасибо большое, @riking! Да, похоже, проблема в балансировщике нагрузки. Я думаю, что ingress работает нормально (и теперь у меня есть представление о том, что между ними есть разница). Я переключился на настройку, которую вы показали, и получаю те же результаты, что и с более сложной конфигурацией. Думаю, следующим шагом будет разобраться с tcpdump и посмотреть, что находится в этих заголовках. . .

РЕДАКТИРОВАНИЕ: Похоже, это должно работать. Вот что я вижу:

GET /thisisatest HTTP/1.1
User-Agent: Wget/1.19.4 (linux-gnu)
Accept: */*
Accept-Encoding: identity
Host: community.example.com
X-Cloud-Trace-Context: 72c9f7219e6b541cad01153c52fb92c5/13509441707361831434
Via: 1.1 google
X-Forwarded-For: MY-IP-ADDRESS, INGRESS-IP
X-Forwarded-Proto: http
Connection: Keep-Alive

У меня есть set_real_ip_from с IP-адресом ingress (и IP-адреса правильно записываются в логи).

@pfaffman Я могу помочь с этим — я работаю с GCP и уже решал эту проблему ранее. Однако у меня занято несколько часов, но если вы сможете прислать мне конфигурацию вашего балансировщика нагрузки (вместе с настройками проверки работоспособности) сюда или в личные сообщения, я постараюсь найти проблему.

PS: Работают как TCP, так и HTTP.

Огромное спасибо, @p16!

Что ж, вот проверка работоспособности. Я изменил путь на /srv/status, но всё ещё вижу, как «GoogleHC/1.0» обращается к /.

Спасибо, отображается ли бэкенд как работоспособный в балансировщике нагрузки? Пожалуйста, также добавьте www.yoursite.com в хост (в разделе «ещё»).

Кроме того, вот что я добавляю в свой app.yml:

  after_web_config:  
    - replace:  
       filename: "/etc/nginx/conf.d/discourse.conf"  
       from: /server.+{/  
       to: |  
         server {  
           if ($http_x_forwarded_proto = 'http') {  
            return 301 https://$host$request_uri;  
           }  

Это не понадобится надолго, так как Google в этом квартале добавит редиректор с http на https.

Да. Похоже, сейчас всё работает! Я, наверное, немного запутался с магическим портом 30182, но, полагаю, это какая-то магия k8s, которую я разберу в другой раз.
Попробую ваш блок after_web_config:. Он кажется немного более чистым по сравнению с тем, что я делал.

Огромное спасибо.