<p>My aim is to route local HTTP service that is not in Kubernetes through Kubernetes Ingress.</p>

<p>The configuration below works so I'm able to open <code>http://owncloud.example.com</code> or <code>https://owncloud.example.com</code> from outside.</p>

<p>Here is Kubernetes configuration:</p>

<pre><code>apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: owncloud
  namespace: default
  annotations:
    kubernetes.io/ingress.class: nginx
    ingress.kubernetes.io/ssl-redirect: "true" 
    ingress.kubernetes.io/secure-backends: "true"    
    ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/server-snippet:
      location ~ ^/(.*) {
        proxy_pass http://192.168.250.100:8260/$1;
        proxy_set_header Host $host;
      }
      location ~ ^/api(.*) {
        proxy_pass http://192.168.250.100:8261/$1;
        proxy_set_header Host $host;
      }
spec:
  tls:
  - hosts:
    - owncloud.example.com
    secretName: owncloud-tls

  rules:
  - host: owncloud.example.com
</code></pre>

<p>The issue is that I see some strange errors in browser's Javascript console related to "meta". They are related with deep Javascript code. So unfortunately, there is no useful log. The website produces weird behaviour at few places while locally it works fine.
So it seems this is something to do with Kubernetes Ingress.</p>

<p>Previously I used plain Nginx connected to outside and this worked great:</p>

<pre><code>location / {
  proxy_pass http://192.168.250.100:8260/
}
</code></pre>

<p>If I add exactly the same block to <code>server-snippet</code>, website doesn't load at all. It catches default Ingress.</p>

<p>How to properly <code>proxy_pass</code> traffic from Kubernetes Ingress to another service which is running outside of Kubernetes? So it doesn't miss something through proxy.</p>

<p>Would be nice to have exploration on <code>server-snippet</code> to understand how Kubernetes Ingress configuration is different from standard Nginx usage. </p>

<p>If using different options, I was not able to find a solution to proxy_pass to different http when accessing path <code>/api</code>.</p>

<p><strong>----------------- Updates -----------------</strong></p>

<p>I have collected all issues for comparison.</p>

<p><strong>Locally - working one</strong>:</p>

<p><a href="https://i.stack.imgur.com/astqg.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/astqg.png" alt="enter image description here"></a></p>

<p>If I click on <code>manifest.json</code>, it shows "Nothing to preview". If I use <code>wget</code> to download that json, I can see <code>&lt;!DOCTYPE html&gt;</code> in this first line. It's HTML file downloaded. But I can confirm this local version is working perfectly for years. So this screenshot is just to know how it looks when it works.</p>

<p><strong>Through Ingress - not working</strong>:</p>

<p>I logged in successfully. Didn't spot anything weird from user experience, but issue exists:</p>

<p><a href="https://i.stack.imgur.com/r8q7K.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/r8q7K.png" alt="enter image description here"></a></p>

<p>Tried to log out. I'm not able to do it. It throws Owncloud specific error "Access forbidden
CSRF check failed" and on the console I see this:</p>

<p><a href="https://i.stack.imgur.com/WNhR9.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/WNhR9.png" alt="enter image description here"></a></p>

<p>If I go to <a href="https://owncloud.example.com/login" rel="nofollow noreferrer">https://owncloud.example.com/login</a> page on purpose:</p>

<p><a href="https://i.stack.imgur.com/PNQhr.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/PNQhr.png" alt="enter image description here"></a> </p>

<p>If I try to access files on this Owncloud, it also fails with <code>400</code>:</p>

<p><a href="https://i.stack.imgur.com/0cBpR.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/0cBpR.png" alt="enter image description here"></a></p>

<p>If I add additional <code>annotations</code>:</p>

<pre><code>  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/server-snippet: |
      location ~ ^/?(.*) {
        proxy_pass http://192.168.250.100:8260/$1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
      }
    # Owncloud tuning
    nginx.ingress.kubernetes.io/proxy-body-size: "500000m"
    nginx.ingress.kubernetes.io/proxy-max-temp-file-size: "500000m"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "36000s"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "36000s"
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "36000s"
    nginx.ingress.kubernetes.io/proxy-buffering: "off"
    nginx.ingress.kubernetes.io/proxy-redirect-from: "off"
    nginx.ingress.kubernetes.io/connection-proxy-header: "keep-alive"
</code></pre>

<p><a href="https://i.stack.imgur.com/pIMmF.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/pIMmF.jpg" alt="enter image description here"></a></p>

<p><strong>Summarise</strong></p>

<p>No errors on application side. So first thing that comes to my mind is <code>/logout</code> behaviour. I get <code>412</code> HTTP code which means: <code>Precondition Failed client error response code indicates that access to the target resource has been denied</code> and <code>400</code> bad request error.</p>

<p>Any expertise to catch this issue?</p>

<p>Many thanks</p>

laimison
<p>Finally found a working solution.</p>

<p>I just corrected <code>location</code> and <code>proxy_pass</code> to solve the root cause.</p>

<p>So if you have some local HTTP service which is outside of Kubernetes cluster and you want to serve this through Ingress, you just need this:</p>

<pre><code>kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  name: owncloud
  namespace: default
  annotations:
    kubernetes.io/ingress.class: nginx
    ingress.kubernetes.io/ssl-redirect: "true"
    ingress.kubernetes.io/secure-backends: "true"
    ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/server-snippet: |
      location ~ "^/(.*)" {
        proxy_pass http://192.168.250.100:8260;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto https;

        # Owncloud tuning
        proxy_max_temp_file_size 0;
        client_max_body_size 500000m;
        proxy_read_timeout 36000s;
        proxy_send_timeout 36000s;
        proxy_connect_timeout 36000s;
        proxy_buffering off;
        proxy_redirect off;
        proxy_set_header Connection "Keep-Alive";
      }
    # Owncloud tuning
    nginx.ingress.kubernetes.io/proxy-max-temp-file-size: "0"
    nginx.ingress.kubernetes.io/proxy-body-size: "500000m"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "36000s"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "36000s"
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "36000s"
    nginx.ingress.kubernetes.io/proxy-buffering: "off"
    nginx.ingress.kubernetes.io/proxy-redirect-from: "off"
    nginx.ingress.kubernetes.io/connection-proxy-header: "keep-alive"
spec:
  rules:
  - host: owncloud.example.com
  tls:
  - hosts:
    - owncloud.example.com
    secretName: owncloud-example-tls
</code></pre>

<ul>
<li><p>Remove Owncloud tuning block if you have another service</p></li>
<li><p>Remove <code>ssl</code>, <code>secure</code>, <code>X-Forwarded-Proto</code> and <code>tls:</code> bits if you don't need HTTPS</p></li>
</ul>

<p>You can add more <code>location</code> blocks such as <code>~ "^/api/(.*)"</code> so it works as normal Nginx.</p>

<p>In my case it was useful to route some local Docker Compose and old fashion services to outside through Kubernetes Ingress.</p>

<p>P.S. Don't forget to vote for @mWatney comment if you came here to solve Owncloud CSRF error.</p>
