<p>Error while trying to connect React frontend web to nodejs express api server into kubernetes cluster.</p>

<p>Can navigate in browser to <code>http:localhost:3000</code> and web site is ok.</p>

<p>But can't navigate to <code>http:localhost:3008</code> as expected (should not be exposed)</p>

<p><strong>My goal is to pass <em>REACT_APP_API_URL</em> environment variable to frontend in order to set axios <code>baseURL</code> and be able to establish communication between front and it's api server.</strong></p>

<p>deploy-front.yml</p>

<pre class="lang-yaml prettyprint-override"><code>apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: gbpd-front
spec:
  selector:
    matchLabels:
      app: gbpd-api
      tier: frontend
      track: stable
  replicas: 2
  template:
    metadata:
      labels:
        app: gbpd-api
        tier: frontend
        track: stable
    spec:
      containers:
        - name: react
          image: binomio/gbpd-front:k8s-3
          ports:
            - containerPort: 3000
          resources:
            limits:
              memory: "150Mi"
            requests:
              memory: "100Mi"
          imagePullPolicy: Always
</code></pre>

<p>service-front.yaml</p>

<pre class="lang-yaml prettyprint-override"><code>apiVersion: v1
kind: Service
metadata:
  name: gbpd-front
spec:
  selector:
    app: gbpd-api
    tier: frontend
  ports:
  - protocol: "TCP"
    port: 3000
    targetPort: 3000
  type: LoadBalancer

</code></pre>

<p>Deploy-back.yaml</p>

<pre class="lang-yaml prettyprint-override"><code>apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: gbpd-api
spec:
  selector:
    matchLabels:
      app: gbpd-api
      tier: backend
      track: stable
  replicas: 3 # tells deployment to run 2 pods matching the template
  template:
    metadata:
      labels:
        app: gbpd-api
        tier: backend
        track: stable
    spec:
      containers:
        - name: gbpd-api
          image: binomio/gbpd-back:dev
          ports:
            - name: http
              containerPort: 3008
</code></pre>

<p>service-back.yaml</p>

<pre class="lang-yaml prettyprint-override"><code>apiVersion: v1
kind: Service
metadata:
  name: gbpd-api
spec:
  selector:
    app: gbpd-api
    tier: backend
  ports:
  - protocol: "TCP"
    port: 3008
    targetPort: http
</code></pre>

<p>I tried many combinations, also tried adding "LoadBalancer" to backservice but nothing...</p>

<p>I can connect perfecto to localhost:3000 and use frontend but frontend can't connect to backend service.</p>

<p><strong>Question 1</strong>: What's is the ip/name to use in order to pass REACT_APP_API_URL to fronten correctly?
<strong>Question 2</strong>: Why is curl localhost:3008 not answering?</p>

<p>After 2 days trying almost everything in k8s official docs... can't figure out what's happening here, so any help will be much appreciated.</p>

<p>kubectl describe svc gbpd-api
Response:</p>

