Deploying Eggplant DAI in Containers

This section provides step-by-step instructions to deploy Eggplant DAI in Kubernetes containers using Helm.

Before You Begin

The configuration for deploying Eggplant DAI in Kubernetes containers is dependent on the mode you choose to run Eggplant DAI in:

  • Quick Trial Mode – This mode includes ephemeral containers for PostgreSQL, RabbitMQ and Minio.
  • Production Mode – This mode includes an external PostgreSQL cluster. Note that the RabbitMQ and Minio instances must be backed by provisioning persistent storage.

Quick Trial Mode

You must have the following prerequisites in place:

  • The Kubernetes cluster where you want to install Eggplant DAI. The kubectl command-line tool is installed and configured to work with your cluster (it should be compatible with your cluster version). You can confirm it's working correctly by using the following command:
  • $ kubectl cluster-info
    Kubernetes master is running at https://cluster.example.com

  • The helm command-line tool. The following instructions assume that you've installed Helm version 3.
  • Your Eggplant DAI license key. Contact your Eggplant representative if you do not have the license key.
  • Your Eggplant service token and JWT secret. Contact your Eggplant representative if you do not have these.

Note: The Helm chart has an option to provision a container based temporary database inside the Kubernetes namespace instead of providing external database parameters. While it is not recommended to use this approach in production environments, it can be useful for development and testing. Note that this database is ephemeral; it will be destroyed if the Helm chart is deleted.

Preparation

Complete these steps to prepare your working environment before installing Eggplant DAI.

Add the Eggplant Helm repository

Add the Eggplant Helm Chart repository to your Helm environment:

$ helm repo add eggplant https://charts.dai.eggplant.cloud
"eggplant" has been added to your repositories.

If you already have the repository e.g., if upgrading an existing installation, ensure that it is up to date by using this command:

helm repo update

Create a Kubernetes namespace

Eggplant DAI installs into a new namespace on your Kubernetes cluster. These instructions use dai, but you can use another name if you prefer.

Note: If you have multiple Kubernetes clusters, remember to select the cluster where you wish to install Eggplant DAI.

Create this namespace:

$ kubectl create namespace dai
namespace/dai created

Then, set it as your current Kubernetes context:

$ kubectl config set-context --current --namespace=dai
Context modified

Prepare Helm Configuration

You must define values for the required settings in the Helm chart by using a configuration file. Use any text editor to create a file with the following content, replacing each <placeholder> with its appropriate value. The sample file is named as dai.yaml in these instructions, but you can choose a name of your preference. If you're upgrading an existing installation, then you should generate this file from your existing installation as described further below.

Note: The file is in YAML format and its.yaml suffix follows the convention for YAML-formatted files.
global:

license: 'license'

serviceToken: '<token>'

jwtSecret: '<secret>'

postgresql:

enabled: true

image:

tag: '5.1.0'

ingress:

enabled: true

hostnames:

- '<ingress hostname>'

rabbitmq:

password: '<rabbitmq password>'

erlangCookie: '<rabbitmq cookie>'

Where,

  • license is your DAI license key string supplied by Eggplant.
  • tag is the version of Eggplant DAI to install. Don’t change this value unless advised to do so by Eggplant.
  • <ingress hostname> is the ingress hostname for your Kubernetes DAI namespace. You must supply this value as appropriate for your Kubernetes cluster.
  • <token> is your DAI service token, as supplied by Eggplant.
  • <secret> is your DAI JWT secret, as supplied by Eggplant.
  • <rabbitmq password> iis the password of your choice to use for RabbitMQ.
  • <rabbitmq cookie> is the 30-byte cookie (base-64 encoded) you need to supply for RabbitMQ to use (e.g., to generate: head -c30 /dev/urandom | base64).

Production Mode

You must have the following prerequisites in place:

  • The Kubernetes cluster where you want to install Eggplant DAI. The kubectl command-line tool is installed and configured to work with your cluster (it should be compatible with your cluster version). You can confirm if it's working correctly by using the following command:
  • $ kubectl cluster-info
    Kubernetes master is running at https://cluster.example.com
  • The helm command-line tool. These instructions assume that you've installed Helm version 3.
  • Your Eggplant DAI license key. Contact your Eggplant representative if you do not have the license key.
  • Your Eggplant service token and JWT secret. Contact your Eggplant representative if you do not have these.
  • Credentials, hostname, and port for an empty PostgreSQL database. The database username and the database name must match, and the user must have full control over the database. Eggplant recommends using PostgreSQL version 11.5. Ensure the pgcrypto and uuid-ossp extensions are installed as these are required by the application.
  • Note: The Helm chart has an option to provision a container-based temporary database, although it is not the recommended approach for production environments.

  • A persistent storage solution, if required for production use, for the asset management and screenshot services.

Preparation

