Loading deploy/all.sh +39 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,9 @@ # Read deployment settings ######################################################################################################################## # ----- TeraFlowSDN ------------------------------------------------------------ # If not already set, set the URL of the Docker registry where the images will be uploaded to. # By default, assume internal MicroK8s registry is used. export TFS_REGISTRY_IMAGES=${TFS_REGISTRY_IMAGES:-"http://localhost:32000/tfs/"} Loading @@ -42,6 +45,9 @@ export TFS_GRAFANA_PASSWORD=${TFS_GRAFANA_PASSWORD:-"admin123+"} # If TFS_SKIP_BUILD is "YES", the containers are not rebuilt-retagged-repushed and existing ones are used. export TFS_SKIP_BUILD=${TFS_SKIP_BUILD:-""} # ----- CockroachDB ------------------------------------------------------------ # If not already set, set the namespace where CockroackDB will be deployed. export CRDB_NAMESPACE=${CRDB_NAMESPACE:-"crdb"} Loading Loading @@ -84,6 +90,9 @@ export CRDB_DROP_DATABASE_IF_EXISTS=${CRDB_DROP_DATABASE_IF_EXISTS:-""} # If CRDB_REDEPLOY is "YES", the database will be dropped while checking/deploying CockroachDB. export CRDB_REDEPLOY=${CRDB_REDEPLOY:-""} # ----- NATS ------------------------------------------------------------------- # If not already set, set the namespace where NATS will be deployed. export NATS_NAMESPACE=${NATS_NAMESPACE:-"nats"} Loading @@ -99,6 +108,32 @@ export NATS_SECRET_NAMESPACE=${NATS_SECRET_NAMESPACE:-${TFS_K8S_NAMESPACE}} export NATS_REDEPLOY=${NATS_REDEPLOY:-""} # ----- QuestDB ---------------------------------------------------------------- # If not already set, set the namespace where QuestDB will be deployed. export QDB_NAMESPACE=${QDB_NAMESPACE:-"qdb"} # If not already set, set the database username to be used by Monitoring. export QDB_USERNAME=${QDB_USERNAME:-"admin"} # If not already set, set the database user's password to be used by Monitoring. export QDB_PASSWORD=${QDB_PASSWORD:-"quest"} # If not already set, set the table name to be used by Monitoring. export QDB_TABLE=${QDB_TABLE:-"tfs_monitoring"} ## If not already set, disable flag for dropping table if exists. ## WARNING: ACTIVATING THIS FLAG IMPLIES LOOSING THE TABLE INFORMATION! ## If QDB_DROP_TABLE_IF_EXISTS is "YES", the table pointed by variable QDB_TABLE will be dropped while ## checking/deploying QuestDB. #export QDB_DROP_TABLE_IF_EXISTS=${QDB_DROP_TABLE_IF_EXISTS:-""} # If not already set, disable flag for re-deploying QuestDB from scratch. # WARNING: ACTIVATING THIS FLAG IMPLIES LOOSING THE DATABASE INFORMATION! # If QDB_REDEPLOY is "YES", the database will be dropped while checking/deploying QuestDB. export QDB_REDEPLOY=${QDB_REDEPLOY:-""} ######################################################################################################################## # Automated steps start here ######################################################################################################################## Loading @@ -109,7 +144,10 @@ export NATS_REDEPLOY=${NATS_REDEPLOY:-""} # Deploy NATS ./deploy/nats.sh # Deploy TFS # Deploy QuestDB ./deploy/qdb.sh # Deploy TeraFlowSDN ./deploy/tfs.sh # Show deploy summary Loading deploy/crdb.sh +1 −1 Original line number Diff line number Diff line Loading @@ -44,7 +44,7 @@ export CRDB_DEPLOY_MODE=${CRDB_DEPLOY_MODE:-"single"} # If not already set, disable flag for dropping database if exists. # WARNING: ACTIVATING THIS FLAG IMPLIES LOOSING THE DATABASE INFORMATION! # If CRDB_DROP_DATABASE_IF_EXISTS is "YES", the database pointed by variable CRDB_NAMESPACE will be dropped while # If CRDB_DROP_DATABASE_IF_EXISTS is "YES", the database pointed by variable CRDB_DATABASE will be dropped while # checking/deploying CockroachDB. export CRDB_DROP_DATABASE_IF_EXISTS=${CRDB_DROP_DATABASE_IF_EXISTS:-""} Loading deploy/qdb.sh 0 → 100755 +165 −0 Original line number Diff line number Diff line #!/bin/bash # Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/) # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ######################################################################################################################## # Read deployment settings ######################################################################################################################## # If not already set, set the namespace where QuestDB will be deployed. export QDB_NAMESPACE=${QDB_NAMESPACE:-"qdb"} # If not already set, set the database username to be used by Monitoring. export QDB_USERNAME=${QDB_USERNAME:-"admin"} # If not already set, set the database user's password to be used by Monitoring. export QDB_PASSWORD=${QDB_PASSWORD:-"quest"} # If not already set, set the table name to be used by Monitoring. export QDB_TABLE=${QDB_TABLE:-"tfs_monitoring"} ## If not already set, disable flag for dropping table if exists. ## WARNING: ACTIVATING THIS FLAG IMPLIES LOOSING THE TABLE INFORMATION! ## If QDB_DROP_TABLE_IF_EXISTS is "YES", the table pointed by variable QDB_TABLE will be dropped while ## checking/deploying QuestDB. #export QDB_DROP_TABLE_IF_EXISTS=${QDB_DROP_TABLE_IF_EXISTS:-""} # If not already set, disable flag for re-deploying QuestDB from scratch. # WARNING: ACTIVATING THIS FLAG IMPLIES LOOSING THE DATABASE INFORMATION! # If QDB_REDEPLOY is "YES", the database will be dropped while checking/deploying QuestDB. export QDB_REDEPLOY=${QDB_REDEPLOY:-""} ######################################################################################################################## # Automated steps start here ######################################################################################################################## # Constants TMP_FOLDER="./tmp" QDB_MANIFESTS_PATH="manifests/questdb" # Create a tmp folder for files modified during the deployment TMP_MANIFESTS_FOLDER="$TMP_FOLDER/manifests" TMP_LOGS_FOLDER="$TMP_FOLDER/logs" QDB_LOG_FILE="$TMP_LOGS_FOLDER/qdb_deploy.log" mkdir -p $TMP_LOGS_FOLDER function qdb_deploy() { echo "QuestDB Namespace" echo ">>> Create QuestDB Namespace (if missing)" kubectl create namespace ${QDB_NAMESPACE} echo echo "QuestDB" echo ">>> Checking if QuestDB is deployed..." if kubectl get --namespace ${QDB_NAMESPACE} statefulset/questdb &> /dev/null; then echo ">>> QuestDB is present; skipping step." else echo ">>> Deploy QuestDB" cp "${QDB_MANIFESTS_PATH}/manifest.yaml" "${TMP_MANIFESTS_FOLDER}/qdb_manifest.yaml" kubectl apply --namespace ${QDB_NAMESPACE} -f "${TMP_MANIFESTS_FOLDER}/qdb_manifest.yaml" echo ">>> Waiting QuestDB statefulset to be created..." while ! kubectl get --namespace ${QDB_NAMESPACE} statefulset/questdb &> /dev/null; do printf "%c" "." sleep 1 done # Wait for statefulset condition "Available=True" does not work # Wait for statefulset condition "jsonpath='{.status.readyReplicas}'=3" throws error: # "error: readyReplicas is not found" # Workaround: Check the pods are ready #echo ">>> QuestDB statefulset created. Waiting for readiness condition..." #kubectl wait --namespace ${QDB_NAMESPACE} --for=condition=Available=True --timeout=300s statefulset/questdb #kubectl wait --namespace ${QDB_NAMESPACE} --for=jsonpath='{.status.readyReplicas}'=3 --timeout=300s \ # statefulset/questdb echo ">>> QuestDB statefulset created. Waiting QuestDB pods to be created..." while ! kubectl get --namespace ${QDB_NAMESPACE} pod/questdb-0 &> /dev/null; do printf "%c" "." sleep 1 done kubectl wait --namespace ${QDB_NAMESPACE} --for=condition=Ready --timeout=300s pod/questdb-0 fi echo echo "QuestDB Port Mapping" echo ">>> Expose QuestDB SQL port (8812->8812)" QDB_SQL_PORT=$(kubectl --namespace ${QDB_NAMESPACE} get service questdb-public -o 'jsonpath={.spec.ports[?(@.name=="sql")].port}') PATCH='{"data": {"'${QDB_SQL_PORT}'": "'${QDB_NAMESPACE}'/questdb-public:'${QDB_SQL_PORT}'"}}' kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" PORT_MAP='{"containerPort": '${QDB_SQL_PORT}', "hostPort": '${QDB_SQL_PORT}'}' CONTAINER='{"name": "nginx-ingress-microk8s", "ports": ['${PORT_MAP}']}' PATCH='{"spec": {"template": {"spec": {"containers": ['${CONTAINER}']}}}}' kubectl patch daemonset nginx-ingress-microk8s-controller --namespace ingress --patch "${PATCH}" echo echo ">>> Expose QuestDB Influx Line Protocol port (9009->9009)" QDB_ILP_PORT=$(kubectl --namespace ${QDB_NAMESPACE} get service questdb-public -o 'jsonpath={.spec.ports[?(@.name=="ilp")].port}') PATCH='{"data": {"'${QDB_ILP_PORT}'": "'${QDB_NAMESPACE}'/questdb-public:'${QDB_ILP_PORT}'"}}' kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" PORT_MAP='{"containerPort": '${QDB_ILP_PORT}', "hostPort": '${QDB_ILP_PORT}'}' CONTAINER='{"name": "nginx-ingress-microk8s", "ports": ['${PORT_MAP}']}' PATCH='{"spec": {"template": {"spec": {"containers": ['${CONTAINER}']}}}}' kubectl patch daemonset nginx-ingress-microk8s-controller --namespace ingress --patch "${PATCH}" echo echo ">>> Expose QuestDB HTTP Mgmt GUI port (9000->9000)" QDB_GUI_PORT=$(kubectl --namespace ${QDB_NAMESPACE} get service questdb-public -o 'jsonpath={.spec.ports[?(@.name=="http")].port}') PATCH='{"data": {"'${QDB_GUI_PORT}'": "'${QDB_NAMESPACE}'/questdb-public:'${QDB_GUI_PORT}'"}}' kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" PORT_MAP='{"containerPort": '${QDB_GUI_PORT}', "hostPort": '${QDB_GUI_PORT}'}' CONTAINER='{"name": "nginx-ingress-microk8s", "ports": ['${PORT_MAP}']}' PATCH='{"spec": {"template": {"spec": {"containers": ['${CONTAINER}']}}}}' kubectl patch daemonset nginx-ingress-microk8s-controller --namespace ingress --patch "${PATCH}" echo } function qdb_undeploy() { echo "QuestDB" echo ">>> Checking if QuestDB is deployed..." if kubectl get --namespace ${QDB_NAMESPACE} statefulset/questdb &> /dev/null; then echo ">>> Undeploy QuestDB" kubectl delete --namespace ${QDB_NAMESPACE} -f "${TMP_MANIFESTS_FOLDER}/qdb_manifest.yaml" --ignore-not-found else echo ">>> QuestDB is not present; skipping step." fi echo echo "QuestDB Namespace" echo ">>> Delete QuestDB Namespace (if exists)" echo "NOTE: this step might take few minutes to complete!" kubectl delete namespace ${QDB_NAMESPACE} --ignore-not-found echo } # TODO: implement method to drop table #function qdb_drop_table() { # echo "Drop table if exists" # QDB_CLIENT_URL="postgresql://${QDB_USERNAME}:${QDB_PASSWORD}@questdb-0:${QDB_SQL_PORT}/defaultdb?sslmode=require" # kubectl exec -it --namespace ${QDB_NAMESPACE} questdb-0 -- \ # ./qdb sql --certs-dir=/qdb/qdb-certs --url=${QDB_CLIENT_URL} \ # --execute "DROP TABLE IF EXISTS ${QDB_TABLE};" # echo #} if [ "$QDB_REDEPLOY" == "YES" ]; then qdb_undeploy #elif [ "$QDB_DROP_TABLE_IF_EXISTS" == "YES" ]; then # qdb_drop_table fi qdb_deploy deploy/tfs.sh +42 −40 Original line number Diff line number Diff line Loading @@ -57,6 +57,18 @@ export CRDB_DATABASE=${CRDB_DATABASE:-"tfs"} # If not already set, set the namespace where NATS will be deployed. export NATS_NAMESPACE=${NATS_NAMESPACE:-"nats"} # If not already set, set the namespace where QuestDB will be deployed. export QDB_NAMESPACE=${QDB_NAMESPACE:-"qdb"} # If not already set, set the database username to be used by Monitoring. export QDB_USERNAME=${QDB_USERNAME:-"admin"} # If not already set, set the database user's password to be used by Monitoring. export QDB_PASSWORD=${QDB_PASSWORD:-"quest"} # If not already set, set the table name to be used by Monitoring. export QDB_TABLE=${QDB_TABLE:-"tfs_monitoring"} ######################################################################################################################## # Automated steps start here Loading Loading @@ -95,6 +107,22 @@ kubectl create secret generic nats-data --namespace ${TFS_K8S_NAMESPACE} --type= --from-literal=NATS_CLIENT_PORT=${NATS_CLIENT_PORT} printf "\n" echo "Create secret with QuestDB data" QDB_HTTP_PORT=$(kubectl --namespace ${QDB_NAMESPACE} get service questdb-public -o 'jsonpath={.spec.ports[?(@.name=="http")].port}') QDB_ILP_PORT=$(kubectl --namespace ${QDB_NAMESPACE} get service questdb-public -o 'jsonpath={.spec.ports[?(@.name=="ilp")].port}') QDB_SQL_PORT=$(kubectl --namespace ${QDB_NAMESPACE} get service questdb-public -o 'jsonpath={.spec.ports[?(@.name=="sql")].port}') METRICSDB_HOSTNAME="questdb-public.${QDB_NAMESPACE}.svc.cluster.local" kubectl create secret generic qdb-data --namespace ${TFS_K8S_NAMESPACE} --type='Opaque' \ --from-literal=QDB_NAMESPACE=${QDB_NAMESPACE} \ --from-literal=METRICSDB_HOSTNAME=${METRICSDB_HOSTNAME} \ --from-literal=METRICSDB_REST_PORT=${QDB_HTTP_PORT} \ --from-literal=METRICSDB_ILP_PORT=${QDB_ILP_PORT} \ --from-literal=METRICSDB_SQL_PORT=${QDB_SQL_PORT} \ --from-literal=METRICSDB_TABLE=${QDB_TABLE} \ --from-literal=METRICSDB_USERNAME=${QDB_USERNAME} \ --from-literal=METRICSDB_PASSWORD=${QDB_PASSWORD} printf "\n" echo "Deploying components and collecting environment variables..." ENV_VARS_SCRIPT=tfs_runtime_env_vars.sh echo "# Environment variables for TeraFlowSDN deployment" > $ENV_VARS_SCRIPT Loading Loading @@ -251,17 +279,6 @@ for EXTRA_MANIFEST in $TFS_EXTRA_MANIFESTS; do done printf "\n" # By now, leave these controls here. Some component dependencies are not well handled. if [[ "$TFS_COMPONENTS" == *"monitoring"* ]]; then echo "Waiting for 'MonitoringDB' component..." # Kubernetes does not implement --for='condition=available' for statefulsets. # By now, we assume a single replica of monitoringdb. To be updated in future releases. kubectl wait --namespace $TFS_K8S_NAMESPACE \ --for=jsonpath='{.status.readyReplicas}'=1 --timeout=300s statefulset/monitoringdb printf "\n" fi for COMPONENT in $TFS_COMPONENTS; do echo "Waiting for '$COMPONENT' component..." COMPONENT_OBJNAME=$(echo "${COMPONENT}" | sed "s/\_/-/") Loading @@ -272,36 +289,19 @@ done if [[ "$TFS_COMPONENTS" == *"webui"* ]] && [[ "$TFS_COMPONENTS" == *"monitoring"* ]]; then echo "Configuring WebUI DataStores and Dashboards..." sleep 3 # INFLUXDB_HOST="monitoringservice" # INFLUXDB_PORT=$(kubectl --namespace $TFS_K8S_NAMESPACE get service/monitoringservice -o jsonpath='{.spec.ports[?(@.name=="influxdb")].port}') # INFLUXDB_URL="http://${INFLUXDB_HOST}:${INFLUXDB_PORT}" # INFLUXDB_USER=$(kubectl --namespace $TFS_K8S_NAMESPACE get secrets influxdb-secrets -o jsonpath='{.data.INFLUXDB_ADMIN_USER}' | base64 --decode) # INFLUXDB_PASSWORD=$(kubectl --namespace $TFS_K8S_NAMESPACE get secrets influxdb-secrets -o jsonpath='{.data.INFLUXDB_ADMIN_PASSWORD}' | base64 --decode) # INFLUXDB_DATABASE=$(kubectl --namespace $TFS_K8S_NAMESPACE get secrets influxdb-secrets -o jsonpath='{.data.INFLUXDB_DB}' | base64 --decode) sleep 5 # Exposed through the ingress controller "tfs-ingress" GRAFANA_HOSTNAME="127.0.0.1" GRAFANA_PORT="80" GRAFANA_BASEURL="/grafana" GRAFANA_URL="127.0.0.1:80/grafana" # Default Grafana credentials GRAFANA_USERNAME="admin" GRAFANA_PASSWORD="admin" # Default Grafana API URL GRAFANA_URL_DEFAULT="http://${GRAFANA_USERNAME}:${GRAFANA_PASSWORD}@${GRAFANA_HOSTNAME}:${GRAFANA_PORT}${GRAFANA_BASEURL}" # Updated Grafana API URL GRAFANA_URL_UPDATED="http://${GRAFANA_USERNAME}:${TFS_GRAFANA_PASSWORD}@${GRAFANA_HOSTNAME}:${GRAFANA_PORT}${GRAFANA_BASEURL}" echo "export GRAFANA_URL_UPDATED=${GRAFANA_URL_UPDATED}" >> $ENV_VARS_SCRIPT echo "Connecting to grafana at URL: ${GRAFANA_URL_DEFAULT}..." # Configure Grafana Admin Password # Ref: https://grafana.com/docs/grafana/latest/http_api/user/#change-password GRAFANA_URL_DEFAULT="http://${GRAFANA_USERNAME}:${GRAFANA_PASSWORD}@${GRAFANA_URL}" echo "Connecting to grafana at URL: ${GRAFANA_URL_DEFAULT}..." curl -X PUT -H "Content-Type: application/json" -d '{ "oldPassword": "'${GRAFANA_PASSWORD}'", "newPassword": "'${TFS_GRAFANA_PASSWORD}'", Loading @@ -309,16 +309,21 @@ if [[ "$TFS_COMPONENTS" == *"webui"* ]] && [[ "$TFS_COMPONENTS" == *"monitoring" }' ${GRAFANA_URL_DEFAULT}/api/user/password echo # Updated Grafana API URL GRAFANA_URL_UPDATED="http://${GRAFANA_USERNAME}:${TFS_GRAFANA_PASSWORD}@${GRAFANA_URL}" echo "export GRAFANA_URL_UPDATED=${GRAFANA_URL_UPDATED}" >> $ENV_VARS_SCRIPT # Ref: https://grafana.com/docs/grafana/latest/http_api/data_source/ # TODO: replace user, password and database by variables to be saved QDB_HOST_PORT="${METRICSDB_HOSTNAME}:${QDB_SQL_PORT}" echo "Creating a datasource..." curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -d '{ "access" : "proxy", "type" : "postgres", "name" : "monitoringdb", "url" : "monitoringservice:8812", "database" : "monitoring", "user" : "admin", "name" : "questdb", "url" : "'${QDB_HOST_PORT}'", "database" : "'${QDB_TABLE}'", "user" : "'${QDB_USERNAME}'", "basicAuth": false, "isDefault": true, "jsonData" : { Loading @@ -333,9 +338,7 @@ if [[ "$TFS_COMPONENTS" == *"webui"* ]] && [[ "$TFS_COMPONENTS" == *"monitoring" "tlsConfigurationMethod": "file-path", "tlsSkipVerify" : true }, "secureJsonData": { "password": "quest" } "secureJsonData": {"password": "'${QDB_PASSWORD}'"} }' ${GRAFANA_URL_UPDATED}/api/datasources echo Loading @@ -352,4 +355,3 @@ if [[ "$TFS_COMPONENTS" == *"webui"* ]] && [[ "$TFS_COMPONENTS" == *"monitoring" printf "\n\n" fi manifests/monitoringservice.yaml +9 −89 Original line number Diff line number Diff line Loading @@ -12,42 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. apiVersion: apps/v1 kind: StatefulSet metadata: name: monitoringdb spec: selector: matchLabels: app: monitoringservice serviceName: "monitoringservice" replicas: 1 template: metadata: labels: app: monitoringservice spec: terminationGracePeriodSeconds: 5 restartPolicy: Always containers: - name: metricsdb image: questdb/questdb ports: - name: http containerPort: 9000 protocol: TCP - name: influxdb containerPort: 9009 protocol: TCP - name: postgre containerPort: 8812 protocol: TCP env: - name: QDB_CAIRO_COMMIT_LAG value: "1000" - name: QDB_CAIRO_MAX_UNCOMMITTED_ROWS value: "100000" --- apiVersion: apps/v1 kind: Deployment metadata: Loading @@ -63,29 +27,19 @@ spec: app: monitoringservice spec: terminationGracePeriodSeconds: 5 restartPolicy: Always containers: - name: server image: labs.etsi.org:5050/tfs/controller/monitoring:latest imagePullPolicy: Always ports: - name: grpc containerPort: 7070 protocol: TCP - name: metrics containerPort: 9192 protocol: TCP - containerPort: 7070 - containerPort: 9192 env: - name: LOG_LEVEL value: "INFO" - name: METRICSDB_HOSTNAME value: "monitoringservice" - name: METRICSDB_ILP_PORT value: "9009" - name: METRICSDB_REST_PORT value: "9000" - name: METRICSDB_TABLE value: "monitoring" envFrom: - secretRef: name: qdb-data readinessProbe: exec: command: ["/bin/grpc_health_probe", "-addr=:7070"] Loading @@ -94,11 +48,11 @@ spec: command: ["/bin/grpc_health_probe", "-addr=:7070"] resources: requests: cpu: 250m memory: 512Mi cpu: 50m memory: 64Mi limits: cpu: 700m memory: 1024Mi cpu: 500m memory: 512Mi --- apiVersion: v1 kind: Service Loading @@ -115,41 +69,7 @@ spec: protocol: TCP port: 7070 targetPort: 7070 - name: http protocol: TCP port: 9000 targetPort: 9000 - name: influxdb protocol: TCP port: 9009 targetPort: 9009 - name: postgre protocol: TCP port: 8812 targetPort: 8812 - name: metrics protocol: TCP port: 9192 targetPort: 9192 --- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: access-monitoring spec: podSelector: matchLabels: app: monitoringservice ingress: - from: [] ports: - port: 7070 - port: 8812 - from: - podSelector: matchLabels: app: monitoringservice ports: - port: 9009 - port: 9000 Loading
deploy/all.sh +39 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,9 @@ # Read deployment settings ######################################################################################################################## # ----- TeraFlowSDN ------------------------------------------------------------ # If not already set, set the URL of the Docker registry where the images will be uploaded to. # By default, assume internal MicroK8s registry is used. export TFS_REGISTRY_IMAGES=${TFS_REGISTRY_IMAGES:-"http://localhost:32000/tfs/"} Loading @@ -42,6 +45,9 @@ export TFS_GRAFANA_PASSWORD=${TFS_GRAFANA_PASSWORD:-"admin123+"} # If TFS_SKIP_BUILD is "YES", the containers are not rebuilt-retagged-repushed and existing ones are used. export TFS_SKIP_BUILD=${TFS_SKIP_BUILD:-""} # ----- CockroachDB ------------------------------------------------------------ # If not already set, set the namespace where CockroackDB will be deployed. export CRDB_NAMESPACE=${CRDB_NAMESPACE:-"crdb"} Loading Loading @@ -84,6 +90,9 @@ export CRDB_DROP_DATABASE_IF_EXISTS=${CRDB_DROP_DATABASE_IF_EXISTS:-""} # If CRDB_REDEPLOY is "YES", the database will be dropped while checking/deploying CockroachDB. export CRDB_REDEPLOY=${CRDB_REDEPLOY:-""} # ----- NATS ------------------------------------------------------------------- # If not already set, set the namespace where NATS will be deployed. export NATS_NAMESPACE=${NATS_NAMESPACE:-"nats"} Loading @@ -99,6 +108,32 @@ export NATS_SECRET_NAMESPACE=${NATS_SECRET_NAMESPACE:-${TFS_K8S_NAMESPACE}} export NATS_REDEPLOY=${NATS_REDEPLOY:-""} # ----- QuestDB ---------------------------------------------------------------- # If not already set, set the namespace where QuestDB will be deployed. export QDB_NAMESPACE=${QDB_NAMESPACE:-"qdb"} # If not already set, set the database username to be used by Monitoring. export QDB_USERNAME=${QDB_USERNAME:-"admin"} # If not already set, set the database user's password to be used by Monitoring. export QDB_PASSWORD=${QDB_PASSWORD:-"quest"} # If not already set, set the table name to be used by Monitoring. export QDB_TABLE=${QDB_TABLE:-"tfs_monitoring"} ## If not already set, disable flag for dropping table if exists. ## WARNING: ACTIVATING THIS FLAG IMPLIES LOOSING THE TABLE INFORMATION! ## If QDB_DROP_TABLE_IF_EXISTS is "YES", the table pointed by variable QDB_TABLE will be dropped while ## checking/deploying QuestDB. #export QDB_DROP_TABLE_IF_EXISTS=${QDB_DROP_TABLE_IF_EXISTS:-""} # If not already set, disable flag for re-deploying QuestDB from scratch. # WARNING: ACTIVATING THIS FLAG IMPLIES LOOSING THE DATABASE INFORMATION! # If QDB_REDEPLOY is "YES", the database will be dropped while checking/deploying QuestDB. export QDB_REDEPLOY=${QDB_REDEPLOY:-""} ######################################################################################################################## # Automated steps start here ######################################################################################################################## Loading @@ -109,7 +144,10 @@ export NATS_REDEPLOY=${NATS_REDEPLOY:-""} # Deploy NATS ./deploy/nats.sh # Deploy TFS # Deploy QuestDB ./deploy/qdb.sh # Deploy TeraFlowSDN ./deploy/tfs.sh # Show deploy summary Loading
deploy/crdb.sh +1 −1 Original line number Diff line number Diff line Loading @@ -44,7 +44,7 @@ export CRDB_DEPLOY_MODE=${CRDB_DEPLOY_MODE:-"single"} # If not already set, disable flag for dropping database if exists. # WARNING: ACTIVATING THIS FLAG IMPLIES LOOSING THE DATABASE INFORMATION! # If CRDB_DROP_DATABASE_IF_EXISTS is "YES", the database pointed by variable CRDB_NAMESPACE will be dropped while # If CRDB_DROP_DATABASE_IF_EXISTS is "YES", the database pointed by variable CRDB_DATABASE will be dropped while # checking/deploying CockroachDB. export CRDB_DROP_DATABASE_IF_EXISTS=${CRDB_DROP_DATABASE_IF_EXISTS:-""} Loading
deploy/qdb.sh 0 → 100755 +165 −0 Original line number Diff line number Diff line #!/bin/bash # Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/) # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ######################################################################################################################## # Read deployment settings ######################################################################################################################## # If not already set, set the namespace where QuestDB will be deployed. export QDB_NAMESPACE=${QDB_NAMESPACE:-"qdb"} # If not already set, set the database username to be used by Monitoring. export QDB_USERNAME=${QDB_USERNAME:-"admin"} # If not already set, set the database user's password to be used by Monitoring. export QDB_PASSWORD=${QDB_PASSWORD:-"quest"} # If not already set, set the table name to be used by Monitoring. export QDB_TABLE=${QDB_TABLE:-"tfs_monitoring"} ## If not already set, disable flag for dropping table if exists. ## WARNING: ACTIVATING THIS FLAG IMPLIES LOOSING THE TABLE INFORMATION! ## If QDB_DROP_TABLE_IF_EXISTS is "YES", the table pointed by variable QDB_TABLE will be dropped while ## checking/deploying QuestDB. #export QDB_DROP_TABLE_IF_EXISTS=${QDB_DROP_TABLE_IF_EXISTS:-""} # If not already set, disable flag for re-deploying QuestDB from scratch. # WARNING: ACTIVATING THIS FLAG IMPLIES LOOSING THE DATABASE INFORMATION! # If QDB_REDEPLOY is "YES", the database will be dropped while checking/deploying QuestDB. export QDB_REDEPLOY=${QDB_REDEPLOY:-""} ######################################################################################################################## # Automated steps start here ######################################################################################################################## # Constants TMP_FOLDER="./tmp" QDB_MANIFESTS_PATH="manifests/questdb" # Create a tmp folder for files modified during the deployment TMP_MANIFESTS_FOLDER="$TMP_FOLDER/manifests" TMP_LOGS_FOLDER="$TMP_FOLDER/logs" QDB_LOG_FILE="$TMP_LOGS_FOLDER/qdb_deploy.log" mkdir -p $TMP_LOGS_FOLDER function qdb_deploy() { echo "QuestDB Namespace" echo ">>> Create QuestDB Namespace (if missing)" kubectl create namespace ${QDB_NAMESPACE} echo echo "QuestDB" echo ">>> Checking if QuestDB is deployed..." if kubectl get --namespace ${QDB_NAMESPACE} statefulset/questdb &> /dev/null; then echo ">>> QuestDB is present; skipping step." else echo ">>> Deploy QuestDB" cp "${QDB_MANIFESTS_PATH}/manifest.yaml" "${TMP_MANIFESTS_FOLDER}/qdb_manifest.yaml" kubectl apply --namespace ${QDB_NAMESPACE} -f "${TMP_MANIFESTS_FOLDER}/qdb_manifest.yaml" echo ">>> Waiting QuestDB statefulset to be created..." while ! kubectl get --namespace ${QDB_NAMESPACE} statefulset/questdb &> /dev/null; do printf "%c" "." sleep 1 done # Wait for statefulset condition "Available=True" does not work # Wait for statefulset condition "jsonpath='{.status.readyReplicas}'=3" throws error: # "error: readyReplicas is not found" # Workaround: Check the pods are ready #echo ">>> QuestDB statefulset created. Waiting for readiness condition..." #kubectl wait --namespace ${QDB_NAMESPACE} --for=condition=Available=True --timeout=300s statefulset/questdb #kubectl wait --namespace ${QDB_NAMESPACE} --for=jsonpath='{.status.readyReplicas}'=3 --timeout=300s \ # statefulset/questdb echo ">>> QuestDB statefulset created. Waiting QuestDB pods to be created..." while ! kubectl get --namespace ${QDB_NAMESPACE} pod/questdb-0 &> /dev/null; do printf "%c" "." sleep 1 done kubectl wait --namespace ${QDB_NAMESPACE} --for=condition=Ready --timeout=300s pod/questdb-0 fi echo echo "QuestDB Port Mapping" echo ">>> Expose QuestDB SQL port (8812->8812)" QDB_SQL_PORT=$(kubectl --namespace ${QDB_NAMESPACE} get service questdb-public -o 'jsonpath={.spec.ports[?(@.name=="sql")].port}') PATCH='{"data": {"'${QDB_SQL_PORT}'": "'${QDB_NAMESPACE}'/questdb-public:'${QDB_SQL_PORT}'"}}' kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" PORT_MAP='{"containerPort": '${QDB_SQL_PORT}', "hostPort": '${QDB_SQL_PORT}'}' CONTAINER='{"name": "nginx-ingress-microk8s", "ports": ['${PORT_MAP}']}' PATCH='{"spec": {"template": {"spec": {"containers": ['${CONTAINER}']}}}}' kubectl patch daemonset nginx-ingress-microk8s-controller --namespace ingress --patch "${PATCH}" echo echo ">>> Expose QuestDB Influx Line Protocol port (9009->9009)" QDB_ILP_PORT=$(kubectl --namespace ${QDB_NAMESPACE} get service questdb-public -o 'jsonpath={.spec.ports[?(@.name=="ilp")].port}') PATCH='{"data": {"'${QDB_ILP_PORT}'": "'${QDB_NAMESPACE}'/questdb-public:'${QDB_ILP_PORT}'"}}' kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" PORT_MAP='{"containerPort": '${QDB_ILP_PORT}', "hostPort": '${QDB_ILP_PORT}'}' CONTAINER='{"name": "nginx-ingress-microk8s", "ports": ['${PORT_MAP}']}' PATCH='{"spec": {"template": {"spec": {"containers": ['${CONTAINER}']}}}}' kubectl patch daemonset nginx-ingress-microk8s-controller --namespace ingress --patch "${PATCH}" echo echo ">>> Expose QuestDB HTTP Mgmt GUI port (9000->9000)" QDB_GUI_PORT=$(kubectl --namespace ${QDB_NAMESPACE} get service questdb-public -o 'jsonpath={.spec.ports[?(@.name=="http")].port}') PATCH='{"data": {"'${QDB_GUI_PORT}'": "'${QDB_NAMESPACE}'/questdb-public:'${QDB_GUI_PORT}'"}}' kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" PORT_MAP='{"containerPort": '${QDB_GUI_PORT}', "hostPort": '${QDB_GUI_PORT}'}' CONTAINER='{"name": "nginx-ingress-microk8s", "ports": ['${PORT_MAP}']}' PATCH='{"spec": {"template": {"spec": {"containers": ['${CONTAINER}']}}}}' kubectl patch daemonset nginx-ingress-microk8s-controller --namespace ingress --patch "${PATCH}" echo } function qdb_undeploy() { echo "QuestDB" echo ">>> Checking if QuestDB is deployed..." if kubectl get --namespace ${QDB_NAMESPACE} statefulset/questdb &> /dev/null; then echo ">>> Undeploy QuestDB" kubectl delete --namespace ${QDB_NAMESPACE} -f "${TMP_MANIFESTS_FOLDER}/qdb_manifest.yaml" --ignore-not-found else echo ">>> QuestDB is not present; skipping step." fi echo echo "QuestDB Namespace" echo ">>> Delete QuestDB Namespace (if exists)" echo "NOTE: this step might take few minutes to complete!" kubectl delete namespace ${QDB_NAMESPACE} --ignore-not-found echo } # TODO: implement method to drop table #function qdb_drop_table() { # echo "Drop table if exists" # QDB_CLIENT_URL="postgresql://${QDB_USERNAME}:${QDB_PASSWORD}@questdb-0:${QDB_SQL_PORT}/defaultdb?sslmode=require" # kubectl exec -it --namespace ${QDB_NAMESPACE} questdb-0 -- \ # ./qdb sql --certs-dir=/qdb/qdb-certs --url=${QDB_CLIENT_URL} \ # --execute "DROP TABLE IF EXISTS ${QDB_TABLE};" # echo #} if [ "$QDB_REDEPLOY" == "YES" ]; then qdb_undeploy #elif [ "$QDB_DROP_TABLE_IF_EXISTS" == "YES" ]; then # qdb_drop_table fi qdb_deploy
deploy/tfs.sh +42 −40 Original line number Diff line number Diff line Loading @@ -57,6 +57,18 @@ export CRDB_DATABASE=${CRDB_DATABASE:-"tfs"} # If not already set, set the namespace where NATS will be deployed. export NATS_NAMESPACE=${NATS_NAMESPACE:-"nats"} # If not already set, set the namespace where QuestDB will be deployed. export QDB_NAMESPACE=${QDB_NAMESPACE:-"qdb"} # If not already set, set the database username to be used by Monitoring. export QDB_USERNAME=${QDB_USERNAME:-"admin"} # If not already set, set the database user's password to be used by Monitoring. export QDB_PASSWORD=${QDB_PASSWORD:-"quest"} # If not already set, set the table name to be used by Monitoring. export QDB_TABLE=${QDB_TABLE:-"tfs_monitoring"} ######################################################################################################################## # Automated steps start here Loading Loading @@ -95,6 +107,22 @@ kubectl create secret generic nats-data --namespace ${TFS_K8S_NAMESPACE} --type= --from-literal=NATS_CLIENT_PORT=${NATS_CLIENT_PORT} printf "\n" echo "Create secret with QuestDB data" QDB_HTTP_PORT=$(kubectl --namespace ${QDB_NAMESPACE} get service questdb-public -o 'jsonpath={.spec.ports[?(@.name=="http")].port}') QDB_ILP_PORT=$(kubectl --namespace ${QDB_NAMESPACE} get service questdb-public -o 'jsonpath={.spec.ports[?(@.name=="ilp")].port}') QDB_SQL_PORT=$(kubectl --namespace ${QDB_NAMESPACE} get service questdb-public -o 'jsonpath={.spec.ports[?(@.name=="sql")].port}') METRICSDB_HOSTNAME="questdb-public.${QDB_NAMESPACE}.svc.cluster.local" kubectl create secret generic qdb-data --namespace ${TFS_K8S_NAMESPACE} --type='Opaque' \ --from-literal=QDB_NAMESPACE=${QDB_NAMESPACE} \ --from-literal=METRICSDB_HOSTNAME=${METRICSDB_HOSTNAME} \ --from-literal=METRICSDB_REST_PORT=${QDB_HTTP_PORT} \ --from-literal=METRICSDB_ILP_PORT=${QDB_ILP_PORT} \ --from-literal=METRICSDB_SQL_PORT=${QDB_SQL_PORT} \ --from-literal=METRICSDB_TABLE=${QDB_TABLE} \ --from-literal=METRICSDB_USERNAME=${QDB_USERNAME} \ --from-literal=METRICSDB_PASSWORD=${QDB_PASSWORD} printf "\n" echo "Deploying components and collecting environment variables..." ENV_VARS_SCRIPT=tfs_runtime_env_vars.sh echo "# Environment variables for TeraFlowSDN deployment" > $ENV_VARS_SCRIPT Loading Loading @@ -251,17 +279,6 @@ for EXTRA_MANIFEST in $TFS_EXTRA_MANIFESTS; do done printf "\n" # By now, leave these controls here. Some component dependencies are not well handled. if [[ "$TFS_COMPONENTS" == *"monitoring"* ]]; then echo "Waiting for 'MonitoringDB' component..." # Kubernetes does not implement --for='condition=available' for statefulsets. # By now, we assume a single replica of monitoringdb. To be updated in future releases. kubectl wait --namespace $TFS_K8S_NAMESPACE \ --for=jsonpath='{.status.readyReplicas}'=1 --timeout=300s statefulset/monitoringdb printf "\n" fi for COMPONENT in $TFS_COMPONENTS; do echo "Waiting for '$COMPONENT' component..." COMPONENT_OBJNAME=$(echo "${COMPONENT}" | sed "s/\_/-/") Loading @@ -272,36 +289,19 @@ done if [[ "$TFS_COMPONENTS" == *"webui"* ]] && [[ "$TFS_COMPONENTS" == *"monitoring"* ]]; then echo "Configuring WebUI DataStores and Dashboards..." sleep 3 # INFLUXDB_HOST="monitoringservice" # INFLUXDB_PORT=$(kubectl --namespace $TFS_K8S_NAMESPACE get service/monitoringservice -o jsonpath='{.spec.ports[?(@.name=="influxdb")].port}') # INFLUXDB_URL="http://${INFLUXDB_HOST}:${INFLUXDB_PORT}" # INFLUXDB_USER=$(kubectl --namespace $TFS_K8S_NAMESPACE get secrets influxdb-secrets -o jsonpath='{.data.INFLUXDB_ADMIN_USER}' | base64 --decode) # INFLUXDB_PASSWORD=$(kubectl --namespace $TFS_K8S_NAMESPACE get secrets influxdb-secrets -o jsonpath='{.data.INFLUXDB_ADMIN_PASSWORD}' | base64 --decode) # INFLUXDB_DATABASE=$(kubectl --namespace $TFS_K8S_NAMESPACE get secrets influxdb-secrets -o jsonpath='{.data.INFLUXDB_DB}' | base64 --decode) sleep 5 # Exposed through the ingress controller "tfs-ingress" GRAFANA_HOSTNAME="127.0.0.1" GRAFANA_PORT="80" GRAFANA_BASEURL="/grafana" GRAFANA_URL="127.0.0.1:80/grafana" # Default Grafana credentials GRAFANA_USERNAME="admin" GRAFANA_PASSWORD="admin" # Default Grafana API URL GRAFANA_URL_DEFAULT="http://${GRAFANA_USERNAME}:${GRAFANA_PASSWORD}@${GRAFANA_HOSTNAME}:${GRAFANA_PORT}${GRAFANA_BASEURL}" # Updated Grafana API URL GRAFANA_URL_UPDATED="http://${GRAFANA_USERNAME}:${TFS_GRAFANA_PASSWORD}@${GRAFANA_HOSTNAME}:${GRAFANA_PORT}${GRAFANA_BASEURL}" echo "export GRAFANA_URL_UPDATED=${GRAFANA_URL_UPDATED}" >> $ENV_VARS_SCRIPT echo "Connecting to grafana at URL: ${GRAFANA_URL_DEFAULT}..." # Configure Grafana Admin Password # Ref: https://grafana.com/docs/grafana/latest/http_api/user/#change-password GRAFANA_URL_DEFAULT="http://${GRAFANA_USERNAME}:${GRAFANA_PASSWORD}@${GRAFANA_URL}" echo "Connecting to grafana at URL: ${GRAFANA_URL_DEFAULT}..." curl -X PUT -H "Content-Type: application/json" -d '{ "oldPassword": "'${GRAFANA_PASSWORD}'", "newPassword": "'${TFS_GRAFANA_PASSWORD}'", Loading @@ -309,16 +309,21 @@ if [[ "$TFS_COMPONENTS" == *"webui"* ]] && [[ "$TFS_COMPONENTS" == *"monitoring" }' ${GRAFANA_URL_DEFAULT}/api/user/password echo # Updated Grafana API URL GRAFANA_URL_UPDATED="http://${GRAFANA_USERNAME}:${TFS_GRAFANA_PASSWORD}@${GRAFANA_URL}" echo "export GRAFANA_URL_UPDATED=${GRAFANA_URL_UPDATED}" >> $ENV_VARS_SCRIPT # Ref: https://grafana.com/docs/grafana/latest/http_api/data_source/ # TODO: replace user, password and database by variables to be saved QDB_HOST_PORT="${METRICSDB_HOSTNAME}:${QDB_SQL_PORT}" echo "Creating a datasource..." curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -d '{ "access" : "proxy", "type" : "postgres", "name" : "monitoringdb", "url" : "monitoringservice:8812", "database" : "monitoring", "user" : "admin", "name" : "questdb", "url" : "'${QDB_HOST_PORT}'", "database" : "'${QDB_TABLE}'", "user" : "'${QDB_USERNAME}'", "basicAuth": false, "isDefault": true, "jsonData" : { Loading @@ -333,9 +338,7 @@ if [[ "$TFS_COMPONENTS" == *"webui"* ]] && [[ "$TFS_COMPONENTS" == *"monitoring" "tlsConfigurationMethod": "file-path", "tlsSkipVerify" : true }, "secureJsonData": { "password": "quest" } "secureJsonData": {"password": "'${QDB_PASSWORD}'"} }' ${GRAFANA_URL_UPDATED}/api/datasources echo Loading @@ -352,4 +355,3 @@ if [[ "$TFS_COMPONENTS" == *"webui"* ]] && [[ "$TFS_COMPONENTS" == *"monitoring" printf "\n\n" fi
manifests/monitoringservice.yaml +9 −89 Original line number Diff line number Diff line Loading @@ -12,42 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. apiVersion: apps/v1 kind: StatefulSet metadata: name: monitoringdb spec: selector: matchLabels: app: monitoringservice serviceName: "monitoringservice" replicas: 1 template: metadata: labels: app: monitoringservice spec: terminationGracePeriodSeconds: 5 restartPolicy: Always containers: - name: metricsdb image: questdb/questdb ports: - name: http containerPort: 9000 protocol: TCP - name: influxdb containerPort: 9009 protocol: TCP - name: postgre containerPort: 8812 protocol: TCP env: - name: QDB_CAIRO_COMMIT_LAG value: "1000" - name: QDB_CAIRO_MAX_UNCOMMITTED_ROWS value: "100000" --- apiVersion: apps/v1 kind: Deployment metadata: Loading @@ -63,29 +27,19 @@ spec: app: monitoringservice spec: terminationGracePeriodSeconds: 5 restartPolicy: Always containers: - name: server image: labs.etsi.org:5050/tfs/controller/monitoring:latest imagePullPolicy: Always ports: - name: grpc containerPort: 7070 protocol: TCP - name: metrics containerPort: 9192 protocol: TCP - containerPort: 7070 - containerPort: 9192 env: - name: LOG_LEVEL value: "INFO" - name: METRICSDB_HOSTNAME value: "monitoringservice" - name: METRICSDB_ILP_PORT value: "9009" - name: METRICSDB_REST_PORT value: "9000" - name: METRICSDB_TABLE value: "monitoring" envFrom: - secretRef: name: qdb-data readinessProbe: exec: command: ["/bin/grpc_health_probe", "-addr=:7070"] Loading @@ -94,11 +48,11 @@ spec: command: ["/bin/grpc_health_probe", "-addr=:7070"] resources: requests: cpu: 250m memory: 512Mi cpu: 50m memory: 64Mi limits: cpu: 700m memory: 1024Mi cpu: 500m memory: 512Mi --- apiVersion: v1 kind: Service Loading @@ -115,41 +69,7 @@ spec: protocol: TCP port: 7070 targetPort: 7070 - name: http protocol: TCP port: 9000 targetPort: 9000 - name: influxdb protocol: TCP port: 9009 targetPort: 9009 - name: postgre protocol: TCP port: 8812 targetPort: 8812 - name: metrics protocol: TCP port: 9192 targetPort: 9192 --- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: access-monitoring spec: podSelector: matchLabels: app: monitoringservice ingress: - from: [] ports: - port: 7070 - port: 8812 - from: - podSelector: matchLabels: app: monitoringservice ports: - port: 9009 - port: 9000