11

I am trying to run my custom marklogic image on my local minkube cluster. Marklogic exposes multiple different ports for management (8001) and for querying (8000). Is there a way to expose multiple ports of a container on kubernetes?

This is what I tried:

# try to run container with multiple ports exposed. 
kubectl run ml3 --image=marklogic-initial-install:9.0-3.1 --port=8001 --port 8002
# create service to expose the container
kubectl expose deployment ml3 --type=LoadBalancer
# use qinikube to open the exposed ports 
minikube service ml3

Is this possible at all?

This section in the kubernetes docs suggests that it is indeed possible:

https://kubernetes.io/docs/concepts/services-networking/service/#multi-port-services

But it only talks about how to configure services to expose multiple ports, it does not say how to achieve this for containers -- which should be a prerequisite.

Thanks!

user152468
  • 3,202
  • 6
  • 27
  • 57

2 Answers2

17

With kubectl expose, you can specify multiple ports by separating them with commas:

    --port=8001,8002
user3993923923
  • 171
  • 1
  • 2
  • I think this is the simplest answer to the question. – Anurag Apr 27 '20 at 06:26
  • If you need to expose ports from multiple containers in one command, you can use a tool like [concurrently](https://github.com/open-cli-tools/concurrently). (that's what I use) – Venryx Dec 11 '21 at 06:27
  • This worked! But I need multiple ports to multiple target ports and this didn't work :( --target-port doesn't accept multiple ports – bentzy Aug 29 '22 at 14:33
15

From what I see in your command, you would need to specify in kubectl expose which of the two ports this service will work with. If there are two ports that perform different operations, then it makes sense to have two services (otherwise you would not know which of the two ports would be used in each request). So, my advice would be to execute two kubectl expose commands (in the --port part you can put whatever you wish):

kubectl expose deployment ml3 --type=LoadBalancer --name=management --port=80 --target-port=8000
kubectl expose deployment ml3 --type=LoadBalancer --name=query --port=80 --target-port=8001

So, you would have one service for querying and another for management.

Another alternative would be using one service with two different ports, but I am not sure if this is doable using kubectl expose. It would make sense in this case to use a yaml file:

kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  selector:
    app: MyApp <-- use a proper selector for your pods
  ports:
  - name: management 
    protocol: TCP
    port: 80
    targetPort: 8000
  - name: query 
    protocol: TCP
    port: 81
    targetPort: 8001
Javier Salmeron
  • 8,365
  • 2
  • 28
  • 23
  • Sounds good. But don't I also have to specify both ports when creating the container? Will it work with multiple --port arguments? – user152468 Dec 08 '17 at 16:20
  • when exposing multiple ports you would have to give each exposed port a name. This should be added to the answer. – user152468 Dec 08 '17 at 16:34
  • Answer updated. Regarding specifying the ports when creating the container, it looks like kubectl run will only accept one, according to the documentation. – Javier Salmeron Dec 08 '17 at 17:10