Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kubernetes get nodeport mappings in a pod

Tags:

kubernetes

I'm migrating an application to Docker/Kubernetes. This application has 20+ well-known ports it needs to be accessed on. It needs to be accessed from outside the kubernetes cluster. For this, the application writes its public accessible IP to a database so the outside service knows how to access it. The IP is taken from the downward API (status.hostIP).

One solution is defining the well-known ports as (static) nodePorts in the service, but I don't want this, because it will limit the usability of the node: if another service has started and incidentally taken one of the known ports the application will not be able to start. Also, because Kubernetes opens the ports on all nodes in the cluster, I can only run 1 instance of the application per cluster.

Now I want to make the application aware of the port mappings done by the NodePort-service. How can this be done? As I don't see a hard link between the Service and the Statefulset object in Kubernetes.

Here is my (simplified) Kubernetes config:

apiVersion: v1
kind: Service
metadata:
  name: my-app-svc
  labels:
    app: my-app
spec:
  ports:
    - port: 6000
      targetPort: 6000
      protocol: TCP
      name: debug-port
    - port: 6789
      targetPort: 6789
      protocol: TCP
      name: traffic-port-1
  selector:
    app: my-app
  type: NodePort

---
apiVersion: apps/v1
kind: StatefulSet
metadata:
    name: my-app-sf
spec:
    serviceName: my-app-svc
    replicas: 1
    selector:
      matchLabels:
        app: my-app
    template:
      metadata:
        labels:
          app: my-app
      spec:
          containers:
            - name: my-app
              image: my-repo/myapp/my-app:latest
              imagePullPolicy: Always
              env:
                - name: K8S_ServiceAccountName
                  valueFrom:
                    fieldRef:
                      fieldPath: spec.serviceAccountName
                - name: K8S_ServerIP
                  valueFrom:
                    fieldRef:
                      fieldPath: status.hostIP
                - name: serverName
                  valueFrom:
                    fieldRef:
                      fieldPath: metadata.name
              ports:
              - name: debug
                containerPort: 6000
              - name: traffic1
                containerPort: 6789
like image 954
Sven Avatar asked Oct 31 '18 06:10

Sven


People also ask

How do you check NodePort in Kubernetes?

To specify a NodePort and see which NodePorts are already in use, run the kubectl get svc command. Any NodePorts in use appear under the Ports field.

How do you check a port on a pod?

shell into the pod and try running netstat -tulpn gives you all the ports open.

How do I access NodePort outside cluster?

Declaring a service as NodePort exposes the Service on each Node's IP at the NodePort (a fixed port for that Service , in the default range of 30000-32767). You can then access the Service from outside the cluster by requesting <NodeIp>:<NodePort> .

How do you get the logs of a specific container of a specific pod?

To get Kubectl pod logs, you can access them by adding the -p flag. Kubectl will then get all of the logs stored for the pod. This includes lines that were emitted by containers that were terminated.


1 Answers

This can be done with an initContainer.

You can define an initContainer to get the nodeport and save into a directory that shared with the container, then container can get the nodeport from that directory later, a simple demo like this:

apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
  - name: my-app
    image: busybox
    command: ["sh", "-c", "cat /data/port; while true; do sleep 3600; done"]
    volumeMounts:
    - name: config-data
      mountPath: /data
  initContainers:
  - name: config-data
    image: tutum/curl
    command: ["sh", "-c", "TOKEN=`cat /var/run/secrets/kubernetes.io/serviceaccount/token`; curl -kD - -H \"Authorization: Bearer $TOKEN\" https://kubernetes.default:443/api/v1/namespaces/test/services/app 2>/dev/null | grep nodePort | awk '{print $2}' > /data/port"]
    volumeMounts:
    - name: config-data
      mountPath: /data
  volumes:
  - name: config-data
    emptyDir: {}
like image 195
Kun Li Avatar answered Nov 08 '22 03:11

Kun Li