Compare commits

..

10 Commits

18 changed files with 186 additions and 35 deletions

View File

@@ -1,37 +1,50 @@
# Backend deployment
## Overview
The container is built using the Dockerfile and deployed to our own kubernetes cluster.
Both steps are handled by the CI/CD pipeline:
- First the container is built in the workflow `workflow_build-image.yaml` and pushed to the (local) container registry.
- Then the deployment is handled in the workflow `workflow_deploy-container.yaml` which deploys the container to the kubernetes cluster. Depending on the branch, the deployment is done to the staging or production environment.
This repository contains the necessary files for deploying the backend application to a kubernetes environment.
## Prerequisites
Before deploying the backend application, ensure that you have the following prerequisites:
For the deployment of the **backend** application, the following prerequisites need to be met:
- Kubernetes cluster with the following components:
- On the cluster side: a Kubernetes cluster with the following components:
- ingress controller
- storage class
- `kubectl` installed (`kustomize` is usually bundled)
- On the local side: for development and local testing:
- `kubectl` installed
- `kustomize` (usually bundled with `kubectl`)
## Deployment Steps
### Initial deployment
## Manual deployment
#### Initial deployment
To deploy the backend application, follow these steps:
1. Clone this repository: `git clone https://github.com/your-repo.git`
1. Apply the kustomization: `kubectl apply -k .`
1. Clone this repository
1. Apply the desired overly: `kubectl apply -k <path-to-overlay>`
### Rolling updates
Since the deployment uses the `latest` tag for the backend application, we simply need to trigger a rolling update which will pull the latest image from the registry. To do this, run the following command:
#### Rolling updates
Since the deployment uses a single tag (along with the `always` pull policy) for the backend application, we simply need to trigger a rolling update which will pull the latest image from the registry. To do this, run the following command:
```bash
kubectl -n anyway-backend rollout restart deployment/nav-backend
kubectl -n <namespace> rollout restart deployment/anyway-backend
```
## Configuration
## Automated deployment
### CI/CD and credentials
For the deployment to work, the CI runner needs to authenticate against the kubernetes cluster. This is done by creating a service account in the cluster and providing the CI runner with the necessary credentials through a kubeconfig file. This file is stored as a repository secret `KUBE_CONFIG` and is used by the `kubectl` command in the CI pipeline.
The kustomization allows for easy configuration of the backend application. To customize the deployment, modify the `kustomization.yaml` file.
The RBAC configuration for the service included for your reference in the file `rbac.yaml`. To use it, extract the token from the secret `deployment-token-secret`.
Then fill in the token and service account name into the kubeconfig.
### Memcached
The backend application requires a memcached instance. By default, the kustomization deploys this instance, as configured under `memcached/`. To disable this, comment out the `memcached` overlay in the `kustomization.yaml` file.
### Deployment environments
The deployment is done to two environments:
- Staging: All builds from forks and pull requests are deployed to the staging environment. This is done to test the changes before merging them to the main branch.
- Production: Only builds from the main branch are deployed to the production environment. This is the live environment that is used by the users. The main branch is protected and can only be merged to through pull requests.

View File

@@ -1,16 +1,16 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: nav-backend
name: anyway-backend
spec:
replicas: 1
selector:
matchLabels:
app: nav-backend
app: anyway-backend
template:
metadata:
labels:
app: nav-backend
app: anyway-backend
spec:
containers:
- name: worker
@@ -21,12 +21,14 @@ spec:
ports:
- containerPort: 8000
env:
- name: MEMCACHED_HOST_PATH
value: "memcached:11211"
- name: NUM_WORKERS
value: "3"
- name: OSM_CACHE_DIR
value: "/osm-cache"
- name: MEMCACHED_HOST_PATH
value: "memcached:11211"
- name: LOKI_URL
value: "http://loki.monitoring.svc:3100/loki/api/v1/push"
volumeMounts:
- name: osm-cache
mountPath: /osm-cache

