Skip to content
Snippets Groups Projects
Commit f1a63185 authored by David José Araújo Ferreira's avatar David José Araújo Ferreira
Browse files

NGINX and redeployall

default variables set

code refactoring

NATS cluster complete

Startup Probe failling in NATS cluster mode

Cockroach cluster operator and NATS cluster mode

Update

Update scheduling policy for CRDB

NATS cluster mode

Testing CRDB cluster with node affinity

Revert "Testing dynamic node resources"

This reverts commit 856eb479.

Testing dynamic node resources

NGINX and redeployall

Update my_deploy.sh

Update nginx_ingress_http.yaml

Redeploy all fixed

Add redeploy all feature
parent 67633159
No related branches found
No related tags found
2 merge requests!294Release TeraFlowSDN 4.0,!226Resolve "Testing configurations for DDOS protection"
...@@ -18,6 +18,11 @@ ...@@ -18,6 +18,11 @@
# Read deployment settings # Read deployment settings
######################################################################################################################## ########################################################################################################################
# ----- Redeploy All ------------------------------------------------------------
# If not already set, enables all components redeployment
export REDEPLOYALL=${REDEPLOYALL:-""}
# ----- TeraFlowSDN ------------------------------------------------------------ # ----- TeraFlowSDN ------------------------------------------------------------
...@@ -102,6 +107,15 @@ export NATS_EXT_PORT_CLIENT=${NATS_EXT_PORT_CLIENT:-"4222"} ...@@ -102,6 +107,15 @@ export NATS_EXT_PORT_CLIENT=${NATS_EXT_PORT_CLIENT:-"4222"}
# If not already set, set the external port NATS HTTP Mgmt GUI interface will be exposed to. # If not already set, set the external port NATS HTTP Mgmt GUI interface will be exposed to.
export NATS_EXT_PORT_HTTP=${NATS_EXT_PORT_HTTP:-"8222"} export NATS_EXT_PORT_HTTP=${NATS_EXT_PORT_HTTP:-"8222"}
# TESTING
# If not already set, set NATS installation mode. Accepted values are: 'single' and 'cluster'.
# - If NATS_DEPLOY_MODE is "single", NATS is deployed in single node mode. It is convenient for
# development and testing purposes and should fit in a VM. IT SHOULD NOT BE USED IN PRODUCTION ENVIRONMENTS.
# - If NATS_DEPLOY_MODE is "cluster", NATS is deployed in cluster mode, and an entire NATS cluster
# with 3 replicas (set by default) will be deployed. It is convenient for production and
# provides scalability features.
export NATS_DEPLOY_MODE=${NATS_DEPLOY_MODE:-"single"}
# If not already set, disable flag for re-deploying NATS from scratch. # If not already set, disable flag for re-deploying NATS from scratch.
# WARNING: ACTIVATING THIS FLAG IMPLIES LOOSING THE MESSAGE BROKER INFORMATION! # WARNING: ACTIVATING THIS FLAG IMPLIES LOOSING THE MESSAGE BROKER INFORMATION!
# If NATS_REDEPLOY is "YES", the message broker will be dropped while checking/deploying NATS. # If NATS_REDEPLOY is "YES", the message broker will be dropped while checking/deploying NATS.
......
...@@ -18,6 +18,11 @@ ...@@ -18,6 +18,11 @@
# Read deployment settings # Read deployment settings
######################################################################################################################## ########################################################################################################################
# ----- Redeploy All ------------------------------------------------------------
# If not already set, enables all components redeployment
export REDEPLOYALL=${REDEPLOYALL:-""}
# If not already set, set the namespace where CockroackDB will be deployed. # If not already set, set the namespace where CockroackDB will be deployed.
export CRDB_NAMESPACE=${CRDB_NAMESPACE:-"crdb"} export CRDB_NAMESPACE=${CRDB_NAMESPACE:-"crdb"}
...@@ -223,7 +228,7 @@ function crdb_deploy_cluster() { ...@@ -223,7 +228,7 @@ function crdb_deploy_cluster() {
kubectl create namespace ${CRDB_NAMESPACE} kubectl create namespace ${CRDB_NAMESPACE}
echo echo
echo "CockroachDB" echo "CockroachDB (cluster-mode)"
echo ">>> Checking if CockroachDB is deployed..." echo ">>> Checking if CockroachDB is deployed..."
if kubectl get --namespace ${CRDB_NAMESPACE} statefulset/cockroachdb &> /dev/null; then if kubectl get --namespace ${CRDB_NAMESPACE} statefulset/cockroachdb &> /dev/null; then
echo ">>> CockroachDB is present; skipping step." echo ">>> CockroachDB is present; skipping step."
...@@ -360,7 +365,7 @@ function crdb_drop_database_cluster() { ...@@ -360,7 +365,7 @@ function crdb_drop_database_cluster() {
} }
if [ "$CRDB_DEPLOY_MODE" == "single" ]; then if [ "$CRDB_DEPLOY_MODE" == "single" ]; then
if [ "$CRDB_REDEPLOY" == "YES" ]; then if [ "$CRDB_REDEPLOY" == "YES" ] || [ "$REDEPLOYALL" == "YES" ]; then
crdb_undeploy_single crdb_undeploy_single
fi fi
...@@ -370,7 +375,7 @@ if [ "$CRDB_DEPLOY_MODE" == "single" ]; then ...@@ -370,7 +375,7 @@ if [ "$CRDB_DEPLOY_MODE" == "single" ]; then
crdb_drop_database_single crdb_drop_database_single
fi fi
elif [ "$CRDB_DEPLOY_MODE" == "cluster" ]; then elif [ "$CRDB_DEPLOY_MODE" == "cluster" ]; then
if [ "$CRDB_REDEPLOY" == "YES" ]; then if [ "$CRDB_REDEPLOY" == "YES" ] || [ "$REDEPLOYALL" == "YES" ]; then
crdb_undeploy_cluster crdb_undeploy_cluster
fi fi
......
...@@ -18,6 +18,10 @@ ...@@ -18,6 +18,10 @@
# Read deployment settings # Read deployment settings
######################################################################################################################## ########################################################################################################################
# ----- Redeploy All ------------------------------------------------------------
# If not already set, enables all components redeployment
export REDEPLOYALL=${REDEPLOYALL:-""}
# If not already set, set the namespace where NATS will be deployed. # If not already set, set the namespace where NATS will be deployed.
export NATS_NAMESPACE=${NATS_NAMESPACE:-"nats"} export NATS_NAMESPACE=${NATS_NAMESPACE:-"nats"}
...@@ -27,16 +31,32 @@ export NATS_EXT_PORT_CLIENT=${NATS_EXT_PORT_CLIENT:-"4222"} ...@@ -27,16 +31,32 @@ export NATS_EXT_PORT_CLIENT=${NATS_EXT_PORT_CLIENT:-"4222"}
# If not already set, set the external port NATS HTTP Mgmt GUI interface will be exposed to. # If not already set, set the external port NATS HTTP Mgmt GUI interface will be exposed to.
export NATS_EXT_PORT_HTTP=${NATS_EXT_PORT_HTTP:-"8222"} export NATS_EXT_PORT_HTTP=${NATS_EXT_PORT_HTTP:-"8222"}
# TESTING
# If not already set, set NATS installation mode. Accepted values are: 'single' and 'cluster'.
# - If NATS_DEPLOY_MODE is "single", NATS is deployed in single node mode. It is convenient for
# development and testing purposes and should fit in a VM. IT SHOULD NOT BE USED IN PRODUCTION ENVIRONMENTS.
# - If NATS_DEPLOY_MODE is "cluster", NATS is deployed in cluster mode, and an entire NATS cluster
# with 3 replicas (set by default) will be deployed. It is convenient for production and
# provides scalability features.
export NATS_DEPLOY_MODE=${NATS_DEPLOY_MODE:-"single"}
# If not already set, disable flag for re-deploying NATS from scratch. # If not already set, disable flag for re-deploying NATS from scratch.
# WARNING: ACTIVATING THIS FLAG IMPLIES LOOSING THE MESSAGE BROKER INFORMATION! # WARNING: ACTIVATING THIS FLAG IMPLIES LOOSING THE MESSAGE BROKER INFORMATION!
# If NATS_REDEPLOY is "YES", the message broker will be dropped while checking/deploying NATS. # If NATS_REDEPLOY is "YES", the message broker will be dropped while checking/deploying NATS.
export NATS_REDEPLOY=${NATS_REDEPLOY:-""} export NATS_REDEPLOY=${NATS_REDEPLOY:-""}
######################################################################################################################## ########################################################################################################################
# Automated steps start here # Automated steps start here
######################################################################################################################## ########################################################################################################################
# Constants
TMP_FOLDER="./tmp"
NATS_MANIFESTS_PATH="manifests/nats"
# Create a tmp folder for files modified during the deployment
TMP_MANIFESTS_FOLDER="${TMP_FOLDER}/${NATS_NAMESPACE}/manifests"
mkdir -p $TMP_MANIFESTS_FOLDER
function nats_deploy_single() { function nats_deploy_single() {
echo "NATS Namespace" echo "NATS Namespace"
echo ">>> Create NATS Namespace (if missing)" echo ">>> Create NATS Namespace (if missing)"
...@@ -47,18 +67,85 @@ function nats_deploy_single() { ...@@ -47,18 +67,85 @@ function nats_deploy_single() {
helm3 repo add nats https://nats-io.github.io/k8s/helm/charts/ helm3 repo add nats https://nats-io.github.io/k8s/helm/charts/
echo echo
echo "Install NATS (single-node)"
echo ">>> Checking if NATS is deployed..."
if kubectl get --namespace ${NATS_NAMESPACE} statefulset/${NATS_NAMESPACE} &> /dev/null; then
echo ">>> NATS is present; skipping step."
else
echo ">>> Deploy NATS"
helm3 install ${NATS_NAMESPACE} nats/nats --namespace ${NATS_NAMESPACE} --set nats.image=nats:2.9-alpine
echo ">>> Waiting NATS statefulset to be created..."
while ! kubectl get --namespace ${NATS_NAMESPACE} statefulset/${NATS_NAMESPACE} &> /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 ">>> NATS statefulset created. Waiting for readiness condition..."
#kubectl wait --namespace ${NATS_NAMESPACE} --for=condition=Available=True --timeout=300s statefulset/nats
#kubectl wait --namespace ${NATS_NAMESPACE} --for=jsonpath='{.status.readyReplicas}'=3 --timeout=300s \
# statefulset/nats
echo ">>> NATS statefulset created. Waiting NATS pods to be created..."
while ! kubectl get --namespace ${NATS_NAMESPACE} pod/${NATS_NAMESPACE}-0 &> /dev/null; do
printf "%c" "."
sleep 1
done
kubectl wait --namespace ${NATS_NAMESPACE} --for=condition=Ready --timeout=300s pod/${NATS_NAMESPACE}-0
fi
echo
echo "NATS Port Mapping"
echo ">>> Expose NATS Client port (4222->${NATS_EXT_PORT_CLIENT})"
NATS_PORT_CLIENT=$(kubectl --namespace ${NATS_NAMESPACE} get service ${NATS_NAMESPACE} -o 'jsonpath={.spec.ports[?(@.name=="client")].port}')
PATCH='{"data": {"'${NATS_EXT_PORT_CLIENT}'": "'${NATS_NAMESPACE}'/'${NATS_NAMESPACE}':'${NATS_PORT_CLIENT}'"}}'
kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}"
PORT_MAP='{"containerPort": '${NATS_EXT_PORT_CLIENT}', "hostPort": '${NATS_EXT_PORT_CLIENT}'}'
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 NATS HTTP Mgmt GUI port (8222->${NATS_EXT_PORT_HTTP})"
NATS_PORT_HTTP=$(kubectl --namespace ${NATS_NAMESPACE} get service ${NATS_NAMESPACE} -o 'jsonpath={.spec.ports[?(@.name=="monitor")].port}')
PATCH='{"data": {"'${NATS_EXT_PORT_HTTP}'": "'${NATS_NAMESPACE}'/'${NATS_NAMESPACE}':'${NATS_PORT_HTTP}'"}}'
kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}"
PORT_MAP='{"containerPort": '${NATS_EXT_PORT_HTTP}', "hostPort": '${NATS_EXT_PORT_HTTP}'}'
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 nats_deploy_cluster() {
echo "NATS Namespace"
echo ">>> Create NATS Namespace (if missing)"
kubectl create namespace ${NATS_NAMESPACE}
echo
echo "Add NATS Helm Chart"
helm3 repo add nats https://nats-io.github.io/k8s/helm/charts/
echo
echo "Upgrade NATS Helm Chart" echo "Upgrade NATS Helm Chart"
helm3 repo update nats helm3 repo update nats
echo echo
echo "Install NATS (single-node)" echo "Install NATS (cluster-mode)"
echo ">>> Checking if NATS is deployed..." echo ">>> Checking if NATS is deployed..."
if kubectl get --namespace ${NATS_NAMESPACE} statefulset/${NATS_NAMESPACE} &> /dev/null; then if kubectl get --namespace ${NATS_NAMESPACE} statefulset/${NATS_NAMESPACE} &> /dev/null; then
echo ">>> NATS is present; skipping step." echo ">>> NATS is present; skipping step."
else else
echo ">>> Deploy NATS" echo ">>> Deploy NATS"
helm3 install ${NATS_NAMESPACE} nats/nats --namespace ${NATS_NAMESPACE} --set nats.image=nats:2.9-alpine cp "${NATS_MANIFESTS_PATH}/cluster.yaml" "${TMP_MANIFESTS_FOLDER}/nats_cluster.yaml"
helm3 install ${NATS_NAMESPACE} nats/nats --namespace ${NATS_NAMESPACE} -f "${TMP_MANIFESTS_FOLDER}/nats_cluster.yaml"
echo ">>> Waiting NATS statefulset to be created..." echo ">>> Waiting NATS statefulset to be created..."
while ! kubectl get --namespace ${NATS_NAMESPACE} statefulset/${NATS_NAMESPACE} &> /dev/null; do while ! kubectl get --namespace ${NATS_NAMESPACE} statefulset/${NATS_NAMESPACE} &> /dev/null; do
printf "%c" "." printf "%c" "."
...@@ -78,7 +165,17 @@ function nats_deploy_single() { ...@@ -78,7 +165,17 @@ function nats_deploy_single() {
printf "%c" "." printf "%c" "."
sleep 1 sleep 1
done done
while ! kubectl get --namespace ${NATS_NAMESPACE} pod/${NATS_NAMESPACE}-1 &> /dev/null; do
printf "%c" "."
sleep 1
done
while ! kubectl get --namespace ${NATS_NAMESPACE} pod/${NATS_NAMESPACE}-2 &> /dev/null; do
printf "%c" "."
sleep 1
done
kubectl wait --namespace ${NATS_NAMESPACE} --for=condition=Ready --timeout=300s pod/${NATS_NAMESPACE}-0 kubectl wait --namespace ${NATS_NAMESPACE} --for=condition=Ready --timeout=300s pod/${NATS_NAMESPACE}-0
kubectl wait --namespace ${NATS_NAMESPACE} --for=condition=Ready --timeout=300s pod/${NATS_NAMESPACE}-1
kubectl wait --namespace ${NATS_NAMESPACE} --for=condition=Ready --timeout=300s pod/${NATS_NAMESPACE}-2
fi fi
echo echo
...@@ -110,7 +207,7 @@ function nats_deploy_single() { ...@@ -110,7 +207,7 @@ function nats_deploy_single() {
echo echo
} }
function nats_undeploy_single() { function nats_undeploy() {
echo "NATS" echo "NATS"
echo ">>> Checking if NATS is deployed..." echo ">>> Checking if NATS is deployed..."
if kubectl get --namespace ${NATS_NAMESPACE} statefulset/${NATS_NAMESPACE} &> /dev/null; then if kubectl get --namespace ${NATS_NAMESPACE} statefulset/${NATS_NAMESPACE} &> /dev/null; then
...@@ -127,8 +224,14 @@ function nats_undeploy_single() { ...@@ -127,8 +224,14 @@ function nats_undeploy_single() {
echo echo
} }
if [ "$NATS_REDEPLOY" == "YES" ]; then if [ "$NATS_REDEPLOY" == "YES" ] || [ "$REDEPLOYALL" == "YES" ]; then
nats_undeploy_single nats_undeploy
fi fi
nats_deploy_single if [ "$NATS_DEPLOY_MODE" == "single" ]; then
nats_deploy_single
elif [ "$NATS_DEPLOY_MODE" == "cluster" ]; then
nats_deploy_cluster
else
echo "Unsupported value: NATS_DEPLOY_MODE=$NATS_DEPLOY_MODE"
fi
\ No newline at end of file
...@@ -18,6 +18,10 @@ ...@@ -18,6 +18,10 @@
# Read deployment settings # Read deployment settings
######################################################################################################################## ########################################################################################################################
# ----- Redeploy All ------------------------------------------------------------
# If not already set, enables all components redeployment
export REDEPLOYALL=${REDEPLOYALL:-""}
# If not already set, set the namespace where QuestDB will be deployed. # If not already set, set the namespace where QuestDB will be deployed.
export QDB_NAMESPACE=${QDB_NAMESPACE:-"qdb"} export QDB_NAMESPACE=${QDB_NAMESPACE:-"qdb"}
...@@ -177,7 +181,7 @@ function qdb_drop_tables() { ...@@ -177,7 +181,7 @@ function qdb_drop_tables() {
echo echo
} }
if [ "$QDB_REDEPLOY" == "YES" ]; then if [ "$QDB_REDEPLOY" == "YES" ] || [ "$REDEPLOYALL" == "YES" ]; then
qdb_undeploy qdb_undeploy
fi fi
......
...@@ -33,14 +33,16 @@ spec: ...@@ -33,14 +33,16 @@ spec:
resources: resources:
requests: requests:
# This is intentionally low to make it work on local k3d clusters. # This is intentionally low to make it work on local k3d clusters.
cpu: 4 # TESTING
memory: 4Gi cpu: 1 #4
memory: 500Mi #4Gi
limits: limits:
cpu: 8 # TESTING
memory: 8Gi cpu: 1 #8
memory: 1Gi #8Gi
tlsEnabled: true tlsEnabled: true
# You can set either a version of the db or a specific image name # You can set either a version of the db or a specific image name
# cockroachDBVersion: v22.2.8 # cockroachDBVersion: v22.2.8
image: image:
name: cockroachdb/cockroach:v22.2.8 name: cockroachdb/cockroach:v22.2.8
# nodes refers to the number of crdb pods that are created # nodes refers to the number of crdb pods that are created
...@@ -49,21 +51,17 @@ spec: ...@@ -49,21 +51,17 @@ spec:
additionalLabels: additionalLabels:
crdb: is-cool crdb: is-cool
# affinity is a new API field that is behind a feature gate that is # affinity is a new API field that is behind a feature gate that is
# disabled by default. To enable please see the operator.yaml file. # disabled by default. To enable please see the operator.yaml file.
# The affinity field will accept any podSpec affinity rule. # The affinity field will accept any podSpec affinity rule.
# affinity: # TESTING: Force one pod per node, if possible
# podAntiAffinity: topologySpreadConstraints:
# preferredDuringSchedulingIgnoredDuringExecution: - maxSkew: 1
# - weight: 100 topologyKey: kubernetes.io/hostname
# podAffinityTerm: whenUnsatisfiable: ScheduleAnyway
# labelSelector: labelSelector:
# matchExpressions: matchLabels:
# - key: app.kubernetes.io/instance app.kubernetes.io/instance: cockroachdb
# operator: In
# values:
# - cockroachdb
# topologyKey: kubernetes.io/hostname
# nodeSelectors used to match against # nodeSelectors used to match against
# nodeSelector: # nodeSelector:
......
...@@ -381,6 +381,8 @@ spec: ...@@ -381,6 +381,8 @@ spec:
spec: spec:
containers: containers:
- args: - args:
# TESTING
- -feature-gates=TolerationRules=true,AffinityRules=true,TopologySpreadRules=true
- -zap-log-level - -zap-log-level
- info - info
env: env:
......
container:
image:
tags: 2.9-alpine
env:
# different from k8s units, suffix must be B, KiB, MiB, GiB, or TiB
# should be ~90% of memory limit
GOMEMLIMIT: 400MiB
merge:
# recommended limit is at least 2 CPU cores and 8Gi Memory for production JetStream clusters
resources:
requests:
cpu: 1 # 2
memory: 500Mi # 4Gi
limits:
cpu: 1 # 4
memory: 1Gi # 8Gi
config:
cluster:
enabled: true
replicas: 3
jetstream:
enabled: true
fileStore:
pvc:
size: 4Gi
# Force one pod per node, if possible
podTemplate:
topologySpreadConstraints:
kubernetes.io/hostname:
maxSkew: 1
whenUnsatisfiable: ScheduleAnyway
\ No newline at end of file
...@@ -18,8 +18,8 @@ metadata: ...@@ -18,8 +18,8 @@ metadata:
name: tfs-ingress name: tfs-ingress
annotations: annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2 nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/limit-rps: '2' nginx.ingress.kubernetes.io/limit-rps: '5'
nginx.ingress.kubernetes.io/limit-connections: '5' nginx.ingress.kubernetes.io/limit-connections: '10'
nginx.ingress.kubernetes.io/proxy-connect-timeout: '10' nginx.ingress.kubernetes.io/proxy-connect-timeout: '10'
nginx.ingress.kubernetes.io/proxy-send-timeout: '10' nginx.ingress.kubernetes.io/proxy-send-timeout: '10'
nginx.ingress.kubernetes.io/proxy-read-timeout: '10' nginx.ingress.kubernetes.io/proxy-read-timeout: '10'
......
...@@ -13,6 +13,11 @@ ...@@ -13,6 +13,11 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
# ----- Redeploy All ------------------------------------------------------------
# If not already set, enables all components redeployment
export REDEPLOYALL=""
# ----- TeraFlowSDN ------------------------------------------------------------ # ----- TeraFlowSDN ------------------------------------------------------------
...@@ -96,7 +101,7 @@ export CRDB_DATABASE="tfs" ...@@ -96,7 +101,7 @@ export CRDB_DATABASE="tfs"
# Set CockroachDB installation mode to 'single'. This option is convenient for development and testing. # Set CockroachDB installation mode to 'single'. This option is convenient for development and testing.
# See ./deploy/all.sh or ./deploy/crdb.sh for additional details # See ./deploy/all.sh or ./deploy/crdb.sh for additional details
export CRDB_DEPLOY_MODE="single" export CRDB_DEPLOY_MODE="cluster"
# Disable flag for dropping database, if it exists. # Disable flag for dropping database, if it exists.
export CRDB_DROP_DATABASE_IF_EXISTS="" export CRDB_DROP_DATABASE_IF_EXISTS=""
...@@ -116,6 +121,11 @@ export NATS_EXT_PORT_CLIENT="4222" ...@@ -116,6 +121,11 @@ export NATS_EXT_PORT_CLIENT="4222"
# Set the external port NATS HTTP Mgmt GUI interface will be exposed to. # Set the external port NATS HTTP Mgmt GUI interface will be exposed to.
export NATS_EXT_PORT_HTTP="8222" export NATS_EXT_PORT_HTTP="8222"
# TESTING
# Set NATS installation mode to 'single'. This option is convenient for development and testing.
# See ./deploy/all.sh or ./deploy/nats.sh for additional details
export NATS_DEPLOY_MODE="single"
# Disable flag for re-deploying NATS from scratch. # Disable flag for re-deploying NATS from scratch.
export NATS_REDEPLOY="" export NATS_REDEPLOY=""
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment