We recommend running PostgreSQL as a cloud service such as Google Cloud SQL, Amazon RDS for PostgreSQL or Microsoft Azure PostgreSQL, and not running it in the same Kubernetes cluster as the other applications in case of node failures.
Example Deployment Files
The entire distribution service platform can be deployed in a Kubernetes cluster with only a few commands. We provide a yaml deployment files that you can use as a base for your own deployment. Some configurations are better stored as configmaps or secrets. The script will create 2 replicas of every deployment and attempt to spread them across different nodes in the cluster. Below you can find the deployment files for a deployment in a Google Cloud Kubernetes environment
Sensitive information such as usernames, passwords, and related data should be stored as secrets. Using Kustomize you can create secrets from string literals which can be set as environment variables in your deployment specs.
Keycloak IDP
Kong DB Bootstrapping
Should only be run once
Kong Gateway
Distribution Service
ReadMyCards
Ingress
ConfigMaps From Files
The DS keystores can be stored as configmaps in the cluster, and be mounted as volumes in the pod containers. We require a Java keystore (jks) file to configure the IDP, and a PKCS12 keystore (p12) for the DS API. The contents of both keystores must be identical.
GKE Guide
Database
Create a PostgreSQL 12 database instance
When creating the database instance, configure the connectivity and backups option according to your need. The database instance must be reachable from the K8s cluster.
Create the necessary databases:
t1c-ds
keycloak
kong
Create Kubernetes Cluster
Ubuntu 18.04
PostgreSQL
1) Add PostgreSQL repository:
2) Install PostgreSQL:
3) Configure PostgreSQL. The PostgreSQL server should be reachable from the DS API, Kong Gateway and Keycloak application server(s). We refer you to the documentation: https://www.postgresql.org/docs/12/
4) Create the users and the 3 databases (t1c-ds, kong, keycloak):
We recommend creating different users for each database, but the same user can also be used for all databases.
Distribution Service API
1) Obtain the Distribution Service API server distributable. If you wish to build a package from source, run sbt ";clean;compile;dist" from the project root. A zip archive containing the application will be available under the target/universal folder
2) Install Java:
3) Unzip to a folder of your choice. We recommend using a subdirectory of the /opt folder.
4) Configure the Distribution Service API. See Configuration for a detailed description of the available options.
5) Create a service. We recommend using systemctl. Create a file in the /etc/systemd/system/ folder called t1cds.service and configure it as follows:
We strongly recommend placing sensitive information in the service definition as environment variables. See Configuration to get a list of configuration keys.
6) Enable and start the service
Kong Gateway
We refer you to the Kong installation guides for the platform of your choice:
For development and testing purposes we offer a Docker Compose image to run the platform easily. Note that you must have access to the Trust1Team Docker container registry, or import the DS API image in yours.
apiVersion: v1
kind: Service
metadata:
name: keycloak
namespace: t1c
labels:
app: keycloak
annotations:
beta.cloud.google.com/backend-config: '{"ports": {"80":"t1c-backendconfig"}}'
spec:
ports:
- name: http
port: 80
targetPort: 8080
- name: https
port: 443
targetPort: 8443
selector:
app: keycloak
type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: keycloak
namespace: t1c
labels:
app: keycloak
spec:
replicas: 1
selector:
matchLabels:
app: keycloak
template:
metadata:
labels:
app: keycloak
spec:
restartPolicy: Always
volumes:
- configMap:
name: t1cds-jks
name: keystore
- secret:
secretName: t1cds-svc-account
name: svc-account
containers:
- name: keycloak
image: quay.io/keycloak/keycloak:14.0.0
envFrom:
- configMapRef:
name: t1c-ds-configmap
- secretRef:
name: t1c-ds-secrets
volumeMounts:
- mountPath: "/mnt"
name: keystore
ports:
- name: http
containerPort: 8080
- name: https
containerPort: 8443
readinessProbe:
httpGet:
path: /auth/realms/master
port: 8080
- name: cloud-sql-proxy
# It is recommended to use the latest version of the Cloud SQL proxy
# Make sure to update on a regular schedule!
image: gcr.io/cloudsql-docker/gce-proxy:1.23.1
envFrom:
- configMapRef:
name: t1c-ds-configmap
command: [ "/cloud_sql_proxy" ]
args: [ "-log_debug_stdout=true", "-verbose=false","-instances=$(GCP_DB_CONNECTION_NAME)=tcp:5432", "-credential_file=/secrets/service_account.json" ]
securityContext:
# The default Cloud SQL proxy image runs as the
# "nonroot" user and group (uid: 65532) by default.
runAsNonRoot: true
volumeMounts:
- name: svc-account
mountPath: /secrets/
readOnly: true
---
# This job will state "Pod has warnings, but if the kong-migrations job has completed (db is bootstrapped), you can delete the job
apiVersion: batch/v1
kind: Job
metadata:
name: kong-migrations
spec:
template:
metadata:
name: kong-migrations
spec:
volumes:
- name: svc-account
secret:
secretName: t1cds-svc-account
containers:
- name: kong-migrations
image: kong:2.5.0-alpine
command:
- /bin/sh
- -c
- kong migrations bootstrap
envFrom:
- configMapRef:
name: t1c-ds-configmap
- secretRef:
name: t1c-ds-secrets
- name: cloud-sql-proxy
# It is recommended to use the latest version of the Cloud SQL proxy
# Make sure to update on a regular schedule!
image: gcr.io/cloudsql-docker/gce-proxy:1.23.1
envFrom:
- configMapRef:
name: t1c-ds-configmap
command: [ "/cloud_sql_proxy" ]
args: [ "-log_debug_stdout=true", "-instances=$(GCP_DB_CONNECTION_NAME)=tcp:5432", "-credential_file=/secrets/service_account.json" ]
securityContext:
# The default Cloud SQL proxy image runs as the
# "nonroot" user and group (uid: 65532) by default.
runAsNonRoot: true
volumeMounts:
- name: svc-account
mountPath: /secrets/
readOnly: true
restartPolicy: OnFailure
---
# This job will state "Pod has warnings, but if the kong-migrations job has completed (db is bootstrapped), you can delete the job
apiVersion: batch/v1
kind: Job
metadata:
name: kong-migrations
spec:
template:
metadata:
name: kong-migrations
spec:
volumes:
- name: svc-account
secret:
secretName: t1cds-svc-account
containers:
- name: kong-migrations
image: kong:2.5.0-alpine
command:
- /bin/sh
- -c
- kong migrations up
envFrom:
- configMapRef:
name: t1c-ds-configmap
- secretRef:
name: t1c-ds-secrets
- name: cloud-sql-proxy
# It is recommended to use the latest version of the Cloud SQL proxy
# Make sure to update on a regular schedule!
image: gcr.io/cloudsql-docker/gce-proxy:1.23.1
envFrom:
- configMapRef:
name: t1c-ds-configmap
command: [ "/cloud_sql_proxy" ]
args: [ "-log_debug_stdout=true", "-instances=$(GCP_DB_CONNECTION_NAME)=tcp:5432", "-credential_file=/secrets/service_account.json" ]
securityContext:
# The default Cloud SQL proxy image runs as the
# "nonroot" user and group (uid: 65532) by default.
runAsNonRoot: true
volumeMounts:
- name: svc-account
mountPath: /secrets/
readOnly: true
restartPolicy: OnFailure
---
# This job will state "Pod has warnings, but if the kong-migrations job has completed (db is bootstrapped), you can delete the job
apiVersion: batch/v1
kind: Job
metadata:
name: kong-migrations
spec:
template:
metadata:
name: kong-migrations
spec:
volumes:
- name: svc-account
secret:
secretName: t1cds-svc-account
containers:
- name: kong-migrations
image: kong:2.5.0-alpine
command:
- /bin/sh
- -c
- kong migrations finish
envFrom:
- configMapRef:
name: t1c-ds-configmap
- secretRef:
name: t1c-ds-secrets
- name: cloud-sql-proxy
# It is recommended to use the latest version of the Cloud SQL proxy
# Make sure to update on a regular schedule!
image: gcr.io/cloudsql-docker/gce-proxy:1.23.1
envFrom:
- configMapRef:
name: t1c-ds-configmap
command: [ "/cloud_sql_proxy" ]
args: [ "-log_debug_stdout=true", "-instances=$(GCP_DB_CONNECTION_NAME)=tcp:5432", "-credential_file=/secrets/service_account.json" ]
securityContext:
# The default Cloud SQL proxy image runs as the
# "nonroot" user and group (uid: 65532) by default.
runAsNonRoot: true
volumeMounts:
- name: svc-account
mountPath: /secrets/
readOnly: true
restartPolicy: OnFailure
CREATE USER [INSERT_DATASTORE_USERNAME_HERE];
ALTER USER [INSERT_DATASTORE_USERNAME_HERE] PASSWORD '[INSERT_DATASTORE_PASSWORD_HERE]';
CREATE DATABASE [INSERT_DATABASE_NAME_HERE] OWNER [INSERT_DATASTORE_USERNAME_HERE];
wget -qO - https://adoptopenjdk.jfrog.io/adoptopenjdk/api/gpg/key/public | sudo apt-key add -
sudo add-apt-repository --yes https://adoptopenjdk.jfrog.io/adoptopenjdk/deb/
# If you get a command not found error run the command below:
# sudo apt-get install -y software-properties-common
sudo apt-get update
sudo apt-get install adoptopenjdk-11-hotspot
Description=T1C-DS API
After=syslog.target network.target
Before=httpd.service
[Service]
Environment=PLAY_SECRET=nf8dqrQM9_?XUm]JCxKu7Jyo9cMf`Eqh<VmOTlj`QWJAiKDqp?fD3J=zvOm3v9L:
ExecStart=/opt/t1cds/bin/t1c-ds
[Install]
WantedBy=multi-user.target
chmod 664 /etc/systemd/system/t1cds.service
systemctl enable /etc/systemd/system/t1cds.service
service t1cds start