Installing on AWS EKS Environment
1. Overview
1.1 Purpose
- Guide for the entire process of installing and configuring QueryPie on AWS EKS cluster
- Provide configuration guide for stable operation
1.2 Target Audience
- Engineers who understand basic Kubernetes concepts (Pod, Service, Deployment, etc.)
- Engineers with AWS EKS experience
1.3 Estimated Time
- Entire installation process: approximately 1 hour
- Environment configuration: 15 minutes
- Basic component (MySQL, Redis) installation: 15 minutes
- QueryPie installation: 20 minutes
- Installation verification and initial configuration: 10 minutes
2. Prerequisites
2.1 Infrastructure Requirements
- EKS cluster
- Recommended node specifications: m7i.xlarge (4 vCPU, 16GB RAM)
- Kubernetes version: 1.24 or higher
- Required number of nodes: minimum 1 (3 or more recommended for production environments)
2.2 Local Environment Preparation
AWS CLI installation and configuration
brew install awscli
aws configure # Requires Access Key and Secret Keykubectl installation
brew install kubectlHelm installation (version 3.10.0 or higher required)
brew install helmOptional tools installation (recommended)
brew install kubectx # Context switching tool
brew install fzf # Command-line fuzzy finder2.3 Access Permission Requirements
Container Registry access permissions
- Docker Hub: Public images available without authentication (
docker.io/querypie) - Harbor: Separate account information required (
harbor.chequer.io)- Account information (Username/Password)
- QueryPie image access permissions
2.4 Network Requirements
- Internet connection (for image download)
- Network environment accessible to EKS cluster
- Environment where LoadBalancer can be used (for Ingress configuration)
3. Basic Component Installation
Before starting, create namespaces for QueryPie installation.
kubectl create namespace querypie3.1 MetaDB (MySQL) Installation
MySQL is used as the database that stores QueryPie’s metadata.
3.1.1 Create Persistent Volume
Create a pv.yml file with the following content.
apiVersion: v1
kind: PersistentVolume
metadata:
name: local-pv
labels:
app: mysql
spec:
capacity:
storage: 50Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /var/lib/mysql
type: DirectoryOrCreateCreate PV.
kubectl apply -f pv.yml3.1.2 Deploy MySQL StatefulSet
Create a mysql.yml file with the following content. Set the MYSQL_PASSWORD password according to your company’s policy.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
namespace: querypie
spec:
selector:
matchLabels:
app: mysql
serviceName: mysql
replicas: 1
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
env:
- name: MYSQL_ROOT_PASSWORD
value: querypie
- name: MYSQL_DATABASE
value: querypie
- name: MYSQL_USER
value: querypie
- name: MYSQL_PASSWORD
value: "{your-mysql-password}"
resources:
requests:
cpu: "0.5"
memory: "2Gi"
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: data
mountPath: /var/lib/mysql
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 50Gi
storageClassName: ""
selector:
matchLabels:
app: mysql
---
apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: querypie
labels:
app: mysql
spec:
type: ClusterIP
selector:
app: mysql
ports:
- port: 3306
targetPort: 3306
protocol: TCP
name: mysqlCreate MySQL StatefulSet and Service.
kubectl apply -f mysql.ymlWait until MySQL Pod runs normally.
kubectl get pods -w -n querypie | grep mysql3.1.3 Database Initialization
Connect to MySQL.
kubectl exec -it mysql-0 -n querypie -- mysql -u root -p
# The password is {your-mysql-password} in above example.Create necessary databases.
DROP DATABASE IF EXISTS querypie;
DROP DATABASE IF EXISTS querypie_log;
DROP DATABASE IF EXISTS querypie_snapshot;
CREATE database querypie CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE database querypie_log CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE database querypie_snapshot CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
GRANT ALL privileges ON querypie.* TO querypie@'%';
GRANT ALL privileges ON querypie_log.* TO querypie@'%';
GRANT ALL privileges ON querypie_snapshot.* TO querypie@'%';
FLUSH PRIVILEGES;Exit MySQL.
exit3.2 Redis Installation
Redis is used as QueryPie’s session and cache storage.
Create a redis.yml file with the following content. Set {your-redis-password} according to your company’s policy.
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: querypie
labels:
app: redis
spec:
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:7
imagePullPolicy: IfNotPresent
args: ["--requirepass", "{your-redis-password}"]
ports:
- containerPort: 6379
protocol: TCP
resources:
limits:
cpu: "0.1"
memory: "1Gi"
volumeMounts:
- name: redis-data
mountPath: /data
restartPolicy: Always
volumes:
- name: redis-data
emptyDir: {}
# Data is deleted on pod restart. It is OK for cache purposes.
---
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: querypie
labels:
app: redis
spec:
type: ClusterIP
selector:
app: redis
ports:
- port: 6379
targetPort: 6379
protocol: TCPCreate Redis Deployment and Service.
kubectl apply -f redis.ymlWait until Redis Pod runs normally.
kubectl get pods -w -n querypie | grep redis4. QueryPie Installation
4.1 Secret Configuration
4.1.1 Register Container Registry Authentication Information
When using Docker Hub
If using public images from Docker Hub, you can skip this step. Setting registry: docker.io in values.yaml allows you to download images without authentication.
When using Harbor
If using Harbor registry, register authentication information with the following command.
kubectl create secret docker-registry querypie-regcred \
--docker-server=harbor.chequer.io \
--docker-username='{harbor-id}' \
--docker-password='{harbor-pw}' \
-n querypie4.1.2 QueryPie Environment Configuration
Create a querypie.env file with the following content.
Refer to the environment variables guide: Container Environment Variables
# Agent Secret (32-character random string)
AGENT_SECRET=01234567890123456789012345678912
KEK=querypie
# QueryPie Meta DB connection info
DB_CATALOG=querypie
DB_HOST=mysql
DB_USERNAME=querypie
DB_PASSWORD={your-mysql-password}
DB_PORT=3306
# QueryPie Log DB connection info
LOG_DB_CATALOG=querypie_log
LOG_DB_HOST=mysql
LOG_DB_USERNAME=querypie
LOG_DB_PASSWORD={your-mysql-password}
LOG_DB_PORT=3306
# QueryPie Snapshot DB connection info
ENG_DB_CATALOG=querypie_snapshot
ENG_DB_HOST=mysql
ENG_DB_USERNAME=querypie
ENG_DB_PASSWORD={your-mysql-password}
ENG_DB_PORT=3306
# Redis connection info
REDIS_NODES=redis:6379
REDIS_PASSWORD={your-redis-password}Register the environment configuration file as a Secret.
kubectl create secret generic querypie-secret --from-env-file=querypie.env -n querypie4.2 Helm Chart Configuration
4.2.1 Add Helm Repository
# Add repository
helm repo add querypie https://chequer-io.github.io/querypie-deployment/helm-chart
# Verify repository list
helm repo list4.2.2 values.yaml Configuration
Create a values.yml file with the following content.
Note: The example below is based on using Docker Hub.
When using Harbor Registry, change to registry: harbor.chequer.io.
Refer to the Product Versions document to specify the product version to install.
# -- appVersion: QueryPie version to install. This is an example value.
# -- Please refer to the Product Versions document for available versions.
appVersion: &version 11.5.1
global:
image:
# -- Default registry used for all images
# For Docker Hub: docker.io
# For Harbor: harbor.chequer.io
registry: docker.io
# -- Default image tags used for all images
tag: *version
# -- Default image pull policy for all images
pullPolicy: IfNotPresent
# -- Default labels for all resources deployed by the chart
labels: {}
# -- ServiceAccount for QueryPie and QueryPie tools pods
# It is created for authenticating private image registry and AWS API.
# @default -- {}
serviceAccount:
labels: {}
annotations: {}
# -- The name of the secret used for pulling the QueryPie image from the private registry.
# For Docker Hub: Set imagePullSecrets to an empty array ([]) or remove this section.
# For Harbor: Create the querypie-regcred secret and uncomment below.
imagePullSecrets: []
# Uncomment below when using Harbor registry:
# imagePullSecrets:
# - name: querypie-regcred
querypie:
# -- Labels used for QueryPie pods.
labels: {}
# -- Annotations used for QueryPie pods.
annotations: {}
tolerations: {}
# -- NodeSelector for QueryPie pods
nodeSelector: {}
replicas: 1
# -- PodManagementPolicy for QueryPie pods. OrderedReady is fine for most cases, but Parallel is also good for large-scale deployments.
podManagementPolicy: Parallel
image:
# -- (string) Registry used for the QueryPie image. If not set, the global registry will be used.
registry:
# -- (string) Tag used for the QueryPie image. If not set, the global tag will be used.
tag:
# -- (string) PullPolicy used for the QueryPie image. If not set, the global pullPolicy will be used.
pullPolicy:
# -- Repository used for the QueryPie image. (required)
repository: querypie/querypie
ingress:
# -- (bool) If true, Ingress resource for QueryPie will be created.
enabled: true
labels: {}
# -- Annotations used for the Ingress resource.
# It is useful when you want to enable controller-specific feature for the Ingress resource.
annotations: {}
# -- (string) Class used for the Ingress resource. If not set, the default class will be used.
ingressClassName: ""
# -- Hostname used for the Ingress resource. If not set, every hostname will be accepted.
host: querypie.querypie.io # Replace with your actual URL
# -- Extra paths used for the Ingress resource.
# It is mostly used for redirecting HTTP to HTTPS if the ingress controller does not support redirect by default.
proxyService:
# -- Create a service resource for QueryPie Agent connections.
# Basically, it opens 9000/tcp port for the QueryPie Agent, and 40000~/tcp for the Agentless connections.
enabled: true
labels: {}
# -- Annotations used for the Service resource.
# It is useful when you want to enable controller-specific feature for the Service resource.
annotations: {}
type: LoadBalancer
loadBalancerClass: ""
# -- Set the externalTrafficPolicy to Local is recommended for auditing the real client IP address.
externalTrafficPolicy: "Local"
# -- SessionAffinity is not required for the QueryPie.
sessionAffinity: "None"
updateStrategy:
# -- The strategy used for updating the QueryPie pods.
# It is generally recommended to use the RollingUpdate strategy.
# But if required, you can change it to OnDelete for manual operations.
type: RollingUpdate
resources:
requests:
cpu: "2000m"
memory: 16Gi
limits:
# -- More than 2 CPU cores are recommended.
cpu: "2000m"
# -- More than 16Gi memory is recommended.
memory: 16Gi
# -- Logrotator configuration
# Starting from version 11.3.0, log rotation is built into the main container.
# The logrotator image is only available on Harbor registry.
# When using Docker Hub, this must be disabled.
logrotator:
enabled: false
# Uncomment below and set enabled: true when using Harbor registry:
# image:
# repository: querypie/logrotate
# tag: latest
# -- External storage for the QueryPie Object Storage.
externalStorage:
# -- Type of the external storage.
# - none: No external storage.
# - persistentVolumeClaim: using a single Persistent Volume Claim for all QueryPie pods.
type: none
# -- Use a persistent volume claim for the external storage. It will be available if the type is persistentVolumeClaim.
persistentVolumeClaim:
# -- Use an existing Persistent Volume Claim for the external storage.
# If you set this to true, this helm chart will not create a new Persistent Volume Claim.
useExisting: false
# -- The name of the existing Persistent Volume Claim to be used.
claimName: ""
# -- Metadata of the Persistent Volume Claim.
metadata:
annotations: {}
labels: {}
# -- Spec of the Persistent Volume Claim.
spec:
storageClassName: ""
resources:
requests:
storage: 100Gi
# -- It is required to have ReadWriteMany access mode on production.
accessModes:
- ReadWriteMany
# -- Extra environment variables used for the QueryPie pods.
# This is useful for experimental features, debugging, workaround, and so on.
# for example:
# API_JVM_HEAPSIZE: '2g' will set the JVM heap size to 2GB.
extraEnvs: {}
tools:
image:
# -- Registry used for the QueryPie tools image. If not set, the global registry will be used.
repository: querypie/querypie-tools
config:
# -- External URL that users use to access the QueryPie via web.
# Specify the scheme, hostname, and port is required.
externalURL: "https://querypie.querypie.io" # Replace with your actual URL
secretName: "querypie-secret"
database:
querypie:
# -- The maximum number of connections that QueryPie can use for "metastore" purposes.
connectionPoolSize: 20
dac:
# -- This setting is used to ignore simple queries sent by client tools such as DataGrip.
# Please refer to the commented-out example below.
skipCommandConfigData: "{}"
# skipCommandConfig: |
# {
# "mysql": [
# "^(/\\*.*?\\*/)?\\s*SELECT\\s+@@session\\s*\\.\\s*\\w+\\s*$",
# "^(/\\*.*?\\*/)?\\s*SET\\s+session\\s+transaction\\s+\\w+(\\s+\\w+)*\\s*$",
# "^(/\\*.*?\\*/)?\\s*SET\\s+net_write_timeout\\s*=\\s*\\d+\\s*$",
# "^(/\\*.*?\\*/)?\\s*SELECT\\s+database\\s*\\(\\s*\\)\\s*$",
# "^(/\\*.*?\\*/)?\\s*SET\\s+SQL_SELECT_LIMIT\\s*=\\s*\\w+$",
# "^SHOW\\s+VARIABLES\\s+LIKE\\s+'aurora\\\\_version'\\s*$",
# "^SELECT\\s+version\\s*\\(\\s*\\)\\s*,\\s*@@version_comment\\s*,\\s*database\\s*\\(\\s*\\)\\s*$",
# "^SET\\s+autocommit\\s*=\\s*\\d+$",
# "^(/\\*.*?\\*/)\\s*SELECT\\s+((@@session\\s*\\.\\s*|@@)\\w+(\\s+AS\\s+\\w+)?(\\s*,\\s*)?)+\\s*$"
# ]
# }
# -- The path where the skip command config file will be mounted.
skipCommandConfigFile: /app/arisa/skip_command_config.json4.3 QueryPie Installation
Install QueryPie ACP using Helm.
Select the Helm version according to the Product Versions of QueryPie ACP.
- QueryPie ACP 11.3.0 or later: Use the latest version of Helm Chart 1.5.0 or higher.
- QueryPie ACP before 11.3.0: Use Helm Chart 1.4.4.
The Chart version in this document is provided as an example.
helm upgrade --install poc querypie/querypie --version 1.5.0 -n querypie -f values.yamlRun database migration.
This step must be executed.
If not executed, the error Table 'querypie.system_settings' doesn't exist will occur and the QueryPie Pod will not start normally.
This command creates the required schema and initial data in the MySQL database.
kubectl exec -it deployments/poc-querypie-tools -n querypie -- /app/script/migrate.sh runall4.4 Installation Verification
Check Pod status.
kubectl get pods -n querypieCheck logs.
kubectl logs pod/poc-querypie-0 -fCheck service access.
kubectl port-forward -n querypie statefulsets/poc-querypie 80:80Then proceed with initial setup.
- License Installation
- Refer to Post Installation Setup document to proceed with common settings and product-specific settings.
This completes the product installation process. Great job!
5. Troubleshooting Guide
5.1 Pre-Installation Checks
5.1.1 Check Cluster Access Permissions
# Verify cluster access
kubectl cluster-info
# Check current context
kubectl config current-context
# Verify namespace access permissions
kubectl auth can-i create deployment -n querypie5.1.2 Check Resource Status
# Check node resource status
kubectl top nodes
# Check available storage classes
kubectl get storageclass5.2 General Troubleshooting
5.2.1 Check Pod Status
# Check pod status
kubectl get pods -n querypie
# Check pod details
kubectl describe pod <pod-name> -n querypie
# Check pod logs
kubectl logs <pod-name> -n querypie
kubectl logs <pod-name> -n querypie --previous # Check previous logs if restartedKey problem statuses and checks:
ImagePullBackOff: Check Container Registry authentication information- When using Docker Hub: Check
registry: docker.iosetting invalues.yaml, verifyimagePullSecrets: []setting - When using Harbor: Verify
querypie-regcredSecret creation logrotatorimage error: Checklogrotator.enabled: falsesetting (logrotator image is not provided on Docker Hub)
- When using Docker Hub: Check
Pending: Check if node resources are insufficientCrashLoopBackOff: Check application errors through logsTable 'querypie.system_settings' doesn't existerror: DB migration not executed → Need to runmigrate.sh runallcommand
5.2.2 Check Service Connections
# Check service status
kubectl get svc -n querypie
# Check endpoints
kubectl get endpoints -n querypie
# Test MySQL service connection
kubectl exec -it mysql-0 -- mysql -u querypie -p -h mysql querypie
# Test Redis service connection
kubectl exec -it $(kubectl get pod -l app=redis -o jsonpath='{.items[0].metadata.name}') -- redis-cli -a querypie ping5.2.3 Check Ingress
# Check ingress status
kubectl get ingress -n querypie
# Check ingress details
kubectl describe ingress -n querypie5.3 Resource Monitoring
# Check pod CPU/Memory usage
kubectl top pods -n querypie
# Check node CPU/Memory usage
kubectl top nodes
# Check resource limits for a specific pod
kubectl get pod <pod-name> -n querypie -o jsonpath='{.spec.containers[0].resources}'5.4 Check Installation Configuration
# Check ConfigMap
kubectl get configmap -n querypie
# Check Secret list
kubectl get secrets -n querypie
# Check PV/PVC status
kubectl get pv
kubectl get pvc -n querypie5.5 Information Required for Support Requests
If troubleshooting is difficult, collect the following information and contact the support team:
5.5.1 Environment Information
# Kubernetes version
kubectl version --short
# Node information
kubectl get nodes -o wide
# Helm version
helm version5.5.2 QueryPie Status Information
# Helm deployment status
helm status poc -n querypie
# Pod details
kubectl describe pod/poc-querypie-0 -n querypie
# Recent events list
kubectl get events -n querypie --sort-by='.lastTimestamp'5.5.3 Log Information
# Save QueryPie logs
kubectl logs pod/poc-querypie-0 -n querypie > querypie.log
# Save related component logs
kubectl logs mysql-0 > mysql.log
kubectl logs $(kubectl get pod -l app=redis -o jsonpath='{.items[0].metadata.name}') > redis.log