apollo gateway (federation) fails to connect to services in kubernetes environment

3/27/2020

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

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.

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

Encountered error when loading auth at auth-cluster-ip-service: Only absolute URLs are supported

This is the part where I services are added to the apollo gateway:

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 });
  }
});

First I tried, with the following environment variables

(.env)
SERVICE1_URL =http://localhost:3051
SERVICE2_URL =http://localhost:3052
SERVICE3_URL =http://localhost:3053

I simply ran 4 node apps on localhost on my laptop and it works!

Now the kubernetes part.

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 url, I have the service name 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.

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

apollo-gateway deploymant config file

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:<docker-id>/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

sample SERVICE cluster-ip config file

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

sample SERVICE deployment config file

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:<docker-id>/service1
          ports:
            - containerPort: 3051
-- Sihoon Kim
apollo
apollo-federation
docker
kubernetes

1 Answer

4/2/2020

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

- name: SERVICE1_URL
  value: 'http://service1-cluster-ip-service'

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.

-- David Maze
Source: StackOverflow