-
Notifications
You must be signed in to change notification settings - Fork 0
/
local-k8s.sh
executable file
·283 lines (235 loc) · 8.91 KB
/
local-k8s.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
#!/usr/bin/env bash
set -eou pipefail
# Set the current directory in a variable
CURRENT_DIR="$(dirname "$0")"
# Import functions from utilities.sh
source "$CURRENT_DIR/utilities/helpers.sh"
REQUIREMENTS=(
"kind"
"helm"
"kubectl"
"curl"
"nohup"
"jq"
)
# NOTE: If triggering some of the scripts locally on Mac, you might find an error from the test complaining
# that the injection Docker container can't connect to localhost:8080. This is because the Docker container
# is running in a separate network and can't access the host network. To fix this, you can use the IP address
# of the host machine instead of localhost, using "host.docker.internal". For example:
# client = weaviate.connect_to_local(host="host.docker.internal")
WEAVIATE_PORT=${WEAVIATE_PORT:-8080}
WEAVIATE_GRPC_PORT=${WEAVIATE_GRPC_PORT:-50051}
WEAVIATE_METRICS=${WEAVIATE_METRICS:-2112}
MODULES=${MODULES:-""}
ENABLE_BACKUP=${ENABLE_BACKUP:-"false"}
S3_OFFLOAD=${S3_OFFLOAD:-"false"}
HELM_BRANCH=${HELM_BRANCH:-""}
VALUES_INLINE=${VALUES_INLINE:-""}
DELETE_STS=${DELETE_STS:-"false"}
REPLICAS=${REPLICAS:-1}
OBSERVABILITY=${OBSERVABILITY:-"true"}
PROMETHEUS_PORT=9091
GRAFANA_PORT=3000
TARGET=""
function get_timeout() {
# Increase timeout if MODULES is not empty as the module image might take some time to download
# and calculate the timeout value based on the number of replicas
modules_timeout=0
if [ -n "$MODULES" ]; then
modules_timeout=$((modules_timeout + 1200))
fi
if [ "$ENABLE_BACKUP" == "true" ] || [ "$S3_OFFLOAD" == "true" ]; then
modules_timeout=$((modules_timeout + 100))
fi
if [ "$OBSERVABILITY" == "true" ]; then
modules_timeout=$((modules_timeout + 100))
fi
echo "$((modules_timeout + (REPLICAS * 100)))s"
}
function upgrade() {
echo_green "upgrade # Upgrading to Weaviate ${WEAVIATE_VERSION}"
# Make sure to set the right context
kubectl config use-context kind-weaviate-k8s
# Upload images to cluster if --local-images flag is passed
if [ "${1:-}" == "--local-images" ]; then
use_local_images
# Make sure that the image.registry doesn't point to cr.weaviate.io, otherwise the local images won't be used
VALUES_INLINE="$VALUES_INLINE --set imagePullPolicy=Never --set image.registry=docker.io"
fi
if [[ $S3_OFFLOAD == "true" ]] || [[ $ENABLE_BACKUP == "true" ]]; then
# if the minio pod is not running, start it
kubectl get pod -n weaviate minio &> /dev/null || startup_minio
fi
# This function sets up weaviate-helm and sets the global env var $TARGET
setup_helm $HELM_BRANCH
if [ "$DELETE_STS" == "true" ]; then
echo_yellow "upgrade # Deleting Weaviate StatefulSet"
kubectl delete sts weaviate -n weaviate
else
echo_green "upgrade # Weaviate StatefulSet is not being deleted"
fi
HELM_VALUES=$(generate_helm_values)
VALUES_OVERRIDE=""
# Check if values-override.yaml file exists
if [ -f "${CURRENT_DIR}/values-override.yaml" ]; then
VALUES_OVERRIDE="-f ${CURRENT_DIR}/values-override.yaml"
fi
echo_green "upgrade # Upgrading weaviate-helm with values: \n\
TARGET: $TARGET \n\
HELM_VALUES: $(echo "$HELM_VALUES" | tr -s ' ') \n\
VALUES_OVERRIDE: $VALUES_OVERRIDE"
helm upgrade weaviate $TARGET \
--namespace weaviate \
$HELM_VALUES \
$VALUES_OVERRIDE
# Wait for Weaviate to be up
TIMEOUT=$(get_timeout)
echo_green "upgrade # Waiting (with timeout=$TIMEOUT) for Weaviate $REPLICAS node cluster to be ready"
kubectl wait sts/weaviate -n weaviate --for jsonpath='{.status.readyReplicas}'=${REPLICAS} --timeout=${TIMEOUT}
echo_green "upgrade # Waiting for rollout upgrade to be over"
kubectl -n weaviate rollout status statefulset weaviate
port_forward_to_weaviate $REPLICAS
wait_weaviate
wait_for_other_services
# Check if Weaviate is up
wait_for_all_healthy_nodes $REPLICAS
# Check if Raft schema is in sync
wait_for_raft_sync $REPLICAS
echo_green "upgrade # Success"
}
function setup() {
echo_green "setup # Setting up Weaviate $WEAVIATE_VERSION on local k8s"
# Create Kind config file
cat <<EOF > /tmp/kind-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: weaviate-k8s
nodes:
- role: control-plane
$([ "${WORKERS:-""}" != "" ] && for i in $(seq 1 $WORKERS); do echo "- role: worker"; done)
EOF
echo_green "setup # Create local k8s cluster"
# Create k8s Kind Cluster
kind create cluster --wait 120s --name weaviate-k8s --config /tmp/kind-config.yaml
# Upload images to cluster if --local-images flag is passed
if [ "${1:-}" == "--local-images" ]; then
use_local_images
# Make sure that the image.registry doesn't point to cr.weaviate.io, otherwise the local images won't be used
VALUES_INLINE="$VALUES_INLINE --set imagePullPolicy=Never --set image.registry=docker.io"
fi
# Create namespace
kubectl create namespace weaviate
if [[ $S3_OFFLOAD == "true" ]] || [[ $ENABLE_BACKUP == "true" ]]; then
startup_minio
fi
# This function sets up weaviate-helm and sets the global env var $TARGET
setup_helm $HELM_BRANCH
# Setup monitoring in the weaviate cluster
if [[ $OBSERVABILITY == "true" ]]; then
setup_monitoring
fi
VALUES_OVERRIDE=""
# Check if values-override.yaml file exists
if [ -f "${CURRENT_DIR}/values-override.yaml" ]; then
VALUES_OVERRIDE="-f ${CURRENT_DIR}/values-override.yaml"
fi
HELM_VALUES=$(generate_helm_values)
echo_green "setup # Deploying weaviate-helm with values: \n\
TARGET: $TARGET \n\
HELM_VALUES: $(echo "$HELM_VALUES" | tr -s ' ') \n\
VALUES_OVERRIDE: $VALUES_OVERRIDE"
# Install Weaviate using Helm
helm upgrade --install weaviate $TARGET \
--namespace weaviate \
$HELM_VALUES \
$VALUES_OVERRIDE
#--set debug=true
# Wait for Weaviate to be up
TIMEOUT=$(get_timeout)
echo_green "setup # Waiting (with timeout=$TIMEOUT) for Weaviate $REPLICAS node cluster to be ready"
kubectl wait sts/weaviate -n weaviate --for jsonpath='{.status.readyReplicas}'=${REPLICAS} --timeout=${TIMEOUT}
port_forward_to_weaviate $REPLICAS
wait_weaviate
wait_for_other_services
# Check if Weaviate is up
wait_for_all_healthy_nodes $REPLICAS
echo_green "setup # Success"
echo_green "setup # Weaviate is up and running on http://localhost:$WEAVIATE_PORT"
if [[ $OBSERVABILITY == "true" ]]; then
echo_green "setup # Grafana is accessible on http://localhost:$GRAFANA_PORT (admin/admin)"
echo_green "setup # Prometheus is accessible on http://localhost:$PROMETHEUS_PORT"
fi
}
function clean() {
echo_green "clean # Cleaning up local k8s cluster..."
# Kill kubectl port-forward processes running in the background
pkill -f "kubectl-relay" || true
# Make sure to set the right context
kubectl config use-context kind-weaviate-k8s
# Check if Weaviate release exists
if helm status weaviate -n weaviate &> /dev/null; then
# Uninstall Weaviate using Helm
helm uninstall weaviate -n weaviate
fi
if [[ $S3_OFFLOAD == "true" ]] || [[ $ENABLE_BACKUP == "true" ]]; then
shutdown_minio
fi
# Check if Weaviate namespace exists
if kubectl get namespace weaviate &> /dev/null; then
# Delete Weaviate namespace
kubectl delete namespace weaviate
fi
# Check if Kind cluster exists
if kind get clusters | grep -q "weaviate-k8s"; then
# Delete Kind cluster
kind delete cluster --name weaviate-k8s
fi
echo_green "clean # Success"
}
# Main script
# Check if any options are passed
if [ $# -eq 0 ]; then
echo "Usage: $0 <options> <flags>"
echo "options:"
echo " setup"
echo " clean"
echo " upgrade"
echo "flags:"
echo " --local-images (optional) [Upload local images to the cluster]"
exit 1
fi
# Check if all requirements are installed
for requirement in "${REQUIREMENTS[@]}"; do
if ! command -v $requirement &> /dev/null; then
echo "Please install '$requirement' before running this script"
echo " brew install $requirement"
exit 1
fi
done
# Add an optional second argument --local-images (defaults to false) which allows uploading the local images to the cluster using
# kind load docker-image <image-name> --name weaviate-k8s
LOCAL_IMAGES=""
if [ $# -ge 2 ] && [ "$2" == "--local-images" ]; then
echo "Local images enabled"
LOCAL_IMAGES="--local-images"
fi
# Process command line options
case $1 in
"setup")
setup $LOCAL_IMAGES
;;
"upgrade")
upgrade $LOCAL_IMAGES
;;
"clean")
clean
;;
*)
echo "Invalid option: $1. Use 'setup' or 'clean'"
exit 1
;;
esac
# Retrieve Weaviate logs
if [ $? -ne 0 ]; then
kubectl logs -n weaviate -l app.kubernetes.io/name=weaviate
fi