How can I run two containers that listen on the same port on kubernetes?

8/9/2017

This is my config:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  replicas: 1
  selector:
    matchLabels:
      app: wordpress
  template:
    metadata:
      labels:
        app: wordpress
    spec:
      terminationGracePeriodSeconds: 30
      containers:
        - image: wordpress:latest
          name: wordpress
          imagePullPolicy: "Always"
          env:
            - name: WORDPRESS_HOST
              value: localhost
            - name: WORDPRESS_DB_USERNAME
              valueFrom:
                secretKeyRef:
                  name: cloudsql-db-credentials
                  key: username
          volumeMounts:
            - name: wordpress-persistent-storage
              mountPath: /var/www/html
        - image: nginx:latest
          name: nginx
          ports:
            - containerPort: 80
              name: nginx
        - image: gcr.io/cloudsql-docker/gce-proxy:1.09
          name: cloudsql-proxy
          command: ["/cloud_sql_proxy", "--dir=/cloudsql",
                    "-instances=abcxyz:europe-west1:wordpressdb=tcp:3306",
                    "-credential_file=/secrets/cloudsql/credentials.json"]
          volumeMounts:
            - name: cloudsql-instance-credentials
              mountPath: /secrets/cloudsql
              readOnly: true
            - name: ssl-certs
              mountPath: /etc/ssl/certs
            - name: cloudsql
              mountPath: /cloudsql
      volumes:
        - name: wordpress-persistent-storage
          gcePersistentDisk:
            pdName: wordpress-disk
            fsType: ext4

        - name: cloudsql-instance-credentials
          secret:
            secretName: cloudsql-instance-credentials
        - name: ssl-certs
          hostPath:
            path: /etc/ssl/certs
        - name: cloudsql
          emptyDir:

I'd like to expose Nginx's port 80 only (to act as a load balancer). However it fails to start, the logs from the container:

2017/08/09 14:39:50 [emerg] 1#1: bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
2017/08/09 14:39:50 [emerg] 1#1: bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
2017/08/09 14:39:50 [emerg] 1#1: bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
2017/08/09 14:39:50 [emerg] 1#1: bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
2017/08/09 14:39:50 [emerg] 1#1: bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
2017/08/09 14:39:50 [emerg] 1#1: still could not bind()
nginx: [emerg] still could not bind()

I'm guessing this is due to the Wordpress container is already listening on port 80.

I would have assumed they would be independent and not have any port conflicts. How can I resolve this issue?

-- Chris Stryczynski
google-cloud-platform
kubernetes

1 Answer

8/9/2017

I would have assumed they would be independent and not have any port conflicts. How can I resolve this issue?

Across Pods that's true, but within a Pod, all containers share the same networking namespace -- that's part of what makes them a Pod. To accomplish what you said about "to act as a load balancer", deploy the nginx Pod separately, and point its upstream at a Service you will create for the wordpress Pod. Or, of course, you can also relocate the port the wordpress container is listening on, but the following bears consideration before doing that.

Unless your "load balancer" is genuinely going to take load into account, and not just be a round-robin LB, the very act of creating a Service will naturally disperse traffic across all the Pods that match the selector in the Service.

-- mdaniel
Source: StackOverflow