Is it possible to pass a Service's external IP (NodePort or LoadBalancer) as an environment variable to a container in a different service's Deployment?
For a concrete example, consider a Kubernetes cluster with namespaces for multiple teammates so they each have their own environment for testing. In a single environment, there are at least two services:
For Service #2, it needs to know the external IP address of service #1. So far I've only been able to find examples that make use of kubectl
to describe service #1 to find this information. I was hoping it would be possible to do something like this:
apiVersion: v1
kind: Service
metadata:
name: gateway
namespace: "${ env }"
labels:
app: gateway
spec:
type: LoadBalancer
ports:
- port: 8080
selector:
app: gateway
and
apiVersion: extensions/v1
kind: Deployment
metadata:
name: svc2-deployment
namespace: "${ env }"
labels:
app: svc2
spec:
template:
metadata:
labels:
app: svc2
spec:
containers:
- name: app
env:
- name: GATEWAY_IP
valueFrom:
fieldRef:
fieldPath: service.gateway.----.ingressIp
instead of using say an initContainers
with a script that does kubectl
things. Especially since I'm very new to Kubernetes :)
Not really but you can use DNS for that. For example:
apiVersion: extensions/v1
kind: Deployment
metadata:
name: svc2-deployment
namespace: "${ env }"
labels:
app: svc2
spec:
template:
metadata:
labels:
app: svc2
spec:
containers:
- name: app
env:
- name: GATEWAY_IP
value: gateway.<namespace-where-gw-is-running>.svc.cluster.local
It isn't currently an out of the box feature but there are tools you can install to get that external IP and put it in a configmap - for example the Jenkins-X expose-controller. However, I found it easier to just use DNS and parameterise the DNS name in your descriptors.
If you have wildcard DNS then you can give each service a dedicated external hostname under the domain like service1.domain and service2.domain etc. The wildcard DNS will route all of these to your ingress controller and it can then route to the right service based on hostname. (As the Jenkins-X guys note, you can get Willard DNS for free if your ingress IP is public with nip.io if you don't have something like route53 available.)
My experience of this was on the activiti project. We found that services needed to have a property injected that told them the external URL to the keycloak authentication system because each service contained keycloak code to validate that the token was issued on a valid external URL. You can see the result in the helm charts and there's a README there that explains a bit more. We took inspiration from the gitlab helm chart - their instructions ask the user to put in a wildcard DNS, presumably for similar reasons.