Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Add Kubernetes configuration and deployment files #14

Merged
merged 5 commits into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ To learn more about SubQuery, [see their docs](https://academy.subquery.network)
- [2. Generate types](#2-generate-types)
- [3. Run](#3-run)
- [Localnet ONLY](#localnet-only)
- [4.1 Debugging, errors running \& building](#41-debugging-errors-running--building)
- [4.2 Using a pre-built image](#42-using-a-pre-built-image)
- [4.3 Available Scripts breakdown](#43-available-scripts-breakdown)
- [3.1 Debugging, errors running \& building](#31-debugging-errors-running--building)
- [3.2 Using a pre-built image](#32-using-a-pre-built-image)
- [3.3 Available Scripts breakdown](#33-available-scripts-breakdown)
- [3.4 Using k8s](#34-using-k8s)

## Usage & Query Docs

Expand Down Expand Up @@ -214,7 +215,7 @@ Or Stop & clean up (delete postgres data):
yarn run docker:clean:development
```

#### 4.1 Debugging, errors running & building
#### 3.1 Debugging, errors running & building

If you're hitting errors with the above command, do a nuclear clean of all potential issues:

Expand All @@ -226,7 +227,7 @@ docker context use default

Now pick up from the `yarn run docker:build` step above.

#### 4.2 Using a pre-built image
#### 3.2 Using a pre-built image

If you are unable to build locally, a pre-built image is available on Docker Hub: [bryanchriswhite/pocketdex-subquery-node:latest](https://hub.docker.com/r/bryanchriswhite/pocketdex-subquery-node).

Expand All @@ -251,7 +252,7 @@ services:
...
```

#### 4.3 Available Scripts breakdown
#### 3.3 Available Scripts breakdown

* `preinstall` - Enforces the use of Yarn as the package manager.
* `postinstall` - Executes the `env:prepare` script after the installation process.
Expand All @@ -278,3 +279,7 @@ services:
* `docker:ps:<environment>` - Shows the status of services for the specified environment.
* `docker:stop:<environment>` - Stops all active services for the specified environment without removing them.
* `docker:clean:<environment>` - Stops and removes all services, volumes, and networks for the specified environment.

#### 3.4 Using k8s

See the instructions in [docs/kubernetes.md](./docs/kubernetes.md) for deploying using Kubernetes.
123 changes: 123 additions & 0 deletions docs/kubernetes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# Local Kubernetes Deployment <!-- omit in toc -->

- [Requirements](#requirements)
- [Deploy it](#deploy-it)
- [1. \[Optional\] Set Up PostgreSQL](#1-optional-set-up-postgresql)
- [2. Update Database Secrets](#2-update-database-secrets)
- [3. Configure the Application](#3-configure-the-application)
- [4. Deploy Indexer and Query Components](#4-deploy-indexer-and-query-components)
- [Explore Locally](#explore-locally)
- [Expose Publically](#expose-publically)
- [Watch the Logs](#watch-the-logs)

## Requirements

1. **Kubernetes Cluster**; if you are already running Shannon in `Localnet`, you can work with it.
1. **Helm** & **PostgreSQL**; optional if you already have PostgreSQL

## Deploy it

**NOTE**: Before proceeding, ensure that the Kubernetes deployment has access to the Pocketdex image. You can build the image by following the instructions in the main [README](../README.md) file.

Then, do one of the following:

1. Load it into your Kubernetes cluster using `kind local docker-images <image:tag>`(if you're using it)
2. Push it to your preferred container registry

### 1. [Optional] Set Up PostgreSQL

**NOTE**: Skip this step if you already have a PostgreSQL instance running.

Add the Bitnami Helm repository:

```shell
helm repo add bitnami https://charts.bitnami.com/bitnami
```

Replace all the `CHANGEME` placeholders in `kubernetes/postgresql-values.yaml`.

Install PostgreSQL:

```shell
helm install postgresql bitnami/postgresql --version 15.5.23 -f kubernetes/postgresql-values.yaml
```

#### 2. Update Database Secrets

Replace all the `CHANGEME` placeholders in `kubernetes/db-secrets.yaml`.

Deploy them using:

```shell
kubectl apply -f kubernetes/db-secrets.yaml
```

#### 3. Configure the Application

Review/Edit and deploy the ConfigMap found in `kubernetes/configmap.yaml`:

```shell
kubectl apply -f kubernetes/configmap.yaml
```

#### 4. Deploy Indexer and Query Components

Create the indexer deployment and service:

```shell
kubectl apply -f kubernetes/indexer-deployment.yaml
```

Create the query deployment and service:

```shell
kubectl apply -f kubernetes/query-deployment.yaml
```

### Explore Locally

To explore the application locally, you can access the query playground using a simple `port-forward`:

```shell
kubectl port-forward svc/pocketdex-query --address 127.0.0.1 3000:3000
```

Navigate to `http://localhost:3000`, and you should see the GraphQL Playground.

### Expose Publically

If you need to permanently expose this to the world, you will need an Ingress controller.
Any Ingress controller should work, but here are a few popular ones:

- [HAProxy Ingress](https://artifacthub.io/packages/helm/haproxy-ingress/haproxy-ingress)
- [NGINX Ingress](https://artifacthub.io/packages/helm/nginx-ingress-chart/nginx-ingress)

Once the ingress controller is set up, you can use the example Ingress configuration located at
`kubernetes/ingress.yaml`.

**NOTE**: This file is just an example. You should review and edit it as needed before deploying it.
If you need TLS support, ensure your Ingress Controller is configured to handle it in front of the query service.

```shell
kubectl apply -f kubernetes/ingress.yaml
```

### Watch the Logs

To watch the logs for both the Indexer and Query components:

```shell
kubectl logs -f -l app=pocketdex
```

To watch the logs for the Indexer component only:

```shell
kubectl logs -f -l app=pocketdex -l component=indexer
```

To watch the logs for the Query component only:

```shell
kubectl logs -f -l app=pocketdex -l component=query
```
15 changes: 15 additions & 0 deletions kubernetes/configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: shannon-testnet
data:
# Testnet
endpoint: "https://testnet-validated-validator-rpc.poktroll.com"
# LocalNet
# endpoint: "http://validator-poktroll-validator.default.svc.cluster.local:26657"
chain_id: "poktroll"
# db schema name
db_schema: "testnet"
# indexer endpoint
indexer_endpoint: "http://pocketdex-indexer.default.svc.cluster.local:3000"

11 changes: 11 additions & 0 deletions kubernetes/db-secrets.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: db-credentials
stringData:
user: "postgres"
password: "CHANGEME"
database: "postgres"
host: "postgresql.default.svc.cluster.local"
port: "5432"
107 changes: 107 additions & 0 deletions kubernetes/indexer-deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
### Indexer component
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: pocketdex
component: indexer
name: pocketdex-indexer
spec:
progressDeadlineSeconds: 15 # Adjust deployment progress deadline if needed
replicas: 1 # Number of pod replicas
revisionHistoryLimit: 10 # Number of old ReplicaSets to retain
selector:
matchLabels:
app: pocketdex
component: indexer
strategy:
type: Recreate # Restart strategy type
template:
metadata:
labels:
app: pocketdex
component: indexer
spec:
containers:
- name: pocketdex-indexer
args: [ "--unfinalized-blocks=true" ] # Arguments for the container
env:
- name: NODE_ENV
value: production
- name: WORKERS
value: "8"
- name: BATCH_SIZE
value: "50"
- name: DB_SCHEMA
valueFrom:
configMapKeyRef:
key: db_schema
name: shannon-testnet
- name: START_BLOCK
value: "1"
- name: ENDPOINT
valueFrom:
configMapKeyRef:
key: endpoint
name: shannon-testnet
- name: CHAIN_ID
valueFrom:
configMapKeyRef:
key: chain_id
name: shannon-testnet
- name: DB_USER
valueFrom:
secretKeyRef:
key: user
name: db-credentials
- name: DB_PASS
valueFrom:
secretKeyRef:
key: password
name: db-credentials
- name: DB_DATABASE
valueFrom:
secretKeyRef:
key: database
name: db-credentials
- name: DB_HOST
valueFrom:
secretKeyRef:
key: host
name: db-credentials
- name: DB_PORT
valueFrom:
secretKeyRef:
key: port
name: db-credentials
# TODO: Replace with the actual Pocket Network Docker image of PocketDex once it is released.
image: poktscan/pocketdex:latest # Docker image
imagePullPolicy: IfNotPresent # Image pull policy
resources:
limits:
cpu: "4"
memory: 4Gi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
terminationGracePeriodSeconds: 20 # Time before the termination signal is sent to the container
---
apiVersion: v1
kind: Service
metadata:
labels:
app: pocketdex
component: indexer
name: pocketdex-indexer
spec:
ports:
- name: indexer
port: 3000
protocol: TCP
targetPort: 3000
selector:
app: pocketdex
component: indexer
sessionAffinity: None
type: ClusterIP
29 changes: 29 additions & 0 deletions kubernetes/ingress.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
### IMPORTANT:
### THIS FILE IS JUST AN EXAMPLE SHOWING HOW TO EXPOSE THE POCKETDEX SERVICE WITH AN INGRESS.
### IT IS NOT MEANT TO BE USED AS IS AND WILL REQUIRE MODIFICATION TO FIT YOUR INGRESS CONTROLLER AND SETUP NEEDS.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: pocketdex
labels:
app: pocketdex
component: query
spec:
ingressClassName: default
rules:
# CHANGE the host to the appropriate domain for your setup
- host: pocketdex.testnet.your.domain.com
http:
paths:
- backend:
service:
name: pocketdex-query
port:
name: query
path: /
pathType: Prefix
# If you need TLS support, uncomment the following lines and configure them as needed
# tls:
# - hosts:
# - pocketdex.testnet.your.domain.com
# secretName: certificate-tls
Loading