<p>I've created a Kubernetes cluster on Google Cloud and even though the application is running properly (which I've checked running requests inside the cluster) it seems that the NEG health check is not working properly. Any ideas on the cause?</p>
<p>I've tried to change the service from NodePort to LoadBalancer, different ways of adding annotations to the service. I was thinking that perhaps it might be related to the https requirement in the django side.</p>
<p><a href="https://i.stack.imgur.com/G29KX.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/G29KX.png" alt="enter image description here" /></a></p>
<p><a href="https://i.stack.imgur.com/wEbwG.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/wEbwG.png" alt="enter image description here" /></a></p>
<pre><code># [START kubernetes_deployment]
apiVersion: apps/v1
kind: Deployment
metadata:
  name: moner-app
  labels:
    app: moner-app
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: moner-app
  template:
    metadata:
      labels:
        app: moner-app
    spec:
      containers:
      - name: moner-core-container
        image: my-template
        imagePullPolicy: Always
        resources:
          requests:
            memory: &quot;128Mi&quot;
          limits:
            memory: &quot;512Mi&quot;
        startupProbe:
          httpGet:
            path: /ht/
            port: 5000
            httpHeaders:
              - name: &quot;X-Forwarded-Proto&quot;
                value: &quot;https&quot;
          failureThreshold: 30
          timeoutSeconds: 10
          periodSeconds: 10
          initialDelaySeconds: 90
        readinessProbe:
            initialDelaySeconds: 120
            httpGet:
              path: &quot;/ht/&quot;
              port: 5000
              httpHeaders:
              - name: &quot;X-Forwarded-Proto&quot;
                value: &quot;https&quot;
            periodSeconds: 10
            failureThreshold: 3
            timeoutSeconds: 10
        livenessProbe:
          initialDelaySeconds: 30
          failureThreshold: 3
          periodSeconds: 30
          timeoutSeconds: 10
          httpGet:
            path: &quot;/ht/&quot;
            port: 5000
            httpHeaders:
              - name: &quot;X-Forwarded-Proto&quot;
                value: &quot;https&quot;
        volumeMounts:
          - name: cloudstorage-credentials
            mountPath: /secrets/cloudstorage
            readOnly: true
        env:
            # [START_secrets]
            - name: THIS_POD_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            - name: GRACEFUL_TIMEOUT
              value: '120'
            - name: GUNICORN_HARD_TIMEOUT
              value: '90'
            - name: DJANGO_ALLOWED_HOSTS
              value: '*,$(THIS_POD_IP),0.0.0.0'
        ports:
        - containerPort: 5000
        args: [&quot;/start&quot;]
        
      # [START proxy_container]
      - image: gcr.io/cloudsql-docker/gce-proxy:1.16
        name: cloudsql-proxy
        command: [&quot;/cloud_sql_proxy&quot;, &quot;--dir=/cloudsql&quot;,
                  &quot;-instances=moner-dev:us-east1:core-db=tcp:5432&quot;,
                  &quot;-credential_file=/secrets/cloudsql/credentials.json&quot;]
        resources:
          requests:
            memory: &quot;64Mi&quot;
          limits:
            memory: &quot;128Mi&quot;
        volumeMounts:
          - name: cloudsql-oauth-credentials
            mountPath: /secrets/cloudsql
            readOnly: true
          - name: ssl-certs
            mountPath: /etc/ssl/certs
          - name: cloudsql
            mountPath: /cloudsql
      # [END proxy_container]
      # [START volumes]
      volumes:
        - name: cloudsql-oauth-credentials
          secret:
            secretName: cloudsql-oauth-credentials
        - name: ssl-certs
          hostPath:
            path: /etc/ssl/certs
        - name: cloudsql
          emptyDir: {}
        - name: cloudstorage-credentials
          secret:
            secretName: cloudstorage-credentials
      # [END volumes]
# [END kubernetes_deployment]

---

# [START service]
apiVersion: v1
kind: Service
metadata:
  name: moner-svc
  annotations:
    cloud.google.com/neg: '{&quot;ingress&quot;: true, &quot;exposed_ports&quot;: {&quot;5000&quot;:{}}}' # Creates an NEG after an Ingress is created
    cloud.google.com/backend-config: '{&quot;default&quot;: &quot;moner-backendconfig&quot;}'
  labels:
    app: moner-svc
spec:
  type: NodePort
  ports:
  - name: moner-core-http
    port: 5000
    protocol: TCP
    targetPort: 5000
  selector:
    app: moner-app
# [END service]

---

# [START certificates_setup]
apiVersion: networking.gke.io/v1
kind: ManagedCertificate
metadata:
  name: managed-cert
spec:
  domains:
    - domain.com
    - app.domain.com
# [END certificates_setup]

---

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: moner-backendconfig
spec:
  customRequestHeaders:
      headers:
      - &quot;X-Forwarded-Proto:https&quot;
  healthCheck:
    checkIntervalSec: 15
    port: 5000
    type: HTTP
    requestPath: /ht/


---

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: managed-cert-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: moner-ssl
    networking.gke.io/managed-certificates: managed-cert
    kubernetes.io/ingress.class: &quot;gce&quot;
spec:
  defaultBackend:
    service:
      name: moner-svc
      port: 
        name: moner-core-http
</code></pre>

<p>Apparently, you didn’t have a GCP firewall rule to allow traffic on port 5000 to your GKE nodes. <a href="https://cloud.google.com/vpc/docs/using-firewalls#creating_firewall_rules" rel="nofollow noreferrer">Creating an ingress firewall rule</a> with IP range - 0.0.0.0/0 and port - TCP 5000  targeted to your GKE nodes could allow your setup to work even with port 5000.</p>
