Mapping incoming port in kubernetes service to different port on docker container

Maiko Kuppe picture Maiko Kuppe · Sep 14, 2016 · Viewed 12.6k times · Source

This is the way I understand the flow in question:

  1. When requesting a kubernetes service (via http for example) I am using port 80.
  2. The request is forwarded to a pod (still on port 80)
  3. The port forwards the request to the (docker) container that exposes port 80
  4. The container handles the request

However my container exposes a different port, let's say 3000. How can make a port mapping like 80:3000 in step 2 or 3?

There are confusing options like targetport and hostport in the kubernetes docs which didn't help me. kubectl port-forward seems to forward only my local (development) machine's port to a specific pod for debugging.

These are the commands I use for setting up a service in the google cloud:

kubectl run test-app --image=eu.gcr.io/myproject/my_app --port=80
kubectl expose deployment test-app --type="LoadBalancer"

Answer

Maiko Kuppe picture Maiko Kuppe · Sep 14, 2016

I found that I needed to add some arguments to my second command:

kubectl expose deployment test-app --type="LoadBalancer" --target-port=3000 --port=80

This creates a service which directs incoming http traffic (on port 80) to its pods on port 3000.

A nicer way to do this whole thing is with yaml files service.yaml and deployment.yaml and calling

kubectl create -f deployment.yaml
kubectl create -f service.yaml

where the files have these contents

# deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: app-deployment
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: test-app
    spec:
      containers:
        - name: user-app
          image: eu.gcr.io/myproject/my_app
          ports:
            - containerPort: 3000

and

# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: app-service
spec:
  selector:
    app: test-app
  ports:
  - port: 80
    targetPort: 3000
  type: LoadBalancer

Note that the selector of the service must match the label of the deployment.