Complete these steps to prepare your working environment before installing Eggplant DAI.

Add the Eggplant Helm repository

Add the Eggplant Helm Chart repository to your Helm environment:

$ helm repo add eggplant https://charts.dai.eggplant.cloud
"eggplant" has been added to your repositories.

If you already have the repository e.g., if upgrading an existing installation, ensure that it is up to date by using this command:

helm repo update

Create a Kubernetes namespace

Eggplant DAI installs into a new namespace on your Kubernetes cluster. These instructions use dai, but you can use another name if you prefer.

Note: If you have multiple Kubernetes clusters, remember to select the cluster where you wish to install Eggplant DAI.

Create this namespace:

$ kubectl create namespace dai
namespace/dai created

Then, set it as your current Kubernetes context:

$ kubectl config set-context --current --namespace=dai
Context modified

Prepare Helm Configuration

You must define values for the required settings in the Helm chart by using a configuration file. Use any text editor to create a file with the following content, replacing each <placeholder> with its appropriate value. The sample file is named as dai.yaml in these instructions, but you can choose a name of your preference. If you're upgrading an existing installation, then you should generate this file from your existing installation as described further below.

Note: The file is in YAML format and its .yaml suffix follows the convention for YAML-formatted files.

global:

license: 'license'

serviceToken: '<token>'

jwtSecret: '<secret>'

postgresql:

enabled: false

externalDatabase:

host: '<database hostname>'

user: '<database username>'

password: '<database password>'

port: <database port>

image:

tag: '5.1.0'

ingress:

enabled: true

hostnames:

- '<ingress hostname>'

minio:

persistence:

enabled: true

rabbitmq:

password: '<rabbitmq password>'

erlangCookie: '<rabbitmq cookie>'

persistence:

enabled: true

Where,

  • license is your DAI license key string supplied by Eggplant.
  • <database hostname> <database username> <database password> <database port> are parameters required to access your PostgreSQL database.
  • tag is the version of Eggplant DAI to install. Don’t change this value unless advised to do so by Eggplant.
  • <ingress hostname> is the ingress hostname for your Kubernetes DAI namespace. You must supply this value as appropriate for your Kubernetes cluster.
  • <token> is your DAI service token, as supplied by Eggplant.
  • <secret> is your DAI JWT secret, as supplied by Eggplant.
  • <rabbitmq password> is the password of your choice to use for RabbitMQ.
  • <rabbitmq cookie> is the 30-byte cookie (base-64 encoded) you need to supply for RabbitMQ to use (e.g., to generate: head -c30 /dev/urandom | base64).

If you don't want to use external database configurations, then you can set the following setting to true in the dai.yaml file:

postgresql:
enabled: true

Ensure that you can access the PostgreSQL database using the following psql command line, for example:

$ psql -h <database hostname> -U <database username>
Note: Ensure that the database is named the same as <database username>.

For a full list of configurable values for MinIO and RabbitMQ, refer to the MinIO and RabbitMQ subcharts.

Autoscaling

We recommend using Keda for engine autoscaling. To enable this, add the following setting in your values file:

keda:
enabled: true

You must install Keda V1 before installing the DAI chart.

The default configuration provides two engine replicas, which is configurable using the ai_engine.replicaCount parameter. See the Values table below for more information.

Note: KEDA version 2 is not supported at this time.

Upgrading Eggplant DAI from 4.x to 5.x

When upgrading from version 4.x to version 5.x, you should prepare your values file by exporting the settings used by your existing installation:

$ helm get values dai --namespace dai > dai.yaml

You'll need to edit the file to change the image tag for the upgrade version and to add the new parameters it requires so that your file reflects the example presented above:

  • Add your service token and jwt secret into the global section. As these parameters are new for version 5.x, they'll be supplied to you by Eggplant.

When upgrading, also add the following additional setting to provide your RabbitMQ credentials for the current installation:

rabbitmq:

password: '<rabbitmq password>'

erlangCookie: '<rabbitmq cookie>'

To obtain the values for these parameters:

$ kubectl get secret dai-rabbitmq -o json | jq -r '.data'

Before upgrading, we recommend taking a snapshot or backup of your database. The process of backing up your database itself depends on your local environment. Although this is optional, it's a recommended, step.

If you are upgrading from 4.0.0 then you will need to apply a change to your database. Using the information in the externaldatabase block in your values file, update this setting:

$ psql -h <host> -U <user> ttdb -c 'ALTER TABLE executionstatus ADD COLUMN modelid uuid'

Database

Ensure that you can access the PostgreSQL database using, for example, the following psql command line:

$ psql -h <database hostname> -U <database username>

Note: Ensure that the database is named the same as <database username>.

Before upgrading, we recommend taking a snapshot or backup of your database, but how you do this depends on your local environment. Note that this is an optional, but recommended step. You must also make the following amendment to your ttdb database:

