How to expose kubernetes pod to outside IP?

3/12/2020

I have a kubernetes file that looks like this:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: <some_name>
spec:
  replicas: 1
  template:
    spec:
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      containers:
        - image: <some_image>
          imagePullPolicy: Always
          name: <some_name>
          env:
          - name: ES_HOST
            value: blahblah.us-west-2.es.amazonaws.com
          - name: ES_PORT
            value: "443"
          - name: DATALOADER_QUEUE
            value: some_sqs_queue
          - name: AWS_DEFAULT_REGION
            value: us-west-2
            ...<bunch of variable>
            limits: &main_limits
              cpu: 500m
              memory: 256Mi
            requests: *main_limits

If I wanted to expose this to the outside world traffic because say my application exposes app metrics using prometheus on a port.. how do I expose that port to the outside world?

my application has these two lines that starts an http server that needs to be exposed:

METRICS_PORT=9100
start_http_server(METRICS_PORT)

that's a prometheus server

-- Jwan622
kubernetes

4 Answers

3/13/2020

In general it's recommended to expose pods via services and not expose the pod directly considering the ephemerality of the pod. As mentioned above by KoopaKiller, the ways to expose a service include:

  1. ClusterIP: Exposes the Service on a cluster-internal IP making the Service only reachable from within the cluster. For your purpose, this will not suffice.

  2. NodePort: Exposes the Service on each Node’s IP at a static port. For your purpose, you will be able to connect the NodePort Service from outside the cluster by connecting to the nodeport for your service.

  3. LoadBalancer: Exposes the Service externally using a cloud provider’s load balancer. This is a safer option to use at high scale, however, note certain load balancers cost a decent amount. You might want to take that into account before choosing.

-- user1460675
Source: StackOverflow

3/12/2020

It's a bit weird to expose Prom metrics outside the local network but that aside, you use a Service. Usually a LoadBalancer type but sometimes NodeIP in special situations. Check out the documentation for more info.

-- coderanger
Source: StackOverflow

3/13/2020

Try the below sample

apiVersion: v1
kind: Service
metadata:
  name: hello
spec:
  selector:
    app: hello
  ports:
  - protocol: "TCP"
    port: 80
    targetPort: 80
  type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello
spec:
  selector:
    matchLabels:
      app: hello
  replicas: 1
  template:
    metadata:
      labels:
        app: hello
    spec:
      containers:
      - name: nginx
        image: nginx

you should be able to access the hello service at http://HOST_IP:NODE_PORT

-- P Ekambaram
Source: StackOverflow

3/13/2020

There are some ways to expose your application in Kubernetes.

Services could be used to expose internally, for others applications running in the same cluster (type: ClusterIP), externally binding a host port to your application node (type: NodePort) or loadbalancing the traffice between the nodes (type: LoadBalancer)

ClusterIP: Exposes the Service on a cluster-internal IP. Choosing this value makes the Service only reachable from within the cluster. This is the default ServiceType.

NodePort: Exposes the Service on each Node’s IP at a static port (the NodePort). A ClusterIP Service, to which the NodePort Service routes, is automatically created. You’ll be able to contact the NodePort Service, from outside the cluster, by requesting :.

LoadBalancer: Exposes the Service externally using a cloud provider’s load balancer. NodePort and ClusterIP Services, to which the external load balancer routes, are automatically created.

If you are using a cloud provider, you could use a service type LoadBalancer, then your service will get an external IP from your cloud provider and will be accessible publicly:

apiVersion: v1
kind: Service
metadata:
  name: <<some name>>
spec:
  selector:
    app: my_app_name # << HERE
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: LoadBalancer

Please note that for it works, you need to add a selector in your deployment file to service know for what pods redirect the requests. Like this:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: <some_name>
spec:
  selector:
    app: my_app_name # <= SELECTOR HERE
  replicas: 1
  template:
 ...

To check if everything is ok, use the command below and check for EXTERNAL-IP:

kubectl get svc <some_name>

References:

https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types

https://kubernetes.io/docs/concepts/services-networking/service/#with-selectors

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

-- KoopaKiller
Source: StackOverflow