From 43fbfcb3458458f213997547bec5524b7a9b2d3b Mon Sep 17 00:00:00 2001 From: Nicolas Marcq Date: Mon, 11 Dec 2023 11:40:47 +0100 Subject: [PATCH] k8s deployment doc --- docs/administration/backup.md | 107 ++++++++++++++---- docs/administration/upgrade.md | 24 +++- docs/configuration/openid.md | 16 --- docs/configuration/squest_settings.md | 5 +- docs/getting_started.md | 25 ---- .../tls.md => installation/docker-compose.md} | 29 ++++- docs/installation/kubernetes.md | 92 +++++++++++++++ .../advanced}/ldap.md | 27 ++++- k8s/inventory/group_vars/all/squest.yml | 10 +- mkdocs.yml | 10 +- 10 files changed, 265 insertions(+), 80 deletions(-) delete mode 100644 docs/configuration/openid.md rename docs/{configuration/tls.md => installation/docker-compose.md} (70%) create mode 100644 docs/installation/kubernetes.md rename docs/{configuration => manual/advanced}/ldap.md (81%) diff --git a/docs/administration/backup.md b/docs/administration/backup.md index e9d16ace7..de039e67c 100644 --- a/docs/administration/backup.md +++ b/docs/administration/backup.md @@ -6,9 +6,31 @@ Persistent data of squest are: - media folder (used to store images) An integrated backup solution based on [django-dbbackup](https://django-dbbackup.readthedocs.io/en/master/) is -available. Once enabled, backups are placed in the `/app/backup` folder of the `celery-beat` container. +available. Once enabled, backups are placed in the `/app/backup` folder of one of the django based container. -## Execute a backup manually +!!! note + + Get more info on dbrestore and mediarestore command arguments on the + [official doc](https://django-dbbackup.readthedocs.io/en/master/commands.html#). + +## Using Docker compose + +### Enable automatic backup + +Enable automatic backup by updating your environment configuration file `docker/environment_variables/squest.env`: +```bash +BACKUP_ENABLED=True +``` + +By default, backup is performed every day at 1 AM. + +!!! note + + Follow the full [configuration documentation](../configuration/squest_settings.md) to know all available flags + for the backup service. + + +### Execute a backup manually Execute the command below against the celery-beat container: ```bash @@ -57,22 +79,7 @@ Output example: In this example, data are placed in the mount point `/var/lib/docker/volumes/squest_backup/_data` on the host. Files in this path need to be placed in a safe place. -## Enable automatic backup - -Enable automatic backup by updating your environment configuration file `docker/environment_variables/squest.env`: -```bash -BACKUP_ENABLED=True -``` - -By default, backup is performed every day at 1 AM. - -!!! note - - Follow the full [configuration documentation](../configuration/squest_settings.md) to know all available flags - for the backup service. - - -## Restore +### Restore Start Squest services like for the initial deployment ```bash @@ -100,7 +107,65 @@ docker-compose exec celery-beat python manage.py dbrestore docker-compose exec celery-beat python manage.py mediarestore ``` -!!! note +## Using Kubernetes - Get more info on dbrestore and mediarestore command arguments on the - [official doc](https://django-dbbackup.readthedocs.io/en/master/commands.html#). +### Enable automatic backup + +Enable the backup in `squest.yml` inventory: +```yaml +squest_django: + backup: + enabled: true + crontab: "0 1 * * *" +``` + +Run the deployment playbook +```bash +ansible-playbook -v -i inventory deploy.yml --tags backup +``` + +### Externalize backup via SSH + +This feature is optional. By default, the backup cronjob will place backup file into a PVC. Depending on your K8S environment, you might want to externalize them. +If you want to push those files into an external ssh server you can use the integrated rsync solution. + +```yaml +squest_django: + externalize_backup_via_rsync: # rsync backup files into and external server + enabled: true + crontab: "30 1 * * *" + private_ssh_key: "{{ lookup('file', '/path/to/id_ed25519_squest_k8s_dev') + '\n' }}" + ssh_user: "squest_k8s_dev" + ssh_server: "remote.server.ssh.net" + remote_path: "/backup/squest_k8s_dev/" +``` + +### Execute a backup manually + +Run the `backup.yml` playbook +```bash +ansible-playbook -v -i inventory backup.yml +``` + +This command will execute a job in K8S that add a backup of the database and media files into a PVC. + +### Restore + +To restore Squest. First, deploy the app like for the first deployment using the playbook. + +Once Squest is available, copy backup files into django pod +```bash +kubectl -n squest cp ~/path/to/db-2023-12-06-182115.dump django-54b69fbb48-wrt9j:/app/backup +kubectl -n squest cp ~/path/to/media-2023-12-06-182117.tar django-54b69fbb48-wrt9j:/app/backup +``` + +Check backup is listed +```bash +kubectl -n squest exec -it django-54b69fbb48-wrt9j python manage.py listbackups +``` + +Restore by passing backup file name +```bash +kubectl -n squest exec -it django-54b69fbb48-wrt9j -- python manage.py dbrestore --database default -i db-2023-12-06-182115.dump +kubectl -n squest exec -it django-54b69fbb48-wrt9j -- python manage.py mediarestore -i media-2023-12-06-182117.tar +``` diff --git a/docs/administration/upgrade.md b/docs/administration/upgrade.md index 32b12ed76..8441b4f61 100644 --- a/docs/administration/upgrade.md +++ b/docs/administration/upgrade.md @@ -4,12 +4,14 @@ This documentation aims at explaining how to perform an upgrade of squest on new !!! note - Read the changelog of the version before performing any update to know what are the breaking changes or specific requirements of the new release. + Read the changelog and release note of the version before performing any update to know what are the breaking changes or specific requirements of the new release. !!! note We recommend performing a manual backup before any upgrade. See the dedicated [backup doc](backup.md) +## Using Docker compose + Stop all containers that use the Squest image ```bash docker-compose kill django celery-worker celery-beat @@ -31,3 +33,23 @@ Start back containers ```bash docker-compose start django celery-worker celery-beat ``` + +## Using Kubernetes + +Change the Squest image version in the inventory +```yaml +squest_django: + image: quay.io/hewlettpackardenterprise/squest: +``` + +Run the update playbook +```bash +ansible-playbook -v -i inventory update.yml +``` + +The playbook will: + +- Redirect the traffic to maintenance page +- Rollout Django containers with the new image +- Execute database migration +- Restore traffic to Squest once the app is back available diff --git a/docs/configuration/openid.md b/docs/configuration/openid.md deleted file mode 100644 index 62baa98dc..000000000 --- a/docs/configuration/openid.md +++ /dev/null @@ -1,16 +0,0 @@ -# OpenID Connect authentication backend - -## Default configuration - -The configuration is loaded from environment variables file placed in the folder `docker/environment_variables`. - -Retrieve environment variables from the [Squest configuration settings documentation](../configuration/squest_settings.md#openid-connect) - -Configuration example: -```bash -SOCIAL_AUTH_OIDC_ENABLED=True -SOCIAL_AUTH_OIDC_BTN_TEXT="OpenID Login" -SOCIAL_AUTH_OIDC_OIDC_ENDPOINT="https://example.com/" -SOCIAL_AUTH_OIDC_KEY="client_id" -SOCIAL_AUTH_OIDC_SECRET="secret" -``` \ No newline at end of file diff --git a/docs/configuration/squest_settings.md b/docs/configuration/squest_settings.md index aca0cf5e3..4abdc0913 100644 --- a/docs/configuration/squest_settings.md +++ b/docs/configuration/squest_settings.md @@ -3,7 +3,9 @@ Default settings are configured to provide a testing/development environment. For a production setup it is recommended to adjust them following your target environment. -The configuration is loaded from environment variables file placed in the folder `docker/environment_variables`. +When using docker-compose, the configuration is loaded from environment variables file placed in the folder `docker/environment_variables`. + +When using Kubernetes, the configuration need to be placed in the `squest.yml` inventory file in the variable `squest_django/env`. ## Database @@ -359,4 +361,3 @@ Redis hostname. **Default:** `6379` Redis port. - diff --git a/docs/getting_started.md b/docs/getting_started.md index 860454aab..66d5700e1 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -1,29 +1,4 @@ -Pre-requisites: - -- docker -- docker-compose -- Instance of Red Hat Ansible Automation Platform or AWX - -## Deploy Squest - -The current deployment is based on Docker Compose. To run the application, execute the `docker-compose.yml` file: -```bash -docker-compose up -``` - -Then connect with your web browser to [http://127.0.0.1:8080](http://127.0.0.1:8080) -The default admin account is `admin // admin` - -The default export the port 8080. If you want to use the standard HTTP port 80, update the -file `docker-compose.override.yml`. -```yaml -services: - nginx: - ports: - - "80:8080" -``` - ## Connect Squest to your controller The first step consist into adding a **backend controller** (RHAAP/AWX). diff --git a/docs/configuration/tls.md b/docs/installation/docker-compose.md similarity index 70% rename from docs/configuration/tls.md rename to docs/installation/docker-compose.md index f5f3f895d..305e20433 100644 --- a/docs/configuration/tls.md +++ b/docs/installation/docker-compose.md @@ -1,13 +1,36 @@ -# TLS +# Docker Compose deployment -This section explains how to add TLS support on Squest. +## Deploy Squest app + +The docker-compose based deployment is a good way to easily and quickly test Squest. This way of deploying is also stable enough to be used in production. + +To run the Squest application, execute the `docker-compose.yml` file: +```bash +docker-compose up +``` + +Then connect with your web browser to [http://127.0.0.1:8080](http://127.0.0.1:8080) +The default admin account is `admin // admin` + +The default export the port 8080. If you want to use the standard HTTP port 80, update the +file `docker-compose.override.yml`. +```yaml +services: + nginx: + ports: + - "80:8080" +``` + +## TLS + +This section explains how to add TLS support on Squest when using docker-compose based deployment. The TLS endpoint is managed by a reverse proxy on top of the default web server. This is not the only way to handle this part. Many tools like Nginx, Apache or Traefik could be used, and you are free to use the one you want instead of this proposed configuration. The only recommendation we have is to keep the default nginx web server as main http entrypoint. -## TLS using Caddy +### Using Caddy [Caddy](https://caddyserver.com/) is a powerful webserver written in Go which provide a [reverse proxy](https://caddyserver.com/docs/caddyfile/directives/reverse_proxy#reverse-proxy) feature. diff --git a/docs/installation/kubernetes.md b/docs/installation/kubernetes.md new file mode 100644 index 000000000..a54f8d1f8 --- /dev/null +++ b/docs/installation/kubernetes.md @@ -0,0 +1,92 @@ +# Kubernetes deployment + +!!!warning + + This deployment is still a beta feature. Feel free to send pull requests to enhance the deployment or give us feedback though Gitter chat or GitHub discutions. + +## Pre-requisites + +The Kubernetes deployment is wrapped by Ansible. The code has been tested with Ansible version `2.15.5`. + +Install Ansible dependencies: + +```bash +ansible-galaxy collection install kubernetes.core +``` + +Install Python dependencies: +```bash +pip3 install kubernetes +``` + +## Ansible inventory + +An example inventory file is present in `k8s/inventory/group_vars/all/squest.yml`. + +For a minimal installation you need to at least provide information concerning your Kubernetes environment +```yaml +k8s_kubeconfig_path: "/path/to/kubeconfig" +k8s_cluster_fqdn: "k8s.domain.local" +squest_namespace: "squest" +k8s_storage_class: "thin" +``` + +## Deploy Squest using Ansible + +Run the `deploy` playbook against your inventory config file: + +```bash +cd k8s +ansible-playbook -v -i inventory deploy.yml +``` + +**Tags:** + +| Name | Description | +|-------------|---------------------------------------------| +| namespace | Create the Squest namespace | +| utils | Install CRD utils (certmanager, Prometheus) | +| db | Deploy mariadb CRDs, operator and server | +| rabbitmq | Deploy rabbitmq CRDs, operator and service | +| redis | Deploy redis CRDs, operator and service | +| django | Deploy Squest application | +| celery | Deploy Celery components (worker and beat) | +| maintenance | Deploy nginx maintenance pod | +| backup | Deploy backup cron jobs | + + +!!! note + + By default, the deployment uses **nginx ingress controller** to configure the Squest external access on `squest.{{ k8s_cluster_fqdn }}`. + +## Configuration + +### Squest config + +The [Squest configuration](../configuration/squest_settings.md) is injected as environment variables. The environment is placed in `squest.yml` as `env` flag like the following: +```yaml +squest_django: + env: + TZ: "Europe/Paris" + DB_HOST: "mariadb" + DB_PORT: "3306" + REDIS_CACHE_HOST: "rfrm-redis" + DEBUG: "true" + DB_USER: "{{ squest_db.user }}" + DB_PASSWORD: "{{ squest_db.password }}" + WAIT_HOSTS: "mariadb:3306,rabbitmq:5672" +``` + +### Use your own ingress + +By default, the playbook will configure an ingress that point to `squest.{{ k8s_cluster_fqdn }}` based on the [nginx ingress controller](https://docs.nginx.com/nginx-ingress-controller/). + +To expose the Squest URL by using your own ingress controller, you can either update `annotations` (when the target controller can be managed by annotations) or disable the default ingress to declare then your ingress rules on your own. + +To disable the default ingress configuration, in the `squest.yml` inventory file: +```yaml +squest_django: + image: "quay.io/hewlettpackardenterprise/squest:latest" + ingress: + enabled: false +``` diff --git a/docs/configuration/ldap.md b/docs/manual/advanced/ldap.md similarity index 81% rename from docs/configuration/ldap.md rename to docs/manual/advanced/ldap.md index 6bd48f8ea..5c997c83a 100644 --- a/docs/configuration/ldap.md +++ b/docs/manual/advanced/ldap.md @@ -1,9 +1,9 @@ -# LDAP authentication backend +# LDAP ## Default configuration The configuration is loaded from environment variables file placed in the folder `docker/environment_variables`. -Retrieve environment variables from the [Squest configuration settings documentation](../configuration/squest_settings.md#ldap) +Retrieve environment variables from the [Squest configuration settings documentation](../../configuration/squest_settings.md#ldap) ## Advanced configuration @@ -45,6 +45,9 @@ AUTH_LDAP_USER_ATTR_MAP = { } ``` +## Use custom config + +### Docker compose Update the `ldap.docker-compose.yml` file to mount your configuration file and the CA certificate of the LDAP server (if LDAPS is used) in django and celery containers: ```yaml @@ -66,3 +69,23 @@ Run docker compose with the ldap config ```bash docker-compose -f docker-compose.yml -f docker-compose.override.yml -f ldap.docker-compose.yml up ``` + +### Kubernetes + +Declare your custom configuration file in the `squest_django` section of `squest.yml` inventory: + +```yaml +squest_django: + ldap: # extra ldap config + ldap_config_file: "{{ lookup('file', playbook_dir + '/../Squest/ldap_config.py') }}" +``` + +Push the new configuration +``` +ansible-playbook -v -i inventory deploy.yml --tags django +``` + +Rollout django pod +``` +kubectl rollout restart -n squest deployment/django +``` diff --git a/k8s/inventory/group_vars/all/squest.yml b/k8s/inventory/group_vars/all/squest.yml index 8690b344d..41c7db5a1 100644 --- a/k8s/inventory/group_vars/all/squest.yml +++ b/k8s/inventory/group_vars/all/squest.yml @@ -39,16 +39,16 @@ squest_redis: # Django squest_django: image: "quay.io/hewlettpackardenterprise/squest:latest" - ingress: + ingress: # default ingress based on nginx controller enabled: true host: "squest.{{ k8s_cluster_fqdn }}" annotations: kubernetes.io/ingress.class: "nginx" ingress.kubernetes.io/ssl-redirect: "true" nginx.ingress.kubernetes.io/backend-protocol: "HTTP" -# ldap: +# ldap: # extra ldap config # ldap_config_file: "{{ lookup('file', playbook_dir + '/../Squest/ldap_config.py') }}" - env: + env: # squest settings TZ: "Europe/Paris" DB_HOST: "mariadb" DB_PORT: "3306" @@ -57,10 +57,10 @@ squest_django: DB_USER: "{{ squest_db.user }}" DB_PASSWORD: "{{ squest_db.password }}" WAIT_HOSTS: "mariadb:3306,rabbitmq:5672" - backup: + backup: # backup squest db and media to a PVC enabled: false crontab: "0 1 * * *" - externalize_backup_via_rsync: + externalize_backup_via_rsync: # rsync backup files into and external server enabled: false crontab: "30 1 * * *" private_ssh_key: "{{ lookup('file', '/path/to/id_ed25519_squest_k8s_dev') + '\n' }}" diff --git a/mkdocs.yml b/mkdocs.yml index 0b9b79287..5abb5f6e0 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -28,12 +28,11 @@ markdown_extensions: nav: - Home: index.md + - Installation: + - Docker compose: installation/docker-compose.md + - Kubernetes: installation/kubernetes.md - Getting Started: getting_started.md - - Configuration: - - Squest: configuration/squest_settings.md - - LDAP: configuration/ldap.md - - TLS: configuration/tls.md - - OpenID Connect: configuration/openid.md + - Configuration: configuration/squest_settings.md - Manual: - Service catalog: - Concept: manual/service_catalog/concept.md @@ -55,6 +54,7 @@ nav: - manual/advanced/filters.md - manual/advanced/jinja.md - manual/advanced/validators.md + - manual/advanced/ldap.md - Notifications: manual/notifications.md - Administration: - Backup: administration/backup.md