Skip to content
Merged

K8s #26

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
75 changes: 75 additions & 0 deletions k8s/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Kubernetes config (work in progress)

> [!CAUTION]
>
> This directory contains a yaml file for starting a RabbitMQ
> server. This is for testing and should not be used in production.


## Running

To deploy `agate` first edit the `config.yaml` and `secrets.yaml` to
include real configuration and settings. Then run

```sh
kubectl apply -f agate.yaml -f postgres.yaml -f config.yaml -f secrets.yaml
```

## Resources

This directory contains the kubernetes config required for running
Agate. The list of kubernetes resources required for Agate to work is as follows.


### Namespace

To try and keep things neat, every resource is placed in the `agate`
namespace.


### Deployments

- `django-app`: The django application. Runs via `gunicorn` on port
`8000`.
- `django-scheduler`: A scheduled task that performs periodic
operations such as getting data from the RabbitMQ queues and
deleting old data from the database.
- `postgres`: A Postgres database that stores ingestion attempts as
they occur. Attempts are deleted after 28 days.


### Services

- `django-service`: The service making `django-app` available on port
`8000`.
- `postgres`: The service making the `postgres` deployment available
on port `5432`.


### ConfigMaps

- `django-config` (`config.yaml`): Configuration for the `django-app`
(set in django via environment variables). These will likely need to
be edited for the specific deployment.
- `postgres-config` (`postgres.yaml`): Configuration for `postgres`
such as database, user and host. Can probably be left alone.


### PersistentVolumeClaim

A single persistent volume claim is made for storing the `postgres`
database. 1Gi is requested but this is probably overkill.


### Secrets

All secrets are defined in `secrets.yaml` and will need to be edited
accordingly. The important settings are:

- `message-config-secret`: Writes `varys_config.cfg` that is used to
configure the queue readers.
- `message-config-certs`: Contains the certificate files (encoded as
`base64`) needed to connect to the rabbitMQ queues.
- `django-secret`: The `SECRET_KEY` django setting.
- `postgres-secret`: The `postgres` password.

126 changes: 126 additions & 0 deletions k8s/agate.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
apiVersion: v1
kind: Namespace
metadata:
name: agate
---
apiVersion: v1
kind: Service
metadata:
name: django-service
namespace: agate
spec:
selector:
app: django-app
ports:
- port: 8000
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: django-app
namespace: agate
spec:
replicas: 1
selector:
matchLabels:
app: django-app
template:
metadata:
labels:
app: django-app
spec:
volumes:
- name: message-config
secret:
secretName: message-config-secret
- name: message-certs
secret:
secretName: message-config-certs
# By running an init container, we ensure that django doesn't
# try to perform migrations on a non-existing database
initContainers:
- name: wait-for-postgres
image: postgres:13-alpine
command:
[
"sh",
"-c",
"echo 'Waiting for Postgres...' && \
until pg_isready -h $POSTGRES_HOST -p $POSTGRES_PORT -U $POSTGRES_USER; do \
echo 'Postgres unavailable - sleeping'; \
sleep 1; \
done"
]
envFrom:
- configMapRef:
name: postgres-config
containers:
- name: web
image: ghcr.io/climb-tre/agate:v0.0.6
envFrom:
- configMapRef:
name: postgres-config
- secretRef:
name: postgres-secret
- configMapRef:
name: django-config
- secretRef:
name: django-secret

volumeMounts:
- name: message-config
mountPath: /app/varys_config.cfg
subPath: varys_config.cfg
readOnly: true
- name: message-certs
mountPath: /app/certs/
readOnly: true
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: django-scheduler
namespace: agate
labels:
app: django-scheduler
spec:
replicas: 1
selector:
matchLabels:
app: django-scheduler
template:
metadata:
labels:
app: django-scheduler
spec:
volumes:
- name: message-config
secret:
secretName: message-config-secret
- name: message-certs
secret:
secretName: message-config-certs
containers:
- name: scheduler
image: ghcr.io/climb-tre/agate:v0.0.6
# This runs the scheduler, not the web server
command: ["python", "manage.py", "runscheduler"]

envFrom:
- configMapRef:
name: postgres-config
- secretRef:
name: postgres-secret
- configMapRef:
name: django-config
- secretRef:
name: django-secret

volumeMounts:
- name: message-config
mountPath: /app/varys_config.cfg
subPath: varys_config.cfg
readOnly: true
- name: message-certs
mountPath: /app/certs/
readOnly: true
12 changes: 12 additions & 0 deletions k8s/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: django-config
namespace: agate
data:
DEBUG: "False"
ALLOWED_HOSTS: "127.0.0.1"
CORS_ALLOWED_ORIGINS: "http://127.0.0.1:5173,http://localhost:5173"
CSRF_TRUSTED_ORIGINS: "http://127.0.0.1:5173,http://localhost:5173"
ONYX_DOMAIN: "http://host.containers.internal:8002"
LIMITED_PROJECT_LIST: "mscape,synthscape"
86 changes: 86 additions & 0 deletions k8s/postgres.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: postgres-config
namespace: agate
data:
POSTGRES_DB: "db_service_test"
POSTGRES_USER: "postgres"
POSTGRES_HOST: "postgres"
POSTGRES_PORT: "5432"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-pvc
namespace: agate
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Service
metadata:
name: postgres
namespace: agate
spec:
ports:
- port: 5432
selector:
app: postgres
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
namespace: agate
spec:
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:13-alpine
ports:
- containerPort: 5432

envFrom:
- configMapRef:
name: postgres-config
- secretRef:
name: postgres-secret

volumeMounts:
- name: postgres-storage
mountPath: /var/lib/postgresql/data

readinessProbe:
exec:
command: ["sh", "-c", "pg_isready -U \"$POSTGRES_USER\" -h localhost"]
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3

livenessProbe:
exec:
command: ["sh", "-c", "pg_isready -U \"$POSTGRES_USER\" -h localhost"]
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 6


volumes:
- name: postgres-storage
persistentVolumeClaim:
claimName: postgres-pvc
59 changes: 59 additions & 0 deletions k8s/rabbitmq.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: rabbitmq-pvc
namespace: agate
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Service
metadata:
name: rabbitmq
namespace: agate
spec:
selector:
app: rabbitmq
ports:
- name: amqp
port: 5672
- name: management
port: 15672
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: rabbitmq
namespace: agate
spec:
replicas: 1
selector:
matchLabels:
app: rabbitmq
template:
metadata:
labels:
app: rabbitmq
spec:
containers:
- name: rabbitmq
image: rabbitmq:3-management-alpine
ports:
- containerPort: 5672
- containerPort: 15672
env:
- name: RABBITMQ_DEFAULT_USER
value: "guest"
- name: RABBITMQ_DEFAULT_PASS
value: "guest"
volumeMounts:
- name: rabbitmq-storage
mountPath: /var/lib/rabbitmq
volumes:
- name: rabbitmq-storage
persistentVolumeClaim:
claimName: rabbitmq-pvc
Loading
Loading