Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a kubernetes Deployment inject the service nodeport as an environment variable?

Inside a service yaml file, you can use jsonpath to select a named nodeport value like so:

    - name: MY_NODE_PORT
      valueFrom:
        fieldRef:
          fieldPath: spec.ports[?(@.name=="http")].nodePort

However, in my deployment yaml file, I would like to have an environment variable like MY_NODE_PORT above that is exposed to the container to the pod. I happen to have combined my service and deployment into a single file for me to kubectl create -f. Is it possible to select the named service nodeport in the deployment section, rather than in the service section?

My purpose is to register a Kubernetes service and deployment to a legacy service discovery mechanism, in this case Netflix OSS Eureka.

like image 369
SteveCoffman Avatar asked Jul 25 '17 23:07

SteveCoffman


2 Answers

As in Janos Lenart's answer and Marc Sluiter commented, a service and a deployment are different resources and might as easily be specified in separate files. They have no direct knowledge of one another, and, even if you name the service NodePort port, unless you explicitly specify the service NodePort port value (e.g. something from 30000 to 32767) you won't be able to specify what the pod environment variable should be to match it. While you can hard code the NodePort port value like that, as Janos Lenart suggested, but it's brittle and not recommended.

While Kubernetes provides a number of handy environment variables to pods, it is not possible for a pod environment variable to reference a service nodeport port value that was dynamically assigned by kubernetes.

However, the Pod does have access to talk to the Kubernetes API server, and the API server will be able to reply back with information about the service, such as the nodeport. So a Pod can ask the API server for a service's NodePort port value. I created a kubernetes service and deployment with simple sidecar pod as a proof of concept.

My example here handles registering a Kubernetes NodePort service with an (external or internal) Netflix OSS Eureka service registry. This might be useful to others for bridging Kubernetes to other legacy service discovery mechanisms.

like image 187
SteveCoffman Avatar answered Oct 05 '22 13:10

SteveCoffman


You automatically have a number of environment variables in the containers. You do need to make sure your Service is created before your deployment.

As an example, for a Service named mysql (in the same namespace) you will have variables like this:

MYSQL_PORT="tcp://10.96.0.3:3306"
MYSQL_PORT_3306_TCP="tcp://10.96.0.3:3306"
MYSQL_PORT_3306_TCP_ADDR="10.96.0.3"
MYSQL_PORT_3306_TCP_PORT="3306"
MYSQL_PORT_3306_TCP_PROTO="tcp"
MYSQL_SERVICE_HOST="10.96.0.3"
MYSQL_SERVICE_PORT="3306"
MYSQL_SERVICE_PORT_MYSQL="3306"

As an alternative you can also make use of the cluster DNS service special attention to SRV records).

like image 23
Janos Lenart Avatar answered Oct 05 '22 13:10

Janos Lenart