<p>I want to deploy a .NET Core app with NGINX reverse proxy on Azure Kubernetes Service. What is the best way to organize the pods and containers?</p>

<ol>
<li><p>Two single-container pods, one pod for nginx and one pod for the app (.net-core/kestrel), so each one can scale independently of the other</p></li>
<li><p>One multi-container pod, this single pod with two containers (one for nginx and one for the app)</p></li>
<li><p>One single-container pod, a single container running both the nginx and the .net app</p></li>
</ol>

<p>I would choose the 1st option, but I don't know if it is the right choice, would be great to know the the pros and cons of each option.</p>

<p>If I choose the 1st option, is it best to set affinity to put nginx pod in the same node that the app pod? Or anti-affinity so they deploy on different nodes? Or no affinity/anti-affinity at all?</p>

<p>The best practice for inbound traffic in Kubernetes is to use the <a href="https://kubernetes.io/docs/concepts/services-networking/ingress/" rel="nofollow noreferrer">Ingress</a> resource. This requires a bit of extra setup in AKS because there's no built-in ingress controller. You definitely don't want to do #2 because it's not flexible, and #3 is not possible to my knowledge.</p>

<p>The Kubernetes <code>Ingress</code> resource is a configuration file that manages reverse proxy rules for inbound cluster traffic. This allows you to surface multiple services as if they were a combined API.</p>

<p>To set up ingress, start by creating a public IP address in your auto-generated MC resource group:</p>

<pre><code>az network public-ip create `
    -g MC_rg-name_cluster-name_centralus `
    -n cluster-name-ingress-ip `
    -l centralus `
    --allocation-method static `
    --dns-name cluster-name-ingress
</code></pre>

<p>Now create an ingress controller. This is required to actually handle the inbound traffic from your public IP. It sits and listens to the Kubernetes API <code>Ingress</code> updates, and auto-generates an <code>nginx.conf</code> file.</p>

<pre><code># Note: you'll have to install Helm and its service account prior to running this. See my GitHub link below for more information
helm install stable/nginx-ingress `
    --name nginx-ingress `
    --namespace default `
    --set controller.service.loadBalancerIP=ip.from.above.result `
    --set controller.scope.enabled=true `
    --set controller.scope.namespace="default" `
    --set controller.replicaCount=3

kubectl get service nginx-ingress-controller -n default -w
</code></pre>

<p>Once that's provisioned, make sure to use this annotation on your <code>Ingress</code> resource: <code>kubernetes.io/ingress.class: nginx</code></p>

<p>If you'd like more information on how to set this up, please see <a href="https://github.com/brbarnett/hello-k8s" rel="nofollow noreferrer">this GitHub readme</a> I put together this week. I've also included TLS termination with <code>cert-manager</code>, also installed with Helm.</p>
