<p>I have two Java microservices (<strong>caller.jar</strong> which calls <strong>called.jar</strong>)</p>

<p>We can set the <strong>caller</strong> service http port through an <strong>env-var</strong> <em>CALLERPORT</em> and the address of called service through an env-var <em>CALLEDADDRESS</em>.
<strong>So caller uses two env-var.</strong></p>

<p>We must set also <strong>called</strong> service env-var <em>CALLEDPORT</em> in order to set the specific http port on which called service is listening for http requests.</p>

<p>I don't know exactly how to simply expose these variables from a Dockerfile, in order to set them using Kubernetes.</p>

<p>Here is how I made the two Dockerfiles:</p>

<p><strong>Dockerfile of caller</strong></p>

<pre><code>FROM openjdk:8-jdk-alpine

# ENV CALLERPORT     (it's own port)
# ENV CALLEDADDRESS  (the other service address)

ADD caller.jar /

CMD ["java", "-jar", "caller.jar"]
</code></pre>

<p><strong>Dockerfile of called</strong></p>

<pre><code>FROM openjdk:8-jdk-alpine

# ENV CALLEDPORT (it's own port)

ADD called.jar /

CMD ["java", "-jar", "called.jar"]
</code></pre>

<p>With these I've made two <strong>Docker images</strong>: </p>

<ul>
<li><strong><em>myaccount/caller</em></strong>  </li>
<li><strong><em>myaccount/called</em></strong></li>
</ul>

<p>Then I've made the two deployments.yaml in order to let K8s deploy (on minikube) the two microservices using replicas and loadbalancers.</p>

<p><strong>deployment-caller.yaml</strong></p>

<pre><code>apiVersion: v1
kind: Service              
metadata:
  name: caller-loadbalancer
spec:
  type: LoadBalancer       
  ports:
  - port: 8080               
    targetPort: 8080        
  selector:            
    app: caller    
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: caller
  labels:
    app: caller
spec:
  replicas: 2                                             
  minReadySeconds: 15
  strategy:
    type: RollingUpdate                                   
    rollingUpdate: 
      maxUnavailable: 1                                   
      maxSurge: 1                                         
  selector:
    matchLabels:
      app: caller
      tier: caller
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: caller
        tier: caller
    spec:
      containers:
      - image: myaccount/caller
        name: caller
        env:
        - name: CALLERPORT
          value: "8080"
        - name: CALLEDADDRESS
          value: called-loadbalancer  # WHAT TO PUT HERE?!
        ports:
        - containerPort: 8080
          name: caller
</code></pre>

<p>And <strong>deployment-called.yaml</strong></p>

<pre><code>apiVersion: v1
kind: Service              
metadata:
  name: called-loadbalancer
spec:
  type: LoadBalancer       
  ports:
  - port: 8081               
    targetPort: 8081        
  selector:            
    app: called    
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: called
  labels:
    app: called
spec:
  replicas: 2                                             
  minReadySeconds: 15
  strategy:
    type: RollingUpdate                                   
    rollingUpdate: 
      maxUnavailable: 1                                   
      maxSurge: 1                                         
  selector:
    matchLabels:
      app: called
      tier: called
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: called
        tier: called
    spec:
      containers:
      - image: myaccount/called
        name: called
        env:
        - name: CALLEDPORT
          value: "8081"
        ports:
        - containerPort: 8081
          name: called
</code></pre>

<p><strong>IMPORTANT:</strong>
The single services work well if called singularly (such as calling an healthcheck endpoint) but, when calling the endpoint which involves the communication between the two services, then there is this error:</p>

<blockquote>
  <p>java.net.UnknownHostException: called</p>
</blockquote>

<p>The pods are correctly running and active, but i guess the problem is the part of deployment.yaml in which I must define how to find the pointed service, so here:</p>

<pre><code>spec:
  containers:
    - image: myaccount/caller
      name: caller
      env:
        - name: CALLERPORT
          value: "8080"
        - name: CALLEDADDRESS
          value: called-loadbalancer  # WHAT TO PUT HERE?!
        ports:
        - containerPort: 8080
          name: caller
</code></pre>

<p>Neither </p>

<pre><code>called
</code></pre>

<p>nor</p>

<pre><code>called-loadbalancer
</code></pre>

<p>nor </p>

<pre><code>http://caller 


kubectl get pods,svc -o wide

NAME                          READY     STATUS    RESTARTS   AGE       IP           NODE       NOMINATED NODE   READINESS GATES
pod/called-855cc4d89b-4gf97   1/1       Running   0          3m23s     172.17.0.4   minikube   &lt;none&gt;           &lt;none&gt;
pod/called-855cc4d89b-6268l   1/1       Running   0          3m23s     172.17.0.5   minikube   &lt;none&gt;           &lt;none&gt;
pod/caller-696956867b-9n7zc   1/1       Running   0          106s      172.17.0.6   minikube   &lt;none&gt;           &lt;none&gt;
pod/caller-696956867b-djwsn   1/1       Running   0          106s      172.17.0.7   minikube   &lt;none&gt;           &lt;none&gt;

NAME                          TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE       SELECTOR
service/called-loadbalancer   LoadBalancer   10.99.14.91    &lt;pending&gt;     8081:30161/TCP   171m      app=called
service/caller-loadbalancer   LoadBalancer   10.107.9.108   &lt;pending&gt;     8080:30078/TCP   65m       app=caller
service/kubernetes            ClusterIP      10.96.0.1      &lt;none&gt;        443/TCP          177m      &lt;none&gt;
</code></pre>

<p>works if put in that line of the deployment.yaml.
So what to put in this line?</p>

Alessandro Argentieri
<p>The short answer is you don't need to expose them in the Dockerfile. You can set any environment variables you want when you start a container and they don't have to be specified upfront in the Dockerfile. </p>

<p>You can verify this by starting a container using 'docker run' with '-e' to set env vars and '-it' to get an interactive session. The echo the value of your env var and you'll see it is set. </p>

<p>You can also get a terminal session with one of the containers in your running kubernetes Pod with 'kubectl exec' (<a href="https://kubernetes.io/docs/tasks/debug-application-cluster/get-shell-running-container/" rel="noreferrer">https://kubernetes.io/docs/tasks/debug-application-cluster/get-shell-running-container/</a>). From there you can echo environment variables from there to see that they are set. You can see them more quickly with 'kubectl describe pod ' after getting the pod name with 'kubectl get pods'. </p>

<p>Since you are having problems, you also want to check whether your services are working correctly. Since you are using minikube you can do 'minikube service ' to check they can be accessed externally. You'll also want to check the internal access - see <a href="https://stackoverflow.com/questions/54204956/accessing-spring-boot-controller-endpoint-in-kubernetes-pod/54206135#54206135">Accessing spring boot controller endpoint in kubernetes pod</a></p>

<p>Your approach of using service names and ports is valid. With a bit of debugging you should be able to get it working. Your setup is similar to an illustration I did in <a href="https://dzone.com/articles/kubernetes-namespaces-explained" rel="noreferrer">https://dzone.com/articles/kubernetes-namespaces-explained</a> so referring to that might help (except you are using env vars directly instead of through a configmap but it amounts to the same). </p>

<p>I think that in the caller you are injecting the wrong port in the env var - you are putting the caller's own port and not the port of what it is trying to call. </p>
