- Create a DockerHub account (you could also use my Docker images here)
- Install Docker
- Enable k8s with Docker by clicking on the Docker icon in the system tray, click on “Preferences”, then check the checkbox “Enable Kubernetes”.
What is Apollo Federation?
Apollo Federation is Apollo’s answer for implementing gql in a microservice architecture. It’s designed to replace schema stitching and solve pain points such as coordination, separation of concerns, and brittle gateway code.
Some quick Kubernetes definitions:
Pod: A set of running containers. We’ll have just 1 container per Pod.
Replica Set: A set of identical running pods. We’ll have just 1 Pod per Replica Set.
Deployment: Essentially a Replica Set with automatic rolling updates and autoscaling.
Service: A way to expose an application running on a set of Pods as a network service.
Let’s get started!
Clone the demo project
We’ll start by cloning the Apollo Federation Demo project and installing its dependencies.
git clone https://github.com/apollographql/federation-demo.git
Create DockerHub Repositories
The demo project is comprised of 4 gql services and a gql gateway. We’ll Create 5 repos on DockerHub. One for each gql service, and one for the gateway. Use these repo names: accounts, reviews, products, inventory, and gateway.
Create the Kubernetes manifests
K8s manifests are used to create, modify and delete k8s resources. We’ll be using manifests to define our Deployments and Services. In the root of your project, run the following:
In the workloads.yml file, we’ll create a Deployment for each of the gql services and the gql gateway. The Replica Set and Pods associated with each Deployment will be created automatically by the Deployment so there’s no need to define them separately. Here’s what your workloads.yml file should look like:
If you would rather use my Docker images, just replace <your_username> with timwebill.
Next up is a Service for each Deployment. As mentioned previously, Services provide us with a way to access a Pod or a set of Pods without having to know the actual IP addresses of the Pods. Here’s what your services.yml file should look like:
Note that our accounts, reviews, products, and inventory Services are of type ClusterIP. These Services are exposed on a cluster-internal IP and are only reachable from within the cluster. The k8s gateway Service is of type NodePort which exposes the service on the Node’s IP at the specified port. This means that we can access the gateway Service but not the other Services. When running k8s with Docker, the Node is available on localhost.
Update service domains
In the root of the project, in the gateway.js file, you will see that the gql services urls are pointing to localhost. This would work if we were running each service in the same Docker container but we aren’t. Instead, we need to make use of the k8s Services we’ve just defined. Change the domain in each url to the name of its corresponding k8s Service. Your gateway.js file should look like this:
K8s automatically configures the DNS system with the kube-dns Service. When a container makes a request to an unknown domain (such as http://accounts:4001), k8s will fetch the correct IP address from the kube-dns service and route the request to the correct IP address.
Create the dockerfiles
We’ll create a dockerfile for each gql service and for the gql gateway. From the root of your project run:
Update the dockerfiles to reflect the following:
Build and push the Docker images
For each of the 4 gql services and for the gql gateway run the following command from the root of your project:
docker build -f ./dockerfiles/accounts.dockerfile -t accounts . && docker tag accounts:latest <your_username>/accounts:latest && docker push <your_username>/accounts:latest
Be sure to replace the names of the services and also <your_username> with your DockerHub username.
Apply the Kubernetes manifests
To apply the k8s manifests run the following commands from the root of your project:
kubectl apply -f .
kubectl get all
The output should look something like this:
kubectl get all until the all the pods have STATUS “Running”.
localhost:30000 into your browser and hit enter. Voila! You now have a Federated GraphQL Service running on Kubernetes with Docker. Here’s a sample gql query to check that the service is running correctly:
To delete your k8s resources from the cluster run the following command from the manifests directory:
kubectl delete -f .
If you’ve made it this far well done and thanks for reading!