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
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.