<p>I have experience with graphql but its my first time trying apollo federation and kubernetes.</p>

<p>I first tried splitting my monolith graphql server to micro services using apollo federation.
It worked fine(below is the working code). Now I am trying to run these micro services in kubernetes cluster, but keep having network problems between the apollo gateway and the other backend services.</p>

<p>From the apollo gateway server(when i try running it on kubernetes), I get this error:</p>

<p><code>Encountered error when loading auth at auth-cluster-ip-service: Only absolute URLs are supported</code></p>

<p>This is the part where I services are added to the apollo gateway:</p>

<pre><code>const gateway = new ApolloGateway({
  serviceList: [
    { name: 'service1', url: process.env.SERVICE1_URL },
    { name: 'service2', url: process.env.SERVICE2_URL },
    { name: 'service3', url: process.env.SERVICE3_URL },
  ],
  buildService({ name, url }) {
    return new AuthenticatedDataSource({ name, url });
  }
});

</code></pre>

<p>First I tried, with the following environment variables</p>

<pre><code>(.env)
SERVICE1_URL =http://localhost:3051
SERVICE2_URL =http://localhost:3052
SERVICE3_URL =http://localhost:3053
</code></pre>

<p>I simply ran 4 node apps on localhost on my laptop and it works!</p>

<p>Now the kubernetes part.</p>

<p>Below is the deployment config file for apollo-gateway. I am suspecting that the problem lies within the environment variables. As you can see, instead of an <code>url</code>, I have the <code>service name</code> on the corresponding environment variables' values. But from what I have learned, kubernetes master will fetch this "url"(clusterIP name) and replace with the IP address of the corresponding pods. So it should be fine. </p>

<p>It worked well when I practiced kubernetes. In my practice I was connecting to redis and postgres pods, via clusterIP name.</p>

<p>apollo-gateway deploymant config file</p>

<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: gateway-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      component: gateway
  template:
    metadata:
      labels:
        component: gateway
    spec:
      containers:
        - name: gateway
          image:&lt;docker-id&gt;/gateway
          ports:
            - containerPort: 4000
          env:
            - name: ACCESS_TOKEN_SECRET
              value: fas69dO2Z15nkev6157
            - name: SERVICE1_URL
              value: service1-cluster-ip-service
            - name: SERVICE2_URL
              value: service1-cluster-ip-service
            - name: SERVICE3_URL
              value: service1-cluster-ip-service

</code></pre>

<p>sample SERVICE cluster-ip config file</p>

<pre><code>apiVersion: v1
kind: Service
metadata:
  name: service1-cluster-ip-service
spec:
  type: ClusterIP
  selector:
    component: service1
  ports:
    - port: 3051
      targetPort: 3051
</code></pre>

<p>sample SERVICE deployment config file</p>

<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: service1-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      component: service1
  template:
    metadata:
      labels:
        component: service1
    spec:
      containers:
        - name: auth
          image:&lt;docker-id&gt;/service1
          ports:
            - containerPort: 3051
</code></pre>

<p>When the error message says "only absolute URLs are supported", that means the configured URL needs to include the <code>http://</code> scheme part as well as the host name.  You can fix this by changing your environment settings to include that</p>

<pre><code>- name: SERVICE1_URL
  value: 'http://service1-cluster-ip-service'
</code></pre>

<p>If the Service is listening on something other than the default HTTP port 80 you'll also need to include that port number in the URL.</p>
