Nginx config for django app in kubernetes cluster

4/30/2018

I'm having difficulty creating an nginx configuration file for a django app deployed in kubernetes. Nginx and app are two separate containers within the same cluster. From what I understand containers can communicate with each other via 127.0.0.1:XX and via hostnames. I'm using minikube for this. My app container is built from this file:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: website
  labels:
    name: website
spec:
  template:
    metadata:
      labels:
        name: website
    spec:
      containers:
        - name: website
          image: killabien/web
          ports:
            - containerPort: 8000
---
apiVersion: v1
kind: Service
metadata:
  name: website
  labels:
    name: website
spec:
  type: LoadBalancer
  ports:
    - port: 8000
      targetPort: 8000
  selector:
    name: website

And nginx from this:

apiVersion: v1
kind: Service
metadata:
  name: frontend
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  selector:
    app: website
    tier: frontend
  type: LoadBalancer
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: frontend
spec:
  template:
    metadata:
      labels:
        app: website
        tier: frontend
    spec:
      containers:
        - image: killabien/nginx
          name: nginx

I can access the application itself(served without static files) but when I try to reach nginx I get 502 Bad Gateway error. Here is the nginx config file:

upstream website {
    server 127.0.0.1:8000;

}
server {
    listen 80;
    location /static {
        alias /www/davidbien/static;
    }

   location / {
        proxy_pass http://website;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     }
}

I tried replacing 127.0.0.1:8000 with the container name(website) and localhost:8000 but nothing changed. What am I doing wrong?

-- davidb
django
kubernetes
nginx

1 Answer

4/30/2018

For your particular question:

  • containers can communicate with each other over localhost reference (127.0.0.1) only if they are two containers on the same pod, which is not your case - hence 503.
  • containers that are in different pods (as in your example) but share same namespace (say, default) can communicate with each other using service name (in your case: website)
  • containers that are in different namespaces can communicate using FQDN as in service-name.namespace-name.svc.cluster.local (in your case website.default.svc.cluster.local).

Now, philosophy of k8s is that pod is unit of deployment and container is unit of packaging. IF your nginx and website are always scaled together, than it comes to reason to put them both in same pod and communicate over localhost as if they are two processes on same machine. IF your frontend is going to handle multiple websites and they scale separately then option 2 or 3 (communication over service name or FQDN) is in order.

-- Const
Source: StackOverflow