Reports Server

Reports server provides a scalable solution for storing policy reports and cluster policy reports. It moves reports out of etcd and stores them in an alternate database instance.

Why Reports Server?

Before understanding the benefits of reports server, it is essential to have a look at the reasons that makes moving reports out of etcd desirable.

Leaving etcd

The following reasons to move reports out of etcd are listed below:

  • The etcd database currently has a maximum size of 8GB. Reports tend to be relatively large objects, but even with very small reports, the etcd capacity can be easily reached in larger clusters with many report producers.
  • Under heavy report activity (e.g. cluster churn, scanning, analytical processes, etc.), the volume of data being written and retrieved by etcd requires the API server to buffer large amounts of data. This compounds existing cluster issues and can cascade into complete API unavailability.
  • CAP guarantees are not required for reports. At present, they are understood to be ephemeral data that will be re-created if deleted.
  • Philosophically, report data is analytical in nature and should not be stored in the transactional database.

Benefits of reports server

  • Alleviation of the etcd along with API server load and capacity limitations.
  • Common report consumer workflows can be more efficient.
    a. Report consumers are often analytical and/or operate on aggregate data. The API is not designed to efficiently handle certain queries. For example, a query for all reports containing a vulnerability with a CVSS severity of 8.0 or above will not be handled efficiently. To perform such a query, a report consumer must retrieve and parse all of the reports. Retrieving a large volume of reports, especially with multiple simultaneous consumers, leads to the performance issues described previously.
    b. With reports stored in a relational database, report consumers could instead query the underlying database directly, using more robust query syntax.
    c. This would improve the implementation of, or even replace, the need for certain exporters and enable new reporting use cases.

Prerequisites

  • Helm: Refer to the official docs for installation.
  • Kubernetes Cluster: Any CNCF compliant Kubernetes distribution.

Installation

Reports Server can be installed using the following ways:

  • YAML Manifest: YAML manifest is the recommended method to install reports server when kyverno or policy reports CRDs are already installed in the cluster.
  • Helm Chart: Helm chart is the most flexible installation method as it offers a wide range of configurations.

This guide shows the installation of reports server using Helm chart for different configurations and also discusses ways to migrate to reports server using YAML manifests for the existing kyverno-installed cluster.

Installing Reports Server using multiple configurations

There are three configuration to install reports server:

  • Reports server with managed postgres: Use a centralised postgres database outside of the cluster.
  • Reports server with incluster postgres: Create a postgres instance in the cluster.
  • Reports server with inmemory reports store: Store reports in the memory of reports server pod.

Managed Postgres

Reports server can be configured to work with any postgres instance in and out of the cluster. Install reports server with a postgres instance outside of the cluster with helm by creating a namespace and installing the reports-server chart. The following command does that:

helm repo add rs https://nirmata.github.io/reports-server/
helm repo update
helm install reports-server --namespace reports-server --create-namespace  rs/reports-server \
        --set image.tag=latest \
        --set postgresql.enabled=false \
        --set config.db.host=<HOST_NAME> \
        --set config.db.name=<DB_NAME> \
        --set config.db.user=<POSTGRES_USERNAME> \
        --set config.db.password=<POSTGRES_PASSWORD> \
        --set config.db.sslmode=<SSL_MODE>

Note: Get the values for hostname, dbname, postgres username, postgres password, and ssl mode from managed postgres and fill the values in helm values.

Managed Postgres in AWS

Reports Server can be installed with managed postgres in AWS. Create a postgres instance in AWS using Amazon RDS and install the reports-server chart using the above command. Refer to the official AWS documentation for creating the postgres instance. Get the hostname, dbname, postgres username, postgres password, etc., from the postgres instance and fill the values in helm values.

Incluster Database

Installation of reports server creates a postgres instance by default. But it is recommended to use a postgres operator for production environment. CloudNativePG is such an operator and this section of the guide will use CloudNativePG at the postgres operator alongside reports-server in the installation process. Install reports-server alongside CloudNativePG by following the below steps:

  1. A namespace is required for installing reports-server. Create the required namespace using the following command:
kubectl create ns reports-server
  1. Next, install CloudNativePG by using one of their recommended installation methods. Here, the operator is installed directly through a YAML manifest, applied via kubectl. More information on CloudNativePG installation can be found from their official documentation. The following command installs CloudNativePG:
kubectl apply -f \
  https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-1.18/releases/cnpg-1.18.5.yaml
  1. Now, wait for all pods for the CloudNativePG controller to start. Apply the following command:
kubectl wait pod --all --for=condition=Ready --namespace=cnpg-system
  1. Next, create a CloudNativePG postgres cluster using:
kubectl create -f config/samples/cnpg-cluster.yaml
  1. After that, install the reports-server chart by applying:
helm repo add rs https://nirmata.github.io/reports-server/
helm repo update
helm install reports-server --namespace reports-server --create-namespace  rs/reports-server \
        --set image.tag=latest \
        --set postgresql.enabled=false \
        --set config.db.host=reports-server-cluster-rw.reports-server \
        --set config.db.name=reportsdb \
        --set config.db.user=$(kubectl get secret -n reports-server reports-server-cluster-app --template={{.data.username}} | base64 -d) \
        --set config.db.password=$(kubectl get secret -n reports-server reports-server-cluster-app --template={{.data.password}} | base64 -d)

(Optional) To install reports-server without CNPG, use the following command:

helm install reports-server -n reports-server --create-namespace --wait ./charts/reports-server \
                             --set image.tag=latest \
                             --set config.db.name=reportsdb

Note: The location of the stored reports can be checked by getting into the postgres pod by means of the exec command.

The following command execs into the postgres pod:

kubectl exec -it reports-server-postgresql-0 -n reports-server -- psql -U postgres

After getting into the pod, connect to the database and query for specific data by applying:

\c reportsdb

Inmemory Storage

Reports server can be installed without any database as well. In this case, reports will be stored in the memory of reports-server pod.

Install reports-server with inmemory configuration by installing the reports-server chart through the following command:

helm repo add rs https://nirmata.github.io/reports-server/
helm repo update
helm install reports-server --namespace reports-server --create-namespace  rs/reports-server \
        --set image.tag=latest \
        --set config.debug=true \
        --set postgresql.enabled=false

Migration from etcd to reports-server

Migrating an existing cluster using etcd to store policy reports to reports-server can be done by means of a YAML manifest.

Migration is applicable for the following conditions:

  • The cluster has kyverno already installed.
  • The cluster has policy reports crds already installed.

Note: Clusters with policy reports CRDs have existing API services for policy reports which need to be overwritten for reports-server to work. It is done by applying new api services with the label kube-aggregator.kubernetes.io/automanaged: "false".

Migrate to reports server on the existing cluster by directly installing the YAML manifest using kubectl apply. The installation will overwrite the existing API services. Run the following command to install the YAML manifest:

kubectl apply -f https://raw.githubusercontent.com/nirmata/reports-server/main/config/install.yaml