How to deploy?
Introduction
This guide provides a step-by-step process to install the Sciamus Inventory Management System (IMS).
Prerequisites
Before starting the installation process, ensure the following prerequisites are met:
- Kubernetes Cluster - running K8s cluster is required. You can use cloud providers like GKE (opens in a new tab), EKS (opens in a new tab), AKS (opens in a new tab), or an on-premise setup.
- MongoDB - MongoDB database (version as described here) is required. You can use cloud offerings such as MongoDB Atlas (opens in a new tab), AWS DocumentDB (opens in a new tab), or an on-premise self-managed MongoDB instance.
- Helm - ensure Helm (opens in a new tab) is installed and configured to interact with your K8s cluster.
helm version- kubectl: Install and configure kubectl for K8s interaction.
kubectl version --client- Image Registry - as IMS is provided in the form of source code, you have to build binaries for all IMS microservices, deploy them in the form of images in image registy - prefferably one used by your CI/CD platform - that your K8s cluster can access (e.g., Docker Hub, private registry).
MongoDB
Make sure that database user for particular microservice is entitled to create databases. This is the easiest way to allow IMS system to manage its own database.
If you want to limit privileges, please make sure that application user is granted readWrite role for database used by the microservice.
This should be performed for all microservice databases.
- ims-inventory
- ims-inventory-view
- ims-lock
- ims-task
Build & Deploy Overview
The IMS repository includes several domains with source code for libraries and microservices.
To build and deploy the system, the following steps must be performed: Build
- Build the libraries
- Build the microservices, create images and deploy then in the image registry
Deploy
- Deploy Keycloak on your K8s cluster
- Deploy RabbitMQ on your K8s cluster
- Deploy the system on your K8s cluster
Build
Libraries
For each library - compile, build and deploy in package registry.
mvn --batch-mode deploy \
--update-snapshots \
-DskipTests \
-Dmaven.install.skip=true \
-Dmaven.repo.local=~/.m2/repository \
--settings your_maven_settings.xmlThis should be performed for all libraries provided in IMS repository.
IMS Microservices
Compile source code, build and deploy jar in package registry.
mvn --batch-mode deploy \
--update-snapshots \
-DskipTests \
-Dmaven.install.skip=true \
-Dmaven.repo.local=~/.m2/repository \
--settings your_maven_settings.xmlThen build image and deploy it to image registry.
docker login "$REGISTRY"
docker build -t "$IMAGE_NAME":"$IMAGE_TAG" .
docker push "$IMAGE_NAME":"$IMAGE_TAG"Adjust REGISTRY, IMAGE_NAME, and IMAGE_TAG according to your needs (e.g. CI/CD standards).
This should be performed for all libraries provided in IMS repository.
Deploying Keycloak
Skip this part of deployment if your company is already using Keycloak. Remember to configure IMS microservices with an existing Keycloak instance.
Below is values.yml template configuration file, which must be filled in with the appropriate values:
appVersion: latest
image:
registry: "change_me"
tag: "latest"
imagePullSecret: ""
keycloak:
environment:
name: "keycloak"
replicas: 1
port: 8080
secrets:
# If the existingSecret array contains keys,
# they will be mounted even if you have created a default secret
# If you use own secret key must be contains:
# KEYCLOAK_ADMIN
# KEYCLOAK_ADMIN_PASSWORD
# KC_DB_USERNAME
# KC_DB_PASSWORD
existingSecrets: []
defaultSecret:
create: true
data:
db:
username: "change_me"
password: "change_me"
keycloak:
keycloakAdminUsername: "change_me"
keycloakAdminPassword: "change_me"
resources:
requests:
cpu: "10m"
memory: "256Mi"
limits:
cpu: "1"
memory: "1024Mi"
configuration:
db:
url: "change_me"
schema: "keycloak"
provider: "postgres" #If you use postgre db
realms:
realm_som: "realm/export_som.json"
relativePath: "/keycloak/auth"
hostname: "change_me"
metrics: true
health: true
http_enable: true
java_opts: "-Dkeycloak.profile.feature.upload_scripts=enabled -Xmx2048m"
log_level: "TRACE"Install Keycloak on K8S cluster using Helm:
helm upgrade -n $namespace --install Keycloak .Deploying RabbitMQ
Important note! RabbitMQ in IMS acts as an internal communication layer, thus it's reccomended to deploy dedicated RabbitMQ cluster as described below. You should not use your existing RabbitMQ platform that is used for other purposes - such solution was not tested and we can't say anything about such configuration.
Use Bitnami Helm chart for RabbitMQ: https://github.com/bitnami/charts/tree/main/bitnami/rabbitmq (opens in a new tab)
Note, that IMS utilizes quorum queues (opens in a new tab) to ensure persistency and high avaliability - thus persistence (PersistentVolume) should be enabled in your K8s cluster.
- Create PersistentVolume and PersistentVolumeClaim. This should be adjusted according to your K8s cluster configuration. E.g. you can use StorageClass to create PersistentVolume or even PersistentVolumeClaim - consult with your K8s cluster administrator.
# pv-and-pvc.yaml
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: sciamus-rabbitmq-pv
spec:
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Delete
capacity:
storage: 8Gi
storageClassName: standard
hostPath:
path: /tmp/sciamus-rabbitmq-pv
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: sciamus-rabbitmq-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 8Gi
storageClassName: standard
volumeName: sciamus-rabbitmq-pvkubectl -n ims apply -f ./pv-and-pvc.yaml- Prepare RabbitMQ user definitions and store it in Secret. You can use preffered approach to storage sensitive data (such as passwords) using solution utilized in your environment (e.g. AWS Secret Manger or Vault or any other solution that suits your needs).
# load_definition.json
# This is an example of users that could be configured in RabbitMQ cluster.
# ims-app - Application user, used by IMS microservices, without GUI access
# rabbitmq-admin - RabbitMQ admin, full priviliges
# rabbitmq-monitoring - User with GUI access, without restrictions, with monitoring priviliges
# rabbitmq-management - User with GUI access, without restrictions, with management priviliges
# rabbitmq-user-rw - User with GUI access, withouth configuration priviliges, with management priviliges
# rabbitmq-user-ro - User with GUI access, read only, with management priviliges
# For details see https://www.rabbitmq.com/docs/management#permissions.
{
"users": [
{
"name": "ims-app",
"password": "top-secret-password",
"tags": ""
},
{
"name": "rabbitmq-admin",
"password": "top-secret-password",
"tags": "administrator"
},
{
"name": "rabbitmq-monitoring",
"password": "top-secret-password",
"tags": "monitoring"
},
{
"name": "rabbitmq-management",
"password": "top-secret-password",
"tags": "management"
},
{
"name": "rabbitmq-user-rw",
"password": "top-secret-password",
"tags": "monitoring"
},
{
"name": "rabbitmq-user-ro",
"password": "top-secret-password",
"tags": "monitoring"
}
],
"permissions": [
{
"user": "ims-app",
"vhost": "/",
"configure": ".",
"read": ".",
"write": "."
},
{
"user": "rabbitmq-admin",
"vhost": "/",
"configure": ".",
"read": ".",
"write": "."
},
{
"user": "rabbitmq-monitoring",
"vhost": "/",
"configure": ".",
"read": ".",
"write": "."
},
{
"user": "rabbitmq-management",
"vhost": "/",
"configure": ".",
"read": ".",
"write": "."
},
{
"user": "rabbitmq-user-rw",
"vhost": "/",
"configure": "^$",
"read": ".",
"write": "."
},
{
"user": "rabbitmq-user-ro",
"vhost": "/",
"configure": "^$",
"read": ".",
"write": "^$"
}
],
"vhosts": [
{
"name": "/"
}
]
}kubectl -n ims \
create secret generic ims-rabitmq-load-definition \
--from-file ./load_definition.json- Create erlang cookie as Secret
kubectl -n ims \
create secret generic ims-rabitmq-erlang-cookie \
--from-literal=rabbitmq-erlang-cookie=$(openssl rand -hex 64 | base64 -w 0 | base64 -d)- Configure values
# values.yaml
image:
registry: docker.io
repository: bitnami/rabbitmq
tag: 3.12.13-debian-12-r2
debug: true
auth:
existingErlangSecret: "ims-rabitmq-erlang-cookie"
clustering:
rebalance: all
forceBoot: true
loadDefinition:
enabled: true
existingSecret: "ims-rabitmq-load-definition"
extraConfiguration: |-
management.path_prefix = /rabbitmq
load_definitions = /app/load_definition.json
raft.wal_max_size_bytes = 128000000
cluster_formation.target_cluster_size_hint = {{ .Values.replicaCount }}
log.default.level = debug
log.file = false
log.console = true
log.console.level = debug
log.console.formatter = json
replicaCount: 3
resources:
requests:
cpu: 750m
memory: 1024Mi
limits:
cpu: 1500m
memory: 1024Mi
persistence:
storageClass: "-" # Forces static provision
accessModes:
- ReadWriteMany
existingClaim: "sciamus-rabbitmq-pvc"
metrics:
enabled: true
volumePermissions:
enabled: true
resources:
requests:
cpu: 50m
memory: 12Mi
limits:
cpu: 100m
memory: 24Mi- Install RabbitMQ using Helm
# add bitnami repo
helm repo add bitnami https://charts.bitnami.com/bitnami
# install RabbitMQ (with preconfigured PV & PVC)
helm upgrade \
--namespace ims \
-f values.yaml \
--install ims-rabbitmq \
bitnami/rabbitmq --version 13.0.0Note, that commands and configuration presented above are based on Helm chart version 13.0.0 and RabbitMQ version 3.12.13. You can adjust versions according to your needs and newer versions avaliability.
Deploying IMS Microservices
Microservices are launched using generative solutions. For this purpose, the values_{your_env}.yml file is used to select the environment, followed by installation using Helm, as shown further below.
The process of starting microservices in IMS is described below, using the ims-gateway-service microservice as an example.
For documentation purposes, the file has been divided into the general section and the ims-gateway-service section.
values_{your_env}.yml - general:
general:
namespace: "ns-name"
internalConfiguration:
mongodb:
protocol: "mongodb"
parameters:
base: "yourBase"
query: "yourQuery"
defaultSecret:
mongodbHost: "yourMongoDBHost"
mongodbPort: yourPort
secretKeys:
mongoHost: "yourMongoHost"
mongoPort: "yourMongoPort"
mongoUser: "yourMongoUser"
mongoPassword: "yourMongoPassword"
rabbitmq:
rabbitmqHost: "yourRabbithost"
rabbitmqPort: yourPort
secretKeys:
rabbitmqUser: "yourRabbitMQUser"
rabbitmqPassword: "yourRabbitMQPassword"
internalCredential:
mongodb:
mongoUser: "yourMongoUser"
mongoPwd: "yourMongoPwd"
rabbitmq:
rabbitmqUser: "yourRabbitMQUser"
rabbitmqPwd: "yourRabbitMQPwd"
externalConfiguration:
postgresHost: "yourPostgressHost"
ingressHost: "yourIngressHost"
keycloakAuthUrl: "yourKeyCloakAuthUrl"
keycloakRealm: ims
specifyLabels:
monitoring: "example-app"values_{your_env}.yml - ims-gateway-service:
ims-si-gateway:
global:
image:
repository: "registryUrl"
pullPolicy: IfNotPresent
tagOverride: ""
imagePullSecrets: "no needed"
secrets:
defaultSecret:
create: false
needed: true
existingSecrets:
- name: namespace-app-secret
mongodb:
enabled: false
env:
- name: _JAVA_OPTIONS
value: "-XX:MaxRAMPercentage=70 -XX:+ExitOnOutOfMemoryError"
service:
type: ClusterIP
protocol: TCP
port: 8080
targetPort: 8080
resources:
limits:
cpu: 500m
memory: 1024Mi
requests:
cpu: 10m
memory: 1024Mi
diagnosticMode:
enabled: true
customStartupProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
scheme: HTTP
timeoutSeconds: 1
periodSeconds: 30
successThreshold: 1
failureThreshold: 10
customLivenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
scheme: HTTP
timeoutSeconds: 1
periodSeconds: 10
successThreshold: 1
failureThreshold: 3
customReadinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
scheme: HTTP
initialDelaySeconds: 60
timeoutSeconds: 1
periodSeconds: 10
successThreshold: 1
failureThreshold: 2
configurationManagement:
ims:
apiBase: "/si-gateway/api/v1"
loggingTrace: "false"
defaultLimit: 50
client:
inventory-view:
url: your-url/inventory-view/api/v1
lock:
url: your-url/lock/api/v1
task:
url: your-url/task/api/v1
## @param extraDeployment Array of extra objects to deploy with the release
## For example - VirtualService
extraDeployment:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ims-si-gateway-virtualservice
spec:
hosts:
your-host
gateways:
istio-system/sitom
http:
match:
uri:
prefix: /your-gateway
route:
destination:
host: your-gateway
port:
number: 8080
affinity:
enabled: falseThe values_{your_env}.yml file overrides the values defined in the values.yml file, allowing configuration for a specific environment.
In the values_{your_env}.yml file, additional configurations can be applied using keys prefixed with extra (e.g., extraConfiguration, extraDeployment).
The final step is to execute the helm upgrade command, which applies the configuration for the selected environment and starts the microservice.
- helm upgrade --debug -f ./values_{your_env}.yaml --install ${releaseName} --namespace=namespace-{your_env} ./.chart/.This process should be repeated for all IMS microservices.
Real-Life Deployment
We recommend that the installation of the IMS system in real (DEV, TEST, PROD) environments be carried out using CI/CD class tools.