# Create the security groupexocomputesecurity-groupcreateswiss-ai-center-prod-security-group
# Allow NodePort servicesexocomputesecurity-groupruleaddswiss-ai-center-prod-security-group\--description"NodePort services"\--protocoltcp\--network0.0.0.0/0\--port30000-32767
# Allow SKS kubeletexocomputesecurity-groupruleaddswiss-ai-center-prod-security-group\--description"SKS kubelet"\--protocoltcp\--port10250\--security-groupswiss-ai-center-prod-security-group
# Allow Calico trafficexocomputesecurity-groupruleaddswiss-ai-center-prod-security-group\--description"Calico traffic"\--protocoludp\--port4789\--security-groupswiss-ai-center-prod-security-group
# Create the Kubernetes clusterexocomputeskscreateswiss-ai-center-prod-cluster\--zonech-gva-2\--service-levelpro\--nodepool-nameswiss-ai-center-prod-nodepool-1\--nodepool-size2\--nodepool-disk-size20\--nodepool-instance-type"standard.small"\--nodepool-security-groupswiss-ai-center-prod-security-group
# Validate the creation of the Kubernetes clusterexocomputeskslist
# Get the kubeconfig fileexocomputeskskubeconfigswiss-ai-center-prod-clusterkube-admin>exoscale.kubeconfig
# Display the Kubernetes cluster configurationcatexoscale.kubeconfig
# Validate kubectl can access the Kubernetes clusterkubectl--kubeconfigexoscale.kubeconfig\getnode
# Install the Nginx Ingress Controllerkubectl--kubeconfigexoscale.kubeconfig\apply-fhttps://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/exoscale/deploy.yaml
# Validate the installationkubectl--kubeconfigexoscale.kubeconfig\getpods-ningress-nginx\-lapp.kubernetes.io/name=ingress-nginx--watch
# Get the external IP address of the Nginx Ingress Controllerkubectl--kubeconfigexoscale.kubeconfig\getsvc-ningress-nginx
Check if overlay network is functioning correctly¶
=> Start network overlay test
pool-79a73-lnamo can reach pool-79a73-lnamo
pool-79a73-lnamo can reach pool-79a73-wnliz
pool-79a73-wnliz can reach pool-79a73-lnamo
pool-79a73-wnliz can reach pool-79a73-wnliz
=> End network overlay test
If you see error in the output, there is some issue with the route between the pods on the two hosts. This could be because the required ports for overlay networking are not opened.
You can now clean up the DaemonSet by running the following command:
Add an A record to your DNS zone to point to the Nginx Ingress Controller external IP address. You can use a wildcard *.swiss-ai-center.ch (for example) A record to point to the Nginx Ingress Controller external IP address.
# Create a Let's Encrypt issuercat<<EOF > letsencrypt-issuer.yamlapiVersion: cert-manager.io/v1kind: Issuermetadata: name: letsencryptspec: acme: # The ACME server URL server: https://acme-v02.api.letsencrypt.org/directory # Email address used for ACME registration email: monitor@swiss-ai-center.ch # Name of a secret used to store the ACME account private key privateKeySecretRef: name: letsencrypt # Enable the HTTP-01 challenge provider solvers: - http01: ingress: ingressClassName: nginxEOF# Deploy the Let's Encrypt issuerkubectl--kubeconfigexoscale.kubeconfig\apply-fletsencrypt-issuer.yaml
# Validate the deploymentkubectl--kubeconfigexoscale.kubeconfig\describeissuerletsencrypt
Warning
This is a work in progress. It has not been tested yet.
# Create a PostgreSQL databaseexodbaascreatepghobbyist-2core-engine-prod-database--zonech-gva-2
# Validate the creation of the PostgreSQL databaseexodbaas--zonech-gva-2showcore-engine-prod-database
# Get the PostgreSQL database URLexodbaas--zonech-gva-2showcore-engine-prod-database--uri
Allow the Kubernetes cluster to access the PostgreSQL database¶
# Create a new role for Kubernetesexoiamrolecreatek8s--policy'{"default-service-strategy":"deny","services":{"dbaas":{"type":"allow","rules":[]}}}'# Create a new API key for Kubernetesexoiamapi-keycreatek8s-dbaask8s
# Create a new secret for the API keykubectl--kubeconfigexoscale.kubeconfig\-nkube-systemcreatesecretgenericexoscale-k8s-dbaas-credentials\--from-literal=api-key='API_KEY'\--from-literal=api-secret='API_SECRET'# Download the Kubernetes manifestcurl-ok8s-dbaas.yamlhttps://raw.githubusercontent.com/exoscale-labs/sks-sample-manifests/main/exo-k8s-dbaas-filter/exo-k8s-dbaas-filter.yaml
# Edit the Kubernetes manifest to use the correct API key and secret and database(s) name(s)## Example:## ```yaml# env:# - name: EXOSCALE_API_KEY# valueFrom:# secretKeyRef:# key: api-key# # change the name of the secret if necessary# name: exoscale-k8s-dbaas-credentials# - name: EXOSCALE_API_SECRET# valueFrom:# secretKeyRef:# key: api-secret# # change the name of the secret if necessary# name: exoscale-k8s-dbaas-credentials# ```## and## `exo dbaas update --pg-ip-filter "$IPLISTFOREXO" core-engine-prod-database -z ch-gva-2`# Deploy the Kubernetes manifestkubectl--kubeconfigexoscale.kubeconfig\apply-fk8s-dbaas.yaml
# Validate the deploymentkubectl--kubeconfigexoscale.kubeconfig\getpods-nkube-system\-lapp=exo-k8s-dbaas-filter--watch
# View the logs of the podkubectl--kubeconfigexoscale.kubeconfig\logs-nkube-system\-lapp=exo-k8s-dbaas-filter
# Create a new role for the Core engineexoiamrolecreatecore-engine--policy'{"default-service-strategy":"deny","services":{"sos":{"type":"allow","rules":[]}}}'# Create a new API key for the Core engineexoiamapi-keycreates3core-engine
Update the Core engine GitHub Actions configuration¶
Update the Core engine GitHub Actions configuration by adding/updating the following secrets:
Warning
The PROD_DATABASE_URL must be saved with postgresql:// protocol. The default value is postgres://.
PROD_KUBE_CONFIG: The content of the Kubernetes configuration file (this is an Organization secret in our repository)
PROD_DATABASE_URL: The URL of the PostgreSQL database
PROD_S3_ACCESS_KEY_ID: The access key ID of the S3 bucket
PROD_S3_SECRET_ACCESS_KEY: The secret access key of the S3 bucket
# Check the podskubectl--kubeconfigexoscale.kubeconfig\getpods
# Check the logskubectl--kubeconfigexoscale.kubeconfig\logscore-engine-backend-stateful-0
Deploying a service is similar to deploying the core engine. You need to update the GitHub Actions configuration by adding/updating the following secrets:
PROD_KUBE_CONFIG: The content of the Kubernetes configuration file (this is an Organization secret in our repository)
Update the GitHub Actions configuration by adding/updating the following variables:
DEPLOY_PROD: true
PROD_SERVICE_URL: The URL of the service
SERVICE_NAME: The name of the service
Run the GitHub Actions workflow to deploy the service.
At some point, if you deploy more services, you may need to scale the Kubernetes cluster node pools. You can do this by executing the following commands:
# Scale the Kubernetes cluster node pools to the double of the current sizeexocomputesksnodepoolscaleswiss-ai-center-prod-clusterswiss-ai-center-prod-nodepool-14# Validate the scaling of the Kubernetes cluster node poolsexocomputesksnodepoollistswiss-ai-center-prod-cluster
If you only also wanted to change the instance type and/or disk size, you can do this by executing the following commands:
# Change the type of the Kubernetes cluster node pools to a different instance type and bigger disk-sizeexocomputesksnodepoolupdateswiss-ai-center-prod-clusterswiss-ai-center-prod-nodepool-1--instance-type"standard.medium"--disk-size400# Scale the Kubernetes cluster node pools to the double of the current size# ...see the code snippet above# Validate the scaling of the Kubernetes cluster node poolsexocomputesksnodepoolshowswiss-ai-center-prod-clusterswiss-ai-center-prod-nodepool-1
# You should see Disk size: 400 and Instance type: standard.medium
# You now need to drain the old nodes to move the pods to the new nodes and delete the old nodes. You can do this by executing the following commands:# Find the node pool nameskubectlgetnodes--kubeconfigexoscale.kubeconfig
# For each old node, drain the node to move the pods to the new nodes and delete the old node# Note: To find which node are the old nodes, you can look at the AGE column in the output of the previous commandkubectldrain<old-node-name>--kubeconfigexoscale.kubeconfig--ignore-daemonsets--delete-emptydir-data
exocomputesksnodepoolevictswiss-ai-center-prod-clusterswiss-ai-center-prod-nodepool-1<old-node-name>
# Delete all node poolsexocomputesksnodepooldeleteswiss-ai-center-prod-clusterswiss-ai-center-prod-nodepool-1
# Delete the Kubernetes clusterexocomputesksdeleteswiss-ai-center-prod-cluster
# List the load balancersexocomputeload-balancerlist
# Delete the load balancerexocomputeload-balancerdeletek8s-9fb0fdfd-c90d-4234-b50c-871885f0982d
# Delete the security groupexocomputesecurity-groupdeleteswiss-ai-center-prod-security-group
# Remove terminations protection from the PostgreSQL databaseexodbaasupdatecore-engine-prod-database--zonech-gva-2--termination-protection=false# Delete the PostgreSQL databaseexodbaasdeletecore-engine-prod-database--zonech-gva-2
# Delete the S3 bucketexostoragerb--recursivesos://core-engine-prod-bucket
# Delete the API key for Kubernetesexoiamapi-keydeletek8s-dbaas
# Delete the role for Kubernetesexoiamroledeletek8s
# Delete the API key for the Core engineexoiamapi-keydeletes3
# Delete the role for the Core engineexoiamroledeletecore-engine