View File

@@ -1,15 +1,15 @@
kind: IngressRoute
apiVersion: traefik.io/v1alpha1
metadata:
name: nav-ingress
name: anyway-ingress
spec:
entryPoints:
- websecure
routes:
- match: Host(`anyway.kluster.moll.re`)
- match: Host(`dummy`)
kind: Rule
services:
- name: nav-service
- name: anyway-backend
port: 8000
tls:
certResolver: default-tls

View File

@@ -1,18 +1,10 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: anyway-backend
resources:
- namespace.yaml
# - namespace.yaml
- pvc.yaml
- deployment.yaml
- service.yaml
- ingress.yaml
- memcached/
images:
- name: backend-image
newName: git.kluster.moll.re/anydev/anyway-backend
newTag: latest

View File

@@ -1,10 +1,10 @@
apiVersion: v1
kind: Service
metadata:
name: nav-service
name: anyway-backend
spec:
selector:
app: nav-backend
app: anyway-backend
ports:
- protocol: TCP
port: 8000

View File

@@ -0,0 +1,27 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
namespace: anyway-backend
nameSuffix: -prod
labels:
- includeSelectors: true
pairs:
env: prod
images:
- name: backend-image
newName: git.kluster.moll.re/anydev/anyway-backend
newTag: stable
patches:
- path: patch-ingress.yaml
target:
kind: IngressRoute
name: anyway-ingress
- path: patch-deployment-memcached-address.yaml
target:
kind: Deployment
name: anyway-backend

View File

@@ -0,0 +1,3 @@
- op: replace
path: /spec/template/spec/containers/0/env/0/value
value: "memcached-prod:11211"

View File

@@ -0,0 +1,6 @@
- op: replace
path: /spec/routes/0/match
value: Host(`anyway.anydev.info`) || Host(`anyway.kluster.moll.re`)
- op: replace
path: /spec/routes/0/services/0/name
value: anyway-backend-prod

View File

@@ -0,0 +1,33 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
namespace: anyway-backend
nameSuffix: -stg
labels:
- includeSelectors: true
pairs:
env: stg
images:
- name: backend-image
newName: git.kluster.moll.re/anydev/anyway-backend
newTag: unstable
patches:
- path: patch-ingress.yaml
target:
kind: IngressRoute
name: anyway-ingress
- path: patch-deployment-memcached-address.yaml
target:
kind: Deployment
name: anyway-backend
- path: patch-deployment.yaml
target:
kind: Deployment
name: anyway-backend

View File

@@ -0,0 +1,3 @@
- op: replace
path: /spec/template/spec/containers/0/env/0/value
value: "memcached-stg:11211"

View File

@@ -0,0 +1,5 @@
- op: add
path: /spec/template/spec/containers/0/env/-
value:
name: DEBUG
value: "true"

View File

@@ -0,0 +1,6 @@
- op: replace #action
path: /spec/routes/0/match
value: Host(`anyway-stg.anydev.info`) || Host(`anyway-stg.kluster.moll.re`)
- op: replace
path: /spec/routes/0/services/0/name
value: anyway-backend-stg

61
rbac.yaml Normal file
View File

@@ -0,0 +1,61 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: anyway-backend
name: deployment-role
rules:
- apiGroups:
- ""
- "apps"
- "traefik.io"
resources:
- pods
- services
- deployments
- ingressroutes
- persistentvolumeclaims
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: deployment-rolebinding
namespace: anyway-backend
subjects:
- kind: ServiceAccount
name: deployment-sa
namespace: anyway-backend
roleRef:
kind: Role
name: deployment-role
apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: deployment-sa
namespace: anyway-backend
automountServiceAccountToken: false
---
apiVersion: v1
kind: Secret
metadata:
namespace: anyway-backend
name: deployment-token-secret
annotations:
kubernetes.io/service-account.name: deployment-sa
type: kubernetes.io/service-account-token