ttdb=> ALTER TABLE executionstatus ADD COLUMN modelid uuid;

(If necessary, use \c ttdb to select the required ttdb database).

Installation

Install the DAI Helm chart using the prepared configuration file, like this:

$ helm install dai eggplant/dai --version 0.7.2 -f dai.yaml --namespace dai

or, to upgrade:

$ helm upgrade dai eggplant/dai --version 0.7.2 -f dai.yaml --namespace dai

The eggplant/dai chart is installed as a Helm release called (the first parameter) into the Kubernetes namespace, also called dai (the --namespace parameter), using the parameters supplied in the dai.yaml file is used as an example in these instructions, but you can use any name you prefer.

To watch the cluster building, use the following command.

$ watch kubectl get pods

All the items will display as Running after the cluster is built.

After Eggplant DAI is installed, you should use a web browser to access the ingress hostname specified in the configuration file.

Removal

Delete the Helm release to uninstall Eggplant DAI:

$ helm delete dai release
"dai" uninstalled

This deletes the Helm release previously installed as dai, leaving the Kubernetes namespace behind.

Note: If you configured an internal database, remember that this will also be removed. If you used an external database, however, removing Eggplant DAI does not affect it.

To also delete the namespace:

$ kubectl delete namespaces dai
namespace "dai" deleted

Troubleshooting

If you experience problems, you can view the Kubernetes event log:

$ kubectl get events --sort-by=.metadata.creationTimestamp

You can also view pods' logs, e.g., using the following command:

$ kubectl logs <pod name>

If logs show database connectivity problems, verify the parameters in dai.yaml. You may also want to confirm that the database access works as expected, with the supplied credentials, e.g., using psql :

$ psql -h <database hostname> -U <database username>

If you experience problems when accessing Eggplant DAI on a browser, you can confirm the ingress configuration. It should confirm the hostname specified in the configuration file:

$ kubectl get ingresses

Contact Eggplant Customer Support if you require further assistance.

Example deployment into an AWS EKS Cluster

The following section shows the contents of the sample DAI.yaml file that's been deployed into an AWS EKS Cluster using Service Broker to provision a S3 bucket for the suites and screenshots in Eggplant DAI. For information about the service broker itself, see the Amazon website.

global:
postgresql:

enabled: false

externalDatabase:

host: 'dai-example.eu-west-1.rds.amazonaws.com'

user: '<username>'

password: '<password>'

nodeSelector:

node-pool: 'application'

image:

tag: '5.1.0'

ingress:

enabled: true

hostnames:
- 'dai.example.com'
annotations:

kubernetes.io/ingress.class: 'nginx'

rewrite_annotations:

nginx.ingress.kubernetes.io/rewrite-target: /ai/auth

websocket_annotations:

nginx.ingress.kubernetes.io/affinity: cookie

nginx.ingress.kubernetes.io/proxy-read-timeout: "300"

nginx.ingress.kubernetes.io/session-cookie-expires: "172800"

nginx.ingress.kubernetes.io/session-cookie-max-age: "172800"

nginx.ingress.kubernetes.io/session-cookie-name: route

asset_manager:

s3:

provider: serviceBroker

bucketName: <S3 bucket name>

Chart Requirements

Key

Type

Default

https://charts.bitnami.com/bitnami

minio

3.4.x

https://charts.bitnami.com/bitnami postgresql 9.1.x
https://charts.bitnami.com/bitnami rabbitmq 7.5.x
https://charts.dai.eggplant.cloud common 0.1.x

Values

Key

Type

Default

Description

affinity object

{}

Pod affinity

asset_manager.s3.bucketName string "assets" Name of the bucket on S3/minio
externalBroker.host string nil RabbitMQ hostname Required if rabbitmq.enabled is false
externalBroker.password string nil RabbitMQ password Required if rabbitmq.enabled is false
externalBroker.port int 5672 RabbitMQ Server port
externalBroker.user string nil RabbitMQ user Required if rabbitmq.enabled is false
externalDatabase.existingSecret.keys.host string "db-hostname" Postgres database hostname
externalDatabase.existingSecret.keys.password string "db-password" Postgres database password
externalDatabase.existingSecret.keys.port string "db-port" Postgres database port
externalDatabase.existingSecret.keys.user string "db-username" Postgres database username
externalDatabase.existingSecret.name string nil Name of the secret
externalDatabase.host

string

nil

Postgres database hostname Required if postgres.enabled is false

externalDatabase.password

string

nil

Postgres database password Required if postgres.enabled is false

externalDatabase.port

int

5432

Postgres database server port

externalDatabase.user

string

nil

Postgres database username Required if postgres.enabled is false

externalDatabase.existingSecret.name

string

nil Name of the secret
externalDatabase.host

string

