In this post, I will go over the steps needed to provision a Kubernetes cluster in AWS, and deploy a Neo4j cluster using Neo4j’s helm charts.
This post takes steps from the official Neo4j Kubernetes Documentation
Prerequisites
- An AWS Account
- Configured AWS Command Line Interface
- An SSH Key named
id_rsa.pub.
If you do not have one, you can generate it by running:ssh-keygen -t rsa -C "[email protected]"
Setting up a Kubernetes Cluster in EKS
Installation of tools and applications
- In order to create a Kubernetes (EKS) cluster in AWS, you will need to download the following applications:
-
kubectl
- mac:
brew install kubectl
- everything else: installation page
- mac:
-
eksctl
- mac:
brew install eksctl
- everything else: eksctl installation documentation
- mac:
-
helm
- mac
brew install helm
- everything else: installation page
- mac
- Add the neo4j helm chart repository for neo4j:
helm repo add neo4j https://helm.neo4j.com/neo4j
helm repo update
helm search repo neo4j/
You should see some output like this, to show that the helm repository has been installed and the neo4j charts are available:
Update Complete. ⎈Happy Helming!⎈
NAME CHART VERSION APP VERSION DESCRIPTION
neo4j/neo4j 5.5.0 5.5.0 Neo4j is the world's leading graph database
neo4j/neo4j-cluster-core 4.4.17 4.4.17 Neo4j is the world's leading graph database
neo4j/neo4j-cluster-headless-service 4.4.17 - Neo4j is the world's leading graph database
neo4j/neo4j-cluster-loadbalancer 4.4.17 - Neo4j is the world's leading graph database
neo4j/neo4j-cluster-read-replica 4.4.17 4.4.17 Neo4j is the world's leading graph database
neo4j/neo4j-docker-desktop-pv 4.4.17 - Sets up persistent disks suitable for simple de...
neo4j/neo4j-gcloud-pv 4.4.17 - Sets up persistent disks suitable for simple de...
neo4j/neo4j-headless-service 5.5.0 - Neo4j is the world's leading graph database
neo4j/neo4j-persistent-volume 5.5.0 - Sets up persistent disks suitable for a Neo4j H...
neo4j/neo4j-standalone 4.4.17 4.4.17 Neo4j is the world's leading graph database
- Export Variable for
AWS_DEFAULT_REGION
andAWS_PROFILE
. Details can be found in your~/.aws/credentials
and~/.aws/config
files (assuming the the aws-cli is correctly configured).
export AWS_DEFAULT_REGION="eu-west-1"
export AWS_PROFILE=your-aws-profile-name
- Create the EKS cluster:
eksctl create cluster --name "my-neo4j-eks-cluster" \
--nodes 4 \
--with-oidc \
--ssh-access \
--nodes-min 1 \
--nodes-max 4 \
--node-type c4.xlarge \
--node-volume-size 10 \
--profile $AWS_PROFILE \
--region $AWS_DEFAULT_REGION \
--nodegroup-name "test-neo4j-nodes"
This command will create a cloudformation stack with a number of resources required by the EKS Cluster. You can check the CloudFormation console to check on the progress of the EKS Cluster installation.
Assuming you are working in the eu-west-1 region, the following links point to the CloudFormation and EKS consoles.
EKS Cluster creation can take upwards of 15 minutes
- Create an IAM role (e.g.,
AmazonEKS_EBS_CSI_DriverRole
) and attach the required AWS-managed policy to it (e.g.,AmazonEBSCSIDriverPolicy
).
eksctl create iamserviceaccount \
--approve \
--role-only \
--profile $AWS_PROFILE \
--namespace kube-system \
--name ebs-csi-controller-sa \
--cluster my-neo4j-eks-cluster \
--role-name AmazonEKS_EBS_CSI_DriverRole \
--attach-policy-arn arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy
- Add the EBS CSI Driver as an Amazon EKS add-on to your cluster. Note that you will need to paste your AWS Account ID into this command to define the
service-account-role-arn
.
The EBS CSI (Container Storage Interface) Driver is a plugin for Kubernetes that allows you to use Amazon Elastic Block Store (EBS) volumes as Persistent Volumes (PVs) in your cluster. It implements the CSI specification and provides a way for pods to access EBS volumes dynamically. With the EBS CSI Driver, you can create and manage EBS volumes dynamically, and attach and detach them from your pods as needed, without manual intervention. This makes it easier to use EBS volumes in your Kubernetes environment, and provides a more dynamic and flexible storage solution for your containers.
eksctl create addon \
--force \
--profile $AWS_PROFILE \
--name aws-ebs-csi-driver \
--cluster my-neo4j-eks-cluster \
--service-account-role-arn arn:aws:iam::<aws-account-id>:role/AmazonEKS_EBS_CSI_DriverRole
- Configure kubectl to use the EKS cluster that you’ve just created:
aws eks update-kubeconfig \
--name my-neo4j-eks-cluster \
--profile $AWS_PROFILE \
--region $AWS_DEFAULT_REGION
- Create a namespace for our neo4j and configure it to be used in the current context:
kubectl create namespace neo4j
kubectl config set-context --current --namespace=neo4j
- Create a values.yaml file which we can use for each server we are going to install:
neo4j:
name: my-standalone
resources:
cpu: "0.5"
memory: "2Gi"
# Uncomment to set the initial password
#password: "my-initial-password"
# Uncomment to use enterprise edition
#edition: "enterprise"
#acceptLicenseAgreement: "yes"
volumes:
data:
mode: "dynamic"
dynamic:
# gp2 is a general-purpose SSD volume
storageClassName: gp2
- Install servers 1, 2 and 3
for pod in $(seq 1 3);
do helm install server-$pod neo4j/neo4j --set neo4j.edition=enterprise --namespace neo4j -f neo4j.values.yaml;
done
- Verify that pods are ready
kubectl get pods
- Verify that the service is available
kubectl get service
Use the output of this command to find the internet facing fqdn of the load balancer, for example:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-cluster-lb-neo4j LoadBalancer 10.100.2.118 a436a6dddecdd4135b820a8fb425bce4-1398122496.eu-west-1.elb.amazonaws.com 7474:31184/TCP,7473:30564/TCP,7687:32567/TCP 7m3s
server-1 ClusterIP 10.100.5.218 <none> 7687/TCP,7474/TCP,7473/TCP 7m3s
server-1-admin ClusterIP 10.100.91.203 <none> 6362/TCP,7687/TCP,7474/TCP,7473/TCP 7m3s
server-1-internals ClusterIP None <none> 6362/TCP,7687/TCP,7474/TCP,7473/TCP,7688/TCP,5000/TCP,7000/TCP,6000/TCP 7m3s
server-2 ClusterIP 10.100.49.12 <none> 7687/TCP,7474/TCP,7473/TCP 7m1s
server-2-admin ClusterIP 10.100.179.98 <none> 6362/TCP,7687/TCP,7474/TCP,7473/TCP 7m1s
server-2-internals ClusterIP None <none> 6362/TCP,7687/TCP,7474/TCP,7473/TCP,7688/TCP,5000/TCP,7000/TCP,6000/TCP 7m1s
server-3 ClusterIP 10.100.166.51 <none> 7687/TCP,7474/TCP,7473/TCP 7m
server-3-admin ClusterIP 10.100.249.212 <none> 6362/TCP,7687/TCP,7474/TCP,7473/TCP 7m
server-3-internals ClusterIP None <none> 6362/TCP,7687/TCP,7474/TCP,7473/TCP,7688/TCP,5000/TCP,7000/TCP,6000/TCP 7m
- Connect to the neo4j browser at:
http://EXTERNAL-IP:7474
for example:
http://a436a6dddecdd4135b820a8fb425bce4-1398122496.eu-west-1.elb.amazonaws.com:7474
- Clean Up and delete
Use the eksctl command (example shown below) to destroy your entire EKS environment, or use delete the CloudFormation Stacks which have been deployed.
eksctl delete cluster --name=my-neo4j-eks-cluster