Azure Kubernetes Service
Introduction
These instructions will set up a platform deployment in a Kubernetes cluster on Azure using the Universal GUI and Indicium Application Tier. To route the inbound traffic to the correct services, an Ingress Controller from Nginx is used. Nginx will redirect all traffic from HTTP to HTTPS and uses a self-signed certificate. For Indicium to authenticate to the IAM database, a secret will be created which is exposed inside the container of Indicium. Both deployments contain two health checks for starting and availability.
Prerequisites
- An active Azure Subscription
- The Azure Command-Line Interface, Azure CLI
- The Kubernetes command-line tool, kubectl
- The package manager for Kubernetes, Helm
- An authentication token for the Thinkwise Container Registry, for more information see Thinkwise Container Registry - Authentication
- A database server containing an Intelligent Application Manager
We recommended using a source-code editor like Visual Studio Code. An extension for Kubernetes is available on the Visual Studio Marketplace
The used subscription will be charged by Microsoft for using an Azure Kubernetes Service as long as the cluster runs. For more information about costs, see Azure Calculator.
Deployment steps
The deployment steps are meant for Bash on a Linux distribution. Windows PowerShell will not work.
Before you begin, make sure you are in the correct Kubernetes namespace you want to deploy the Thinkwise Platform to.
The active namespace in kubectl can be checked with kubectl config get-contexts
.
- Create a directory with a name, for example Thinkwise-k8s, and open this in the preferred source-code editor
- In this directory, create the following files:
Thinkwise-k8s/
├── indicium-configuration.yaml
├── indicium.yaml
└── universal.yaml
- Create a new Resource Group with an Azure Kubernetes Service cluster and retrieve the credentials to use the Kubernetes CLI.
In this example, an Azure Kubernetes Service is created in
westeurope
, with the nameaks-example
in the Resource group thinkwise-k8s-example-westeurope
LOCATION=westeurope
RG_NAME=thinkwise-k8s-demo-$location
AKS_NAME=aks-example
az group create \
--location $LOCATION \
--resource-group $RG_NAME
az aks create \
--resource-group $RG_NAME \
--name $AKS_NAME \
--generate-ssh-keys
az aks get-credentials \
--resource-group $RG_NAME \
--name $AKS_NAME
- Install a basic Nginx Ingress Controller to the Kubernetes cluster with Helm:
INGRESS_NAMESPACE=ingress-basic
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm install ingress-nginx ingress-nginx/ingress-nginx \
--create-namespace \
--namespace $INGRESS_NAMESPACE \
--set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-health-probe-request-path"=/healthz
You can use the following command in Bash to view the assigned IP address of the Nginx Ingress Controller:
PUBLIC_IP=$(kubectl get service --namespace $INGRESS_NAMESPACE ingress-nginx-controller -o jsonpath="{.status.loadBalancer.ingress[].ip}")
echo The public IP address is $PUBLIC_IP
- Create a
ConfigMap
for Indicium to use and replace the following values to match your environment. In this example it is namedindicium-configuration
:
---
apiVersion: v1
kind: ConfigMap
metadata:
name: indicium-configuration
data:
SQL_SERVER: "<hostname>"
SQL_DATABASE: "<database>"
ENABLE_REVERSE_PROXY: "true"
ALLOWED_HEADERS: "All"
TRUSTED_NETWORKS: "0.0.0.0/0"
EXTERNAL_PATH_BASE: "/indicium"
- Create a secret for Indicium to connect to the database server. In this example, the secret will be named
database-credentials
:
read -rp "Enter the database username: " DB_USERNAME
read -srp "Enter the database password: " DB_PASSWORD && echo -e "\n"
kubectl create secret generic database-credentials \
--from-literal=SQL_USERNAME="$DB_USERNAME" \
--from-literal=SQL_PASSWORD="$DB_PASSWORD"
- Create a Docker Registry secret to pull the container images. In this example, the secret will be named
thinkwise-registry
:
read -rp "Enter the username: " REGISTRY_USERNAME
read -srp "Enter the secret: " REGISTRY_SECRET && echo -e "\n"
kubectl create secret docker-registry thinkwise-registry \
--docker-server registry.thinkwisesoftware.com \
--docker-username "$REGISTRY_USERNAME" \
--docker-password "$REGISTRY_SECRET"
- Create the following deployment manifests and modify the highlighted lines:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: indicium
spec:
replicas: 1
selector:
matchLabels:
app: indicium
template:
metadata:
labels:
app: indicium
spec:
containers:
- name: indicium
image: registry.thinkwisesoftware.com/public/indicium:2023.1.10
ports:
- containerPort: 80
startupProbe:
tcpSocket:
port: 80
initialDelaySeconds: 5
livenessProbe:
tcpSocket:
port: 80
envFrom:
- configMapRef:
name: indicium-configuration
volumeMounts:
- mountPath: "/var/run/secrets"
readOnly: true
name: database-credentials
imagePullSecrets:
- name: thinkwise-registry
volumes:
- name: database-credentials
secret:
secretName: database-credentials
---
apiVersion: v1
kind: Service
metadata:
name: indicium
spec:
type: ClusterIP
ports:
- name: http
port: 80
targetPort: 80
selector:
app: indicium
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: indicium
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
ingressClassName: nginx
rules:
- host: example.com
http:
paths:
- pathType: Prefix
path: /indicium(/|$)(.*)
backend:
service:
name: indicium
port:
number: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: universal
spec:
replicas: 1
selector:
matchLabels:
app: universal
template:
metadata:
labels:
app: universal
spec:
containers:
- name: universal
image: registry.thinkwisesoftware.com/public/universal:2023.1.10
ports:
- containerPort: 80
startupProbe:
tcpSocket:
port: 80
initialDelaySeconds: 5
livenessProbe:
tcpSocket:
port: 80
env:
- name: SERVICE_URL
value: "https://example.com/indicium/iam/iam"
imagePullSecrets:
- name: thinkwise-registry
---
apiVersion: v1
kind: Service
metadata:
name: universal
spec:
type: ClusterIP
ports:
- name: http
port: 80
targetPort: 80
selector:
app: universal
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: universal
annotations:
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
spec:
ingressClassName: nginx
rules:
- host: example.com
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: universal
port:
number: 80
- Run
kubectl apply -f .
to apply the configuration in the current directory to the Kubernetes cluster.
To remove the created resources in the cluster, use the command kubectl delete -f .
Applying an update
To change the version of the Indicium Application Tier and Universal GUI, follow these steps:
- Change the tag of the Indicium and Universal image in the manifest files to a different version and save the file.
- Execute the command
kubectl apply -f .