nil Postgres database hostname Required if postgres.enabled is false and externalDatabase.existingSecret is not defined
externalDatabase.password string nil Postgres database password Required if postgres.enabled is false and externalDatabase.existingSecret is not defined
externalDatabase.port int 5432 Postgres database server port
externalDatabase.user string nil Postgres database username Required if postgres.enabled is false and externalDatabase.existingSecret is not defined
fullnameOverride string nil String to fully override dai.fullname template
global.adminPassword

string

Random if not set

Password for the first user account created

global.adminUsername

string

"admin@eggplant.io"

Username for first user account created

global.is_cloud_deployment int 0 Default to OnPrem EULA display
global.jwtSecret Required nil jwtSecret
global.labels

list

[]

Add additional labels to all Kubernetes resources

global.license

Required for post install

nil

Product license key

global.postInstall

bool

true

(Optional) Perform post installation tasks

global.serviceToken Required nil serviceToken
image.password

string

nil

Password for private registry from image.registry

image.registry

string

"eggplantsoftware"

Registry path to pull images from

image.tag

string

Chart app version

Container image tag

image.username

string

nil

Username for private registry from image.registry

ingress.annotations

object

{}

Add annotations to the ingress objects

ingress.enabled bool false Enable to create ingress objects
ingress.hostnames list [] Bind ingress objects to specific hostname(s)
ingress.rewrite_annotations object {} Annotations for the /auth to /ai/auth rewrite, useful when working with annotation based services
ingress.tls list [] TLS configuration for ingress Secrets must be manually created in the namespace.
ingress.websocket_annotations object {} Annotations for the websocket ingress object, useful when working with annotation-based services
minio.clientImage.tag string "2020.5.6-debian-10-r8" bitnami/minio-client image version to use
minio.enabled boo true If enabled provides a MinIO deployment. If set to true also make sure asset_manager.s3.provider is set to minio.
minio.image.tag string "2020.5.16-debian-10-r0" bitnami/minio image version to use
minio.persistence.enabled bool false Use a PVC to persist data
nameOverride string nil String to partially override dai.fullname template (will maintain the release name)
nodeSelector object {} Node labels for pod assignment
objectStorage.aws.accessKey string nil IAM Secret Access Key
objectStorage.aws.existingSecret.keys.accessKeyName string nil IAM Access Key ID secret data key name (default is access-key)
objectStorage.aws.existingSecret.keys.secretKeyName string nil IAM Secret Key ID secret data key name (default is secret-key)
objectStorage.aws.existingSecret.name string nil Provide a secret with IAM credentials to access the S3 Bucket Overrides objectStorage.aws.accessKey and objectStorage.aws.secretKey
objectStorage.aws.region string eu-west-1 AWS Region of the S3 Bucket
objectStorage.bucketName string nil Overrides the component level configuration (ai_api.screenshots.bucketName and asset_manager.s3.bucketName), useful when working with a single bucket to store the screenshots and versioned assets
objectStorage.provider string minio Whether to use AWS S3 or MinIO for storing screenshots and versioned assets possible options are: minio or aws
postgresql.enabled bool true If enabled provides a postgres container Not for production use
postgresql.image.tag string "9.6" Postgresql image version to use
postgresql.servicePort int 5432 Postgresql server port
postgresql.persistence.enabled bool false Use a PVC to persist data
rabbitmq.auth.username string "backend" RabbitMQ application username
rabbitmq.enabled bool true If enabled provides a rabbitmq container Extend configuration for production use
rabbitmq.extraContainerPorts list [{"containerPort":15674,"name":"webstomp"}] Extra ports to be included in container spec
rabbitmq.extraPlugins string "rabbitmq_web_stomp rabbitmq_auth_backend_http rabbitmq_auth_backend_cache" Extra plugins to enable
rabbitmq.image.tag string "3.8.5" Rabbitmq image version to use
rabbitmq.persistence.enabled bool false Use a PVC to persist data
rabbitmq.service.extraPorts list [{"name":"webstomp","port":15674,"targetPort":"webstomp"}] Extra ports to expose in the service
securityContext object {} Security context for containers
sut_service.autoRefresh object {"enabled":true,"refreshSchedule":"0 7 * * *"} (Optional) Settings for enabling and configuring auto-refresh of the SUT Service (sut-refresh cron job).
sut_service.autoRefresh.enabled bool true (Optional) Enable or disable SUT Service auto-refreshing. If enabled, this will restart both sut-service and ai-api pods.
sut_service.autoRefresh.refreshSchedule string "0 7 * * *" (Optional) The schedule on which the sut-refresh cron job should be run. Default schedule is daily at 7am UTC.
tolerations list [] Node taints to tolerate

 

This topic was last updated on February 24, 2021, at 10:54:48 AM.

Eggplant icon Eggplantsoftware.com | Documentation Home | User Forums | Support | Copyright © 2021 Eggplant