<p>I'm trying to use an <code>Ingress</code> and <code>ExternalName</code> Service in Kubernetes to route traffic to an external storage service (DigitalOcean Spaces) - but no matter what I try, I get some form of http error.</p>
<p>Things I've tried:</p>
<ul>
<li><a href="https://github.com/kubernetes/ingress-nginx/pull/629#issue-116679227" rel="nofollow noreferrer">https://github.com/kubernetes/ingress-nginx/pull/629#issue-116679227</a> (Error: 404 Not Found, nginx)</li>
<li><a href="https://github.com/kubernetes/ingress-nginx/issues/1809" rel="nofollow noreferrer">https://github.com/kubernetes/ingress-nginx/issues/1809</a> (Error: 502 Bad Gateway, nginx)</li>
<li>A fair bit of other tinkering which has been lost to time.</li>
</ul>
<p>How do I configure a K8s Ingress/Service to direct ingress requests from <code>example.com/static</code> to a storage bucket (e.g. <code>&lt;zone&gt;.digitaloceanspaces.com/&lt;bucket-name&gt;/&lt;path&gt;/&lt;object&gt;</code>)?</p>

1f928
<p>It looks like some of the resources I was able to find were simply outdated. The following solution works as of Kubernetes v1.21.4.</p>
<p><strong>Important Notes</strong>:</p>
<ul>
<li>All <code>Ingress</code> annotations are <em>required</em>:
<ul>
<li><code>kubernetes.io/ingress.class: nginx</code> - necessary to engage Nginx ingress controller.</li>
<li><code>nginx.ingress.kubernetes.io/backend-protocol: HTTPS</code> - necessary to maintain HTTPS traffic to service (<a href="https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#backend-protocol" rel="nofollow noreferrer">this replaces <code>/secure-backends</code> in older versions</a>).</li>
<li><code>nginx.ingress.kubernetes.io/upstream-vhost</code> - must match service <code>externalName</code>, removes hostname from request path (e.g. if this is missing and being tested through localhost, will likely encounter error: &quot;No such bucket: localhost&quot;).</li>
<li><code>nginx.ingress.kubernetes.io/rewrite-target</code> - passes matched asset URL path through to service.</li>
</ul>
</li>
<li>The <code>path.service.port.number</code> in the Ingress definition must match whatever port the <code>ExternalName</code> service expects (443 in the case of our HTTPS traffic).</li>
</ul>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: v1
kind: Service
metadata:
  name: do-bucket-service
spec:
  type: ExternalName
  externalName: &lt;zone&gt;.digitaloceanspaces.com

---

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: do-bucket-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/backend-protocol: HTTPS
    nginx.ingress.kubernetes.io/rewrite-target: /&lt;bucket&gt;/$2
    nginx.ingress.kubernetes.io/upstream-vhost: &lt;zone&gt;.digitaloceanspaces.com
spec:
  rules:
  - http: 
      paths:
      - path: /path/to/static/assets(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: do-bucket-service
            port:
              number: 443
</code></pre>