<pre><code>kubectl describe svc gbpd-api
Name:                     gbpd-api
Namespace:                default
Labels:                   &lt;none&gt;
Annotations:              kubectl.kubernetes.io/last-applied-configuration:
                            {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"gbpd-api","namespace":"default"},"spec":{"ports":[{"port":3008,"p...
Selector:                 app=gbpd-api,tier=backend
Type:                     LoadBalancer
IP:                       10.107.145.227
LoadBalancer Ingress:     localhost
Port:                     &lt;unset&gt;  3008/TCP
TargetPort:               http/TCP
NodePort:                 &lt;unset&gt;  31464/TCP
Endpoints:                10.1.1.48:3008,10.1.1.49:3008,10.1.1.50:3008
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   &lt;none&gt;
</code></pre>

<p>I tested your environment, and it worked when using a Nginx image, let's review the environment:</p>

<ul>
<li>The front-deployment is correctly described.</li>
<li>The front-service exposes it as <a href="https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types" rel="nofollow noreferrer">loadbalancer</a>, meaning your frontend is accessible from outside, perfect.</li>
<li>The back deployment is also correctly described.</li>
<li>The backend-service stays with as ClusterIP in order to be only accessible from inside the cluster, great.</li>
</ul>

<p>Below I'll demonstrate the communication between front-end and back end.</p>

<ul>
<li>I'm using the same yamls you provided, just changed the image to Nginx for example purposes, and since it's a http server I'm changing containerport to 80.</li>
</ul>

<blockquote>
  <p>Question 1: What's is the ip/name to use in order to pass REACT_APP_API_URL to fronten correctly?</p>
</blockquote>

<ul>
<li>I added the ENV variable to the front deploy as requested, and I'll use it to demonstrate also. You must use the service name to curl, I used the short version because we are working in the same namespace. you can also use the full name: <a href="http://gbpd-api.default.svc.cluster.local:3008" rel="nofollow noreferrer">http://gbpd-api.default.svc.cluster.local:3008</a></li>
</ul>

<hr>

<p><strong>Reproduction:</strong></p>

<ul>
<li>Create the yamls and applied them:</li>
</ul>

<pre><code>$ cat deploy-front.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gbpd-front
spec:
  selector:
    matchLabels:
      app: gbpd-api
      tier: frontend
      track: stable
  replicas: 2
  template:
    metadata:
      labels:
        app: gbpd-api
        tier: frontend
        track: stable
    spec:
      containers:
        - name: react
          image: nginx
          env:
            - name: REACT_APP_API_URL
              value: http://gbpd-api:3008
          ports:
            - containerPort: 80
          resources:
            limits:
              memory: "150Mi"
            requests:
              memory: "100Mi"
          imagePullPolicy: Always

$ cat service-front.yaml 
cat: cat: No such file or directory
apiVersion: v1
kind: Service
metadata:
  name: gbpd-front
spec:
  selector:
    app: gbpd-api
    tier: frontend
  ports:
  - protocol: "TCP"
    port: 3000
    targetPort: 80
  type: LoadBalancer

$ cat deploy-back.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gbpd-api
spec:
  selector:
    matchLabels:
      app: gbpd-api
      tier: backend
      track: stable
  replicas: 3
  template:
    metadata:
      labels:
        app: gbpd-api
        tier: backend
        track: stable
    spec:
      containers:
        - name: gbpd-api
          image: nginx
          ports:
            - name: http
              containerPort: 80

$ cat service-back.yaml 
apiVersion: v1
kind: Service
metadata:
  name: gbpd-api
spec:
  selector:
    app: gbpd-api
    tier: backend
  ports:
  - protocol: "TCP"
    port: 3008
    targetPort: http

$ kubectl apply -f deploy-front.yaml 
deployment.apps/gbpd-front created
$ kubectl apply -f service-front.yaml 
service/gbpd-front created
$ kubectl apply -f deploy-back.yaml 
deployment.apps/gbpd-api created
$ kubectl apply -f service-back.yaml 
service/gbpd-api created
</code></pre>

<ul>
<li>Remember, in Kubernetes the communication is <a href="https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/" rel="nofollow noreferrer">designed to be made between services</a>, because the pods are always recreated when there is a change in the deployment or when the pod fail.</li>
</ul>

<pre><code>$ kubectl get all
NAME                              READY   STATUS    RESTARTS   AGE
pod/gbpd-api-dc5b4b74b-kktb9      1/1     Running   0          41m
pod/gbpd-api-dc5b4b74b-mzpbg      1/1     Running   0          41m
pod/gbpd-api-dc5b4b74b-t6qxh      1/1     Running   0          41m
pod/gbpd-front-66b48f8b7c-4zstv   1/1     Running   0          30m
pod/gbpd-front-66b48f8b7c-h58ds   1/1     Running   0          31m

NAME                 TYPE           CLUSTER-IP    EXTERNAL-IP    PORT(S)          AGE
service/gbpd-api     ClusterIP      10.0.10.166   &lt;none&gt;         3008/TCP         40m
service/gbpd-front   LoadBalancer   10.0.11.78    35.223.4.218   3000:32411/TCP   42m
</code></pre>

<ul>
<li>The pods are the workers, and since they are replaceable by nature, we will connect to a frontend pod to simulate his behaviour and try to connect to the backend service (which is the network layer that will direct the traffic to one of the backend pods).</li>
<li>The nginx image does not come with <code>curl</code> preinstalled, so I will have to install it for demonstration purposes:</li>
</ul>

<pre><code>$ kubectl exec -it pod/gbpd-front-66b48f8b7c-4zstv -- /bin/bash
root@gbpd-front-66b48f8b7c-4zstv:/# apt update &amp;&amp; apt install curl -y
done.

root@gbpd-front-66b48f8b7c-4zstv:/# curl gbpd-api:3008
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Welcome to nginx!&lt;/title&gt;
...
</code></pre>

<ul>
<li>Now let's try using the environment variable that was defined:</li>
</ul>

<pre><code>root@gbpd-front-66b48f8b7c-4zstv:/# printenv | grep REACT
REACT_APP_API_URL=http://gbpd-api:3008
root@gbpd-front-66b48f8b7c-4zstv:/# curl $REACT_APP_API_URL
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Welcome to nginx!&lt;/title&gt;
...
</code></pre>

<hr>

<p><strong>Considerations:</strong></p>

<blockquote>
  <p>Question 2: Why is curl localhost:3008 not answering?</p>
</blockquote>

<ul>
<li>Since all yamls are correctly described you must check if <code>image: binomio/gbpd-back:dev</code> is correctly serving on port 3008 as intended.</li>
<li>Since it's not a public image, I can't test it, so I'll give you troubleshooting steps:

<ul>
<li>just like we logged inside the front-end pod you will have to log into this backend-pod and test <code>curl localhost:3008</code>.</li>
<li>If it's based on a linux distro with apt-get, you can run the commands just like I did on my demo:</li>
<li>get the pod name from backend deploy (example: <code>gbpd-api-6676c7695c-6bs5n</code>)</li>
<li>run <code>kubectl exec -it pod/&lt;POD_NAME&gt; -- /bin/bash</code></li>
<li>then run <code>apt update &amp;&amp; apt install curl -y</code></li>
<li>and test <code>curl localhost:3008</code></li>
<li>if no answer run `apt update &amp;&amp; apt install net-tools</li>
<li>and test <code>netstat -nlpt</code>, it will have to show you the output of the services running and the respective port, example:</li>
</ul></li>
</ul>

<pre><code>root@gbpd-api-585df9cb4d-xr6nk:/# netstat -nlpt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1/nginx: master pro 
</code></pre>

<ul>
<li>If the pod does not return nothing even on this approach, you will have to check the code in the image.</li>
</ul>

<p>Let me know if you need help after that!</p>
