forked from cr1st1p/k8s-on-lxd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
k8s-on-lxd.sh
executable file
·403 lines (342 loc) · 10.6 KB
/
k8s-on-lxd.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
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
#! /bin/bash
set -e # bail out on errors
#set -x # debug. Or just --debug
# Author: Cristian Posoiu cristi@posoiu.net
#
PROG="${BASH_SOURCE[0]}"
[ ! -h "$PROG" ] || PROG=$(readlink -f "$PROG")
SCRIPT_PATH="$( cd "$( dirname "$PROG" )" && pwd )"
export SCRIPT_PATH
SCRIPT_NAME="$( basename "$PROG")"
export SCRIPT_NAME
DEBUG=
addon=""
CLUSTER_NAME=""
#shellcheck disable=2034
LXD_PROFILE_NAME=k8s
#shellcheck disable=2034
IMAGE_NAME_BASE=k8s
#shellcheck disable=2034
VERSION=0.5
K8S_VERSION_DEFAULT="1.18.2"
K8S_VERSION="$K8S_VERSION_DEFAULT"
if [[ "$K8S_VERSION" == "1.13"* ]]; then
DOCKER_VERSION=18.06
elif [[ "$K8S_VERSION" == "1.18"* ]]; then
#shellcheck disable=2034
DOCKER_VERSION="5:19.03"
else
#shellcheck disable=2034
DOCKER_VERSION=18.09
fi
# TODO: move this out
# 1 to expose kube-controller-manager and kube-scheduler (i.e. make it listen
# on all interfaces instead of 127.0.0.1).
# Scope: allow to run kube-prometheus
#shellcheck disable=2034
EXPORT_KUBECONTROLLER=${K8S_EXPOSE_KUBECONTROLLER:-1}
# TODO: move this out
# change authorization mode of kubelet.
# Scope: allow to run kube-prometheus
#shellcheck disable=2034
KUBELET_AUTH_CHANGE=${K8S_AUTH_CHANGE:-1}
#shellcheck disable=SC1090
for f in "$SCRIPT_PATH"/lib/*.sh; do
source "$f"
done
# load addons
addons=()
addonsDir="$SCRIPT_PATH/addons"
for d in "$addonsDir"/* ; do
[ -d "$d" ] || continue
addons+=("$(basename "$d")")
#shellcheck disable=1090
source "$d/main.sh"
done
prepareLxd() {
if ! lxdRemoteIsLocal ; then
bail "You need to run the preparation on the actual host with LXD"
fi
runFunctions '^setup_host__'
runFunctions '^setup_lxd__'
lxdCreateProfile
prepareLxdImages
}
stopAll() {
prefix=$1
declare -a list
mapfile -t list < <(lxcListByPrefixRunning "$prefix")
if [ "${#list[@]}" -eq 0 ]; then
info "No containers to stop"
else
info "Will stop containers" "${list[@]}"
for n in "${list[@]}"; do
lxc stop "$LXD_REMOTE$n"
done
fi
}
runAll() {
prefix=$1
mapfile -t list < <(lxcListByPrefixStopped "$prefix")
if [ "${#list[@]}" -eq 0 ]; then
info "No containers to run"
else
info "Will start containers " "${list[@]}"
local masterContainer="$prefix-master"
for container in "${list[@]}"; do
runFunctions '^before_node_starts__' "$masterContainer" "$container"
lxc start "$LXD_REMOTE$container"
done
fi
}
deleteAll() {
prefix=$1
mapfile -t list < <(lxcListByPrefixRunning "$prefix")
if [ "${#list[@]}" -ne 0 ]; then
info "You have to stop first the containers. Use -S $prefix "
else
mapfile -t list < <(lxcListByPrefixAll "$prefix")
if [ "${#list[@]}" -eq 0 ]; then
info "No containers to delete"
else
info "Will delete containers" "${list[@]}"
for n in "${list[@]}" ; do
lxc delete "$LXD_REMOTE$n"
done
fi
fi
}
usage() {
local BOLD_START=""
local COLOR_END=""
if terminalSupportsColors; then
BOLD_START=$(tput smso; tput rev)
COLOR_END=$(tput sgr0)
fi
cat <<EOS
${BOLD_START}$SCRIPT_NAME${COLOR_END}: Running lightweight ${BOLD_START}multiple${COLOR_END} Kubernetes clusters, ${BOLD_START}multi${COLOR_END}-node, multiple ${BOLD_START}versions${COLOR_END}... on a single machine.
For local development purposes.
Usage: $SCRIPT_NAME options...
-n,--name= NAME : sets the name prefix to use for nodes. Nodes will be named
NAME-master, NAME-worker-1, NAME-worker-2, etc
--remote remoteName. Default 'local'
--k8s-version VERSION : which kubernetes version to use. Default is $K8S_VERSION_DEFAULT
Usable during setup phase, and when launching a master node.
--no-colour,--no-color : disable use of colors/bold text/emoticons
-s,--setup: to prepare lxd setup + an lxd image
-m, --master : to create and start a master node, named NAME-master
-w, --worker : to create and start a new worker node, named NAME-worker-N,
where N is a number NOT used yet
--allow-master-scheduling - set master so that pods can be scheduled on it as well. It removes a node tain.
-c,--set-config : to update your local kubectl config to access the LXD k8s
cluster. This is done also during creation of the master node.
-S,--stop : stop all the containers in the named cluster (master and workers)
-R,--run : start all the containers for the named cluster (master and workers)
-D,--delete : deletes all the containers for the named cluster (master and workers) - first stop them!
Others:
--no-check-lost-found: during setup phase, do not check for presence of lost+found directory
${BOLD_START}Addons${COLOR_END}:
--addon ADDON_NAME : always needed
--addon-info : it will display some information from the addon (if provided by the addon)
--addon-list : list the addons
--addon-run COMMAND : it will run specified command from the addon
Some addons could be more like plugins - i.e. they don't provide commands to run but they plug into the steps run
for various phases (setting up the LXD base images for example)
EOS
}
checkArg () {
if [ -z "$2" ] || [[ "$2" == "-"* ]]; then
bail "Expected argument for option: $1. None received"
fi
}
checkAddonArgument() {
[ -n "$addon" ] || bail "Need to tell me the name of the addon via --addon NAME"
}
beforeCommand() {
terminalSupportsColors
ensureClusterNameIsSet
host_check_minimum_requirements
}
declare -i processedArgumentsCount=0
processMainArguments() {
processedArgumentsCount=0
case "$1" in
-h|-u|--help|--usage)
usage
exit 0
;;
--debug)
#shellcheck disable=2034
DEBUG=1
set -x
processedArgumentsCount=1
return 0
;;
--no-color|--no-colors|--no-colour|--no-colours)
export __TERMINAL_SUPPORTS_COLORS=0
processedArgumentsCount=1
return 0
;;
# -v|--verbose)
# export VERBOSE="true"
# shift
# ;;
-s|--setup)
terminalSupportsColors
host_check_minimum_requirements
prepareLxd
exit 0
;;
--setup-inside-lxd-image) # internal command
terminalSupportsColors
runFunctions "^insideLxdImage__"
exit 0
;;
--setup-inside-lxd-image-worker) # internal command
terminalSupportsColors
runFunctions "^insideLxdImage_worker__"
exit 0
;;
--setup-inside-lxd-image-master) # internal command
terminalSupportsColors
runFunctions "^insideLxdImage_master__"
exit 0
;;
-n|--name)
checkArg "$1" "$2"
CLUSTER_NAME="$2"
processedArgumentsCount=2
return 0
;;
--remote)
checkArg "$1" "$2"
export LXD_REMOTE="${2//:/}:"
processedArgumentsCount=2
return 0
;;
-m|--master)
beforeCommand
launchMaster "$CLUSTER_NAME"
exit 0
;;
--allow-master-scheduling)
beforeCommand
runKubectl taint node "${CLUSTER_NAME}-master" node-role.kubernetes.io/master:NoSchedule-
exit 0
;;
--k8s-version|--kubernetes-version)
checkArg "$1" "$2"
export K8S_VERSION="$2"
processedArgumentsCount=2
return 0
;;
-w|--worker)
beforeCommand
launchWorker "$CLUSTER_NAME"
exit 0
;;
-c|--set-config)
beforeCommand
addUserKubectlConfig "$CLUSTER_NAME"
exit 0
;;
-S|--stop)
beforeCommand
stopAll "$CLUSTER_NAME"
exit 0
;;
-R|--run)
beforeCommand
runAll "$CLUSTER_NAME"
exit 0
;;
-D|--delete)
beforeCommand
deleteAll "$CLUSTER_NAME"
exit 0
;;
-t|--test)
# for whatever adhoc test I need
#kubeletChangeAuthMode site2-worker-1
lxdMessageAboutRouting
exit 0
;;
--no-check-lost-found)
#shellcheck disable=2034
no_check_lost_found="1"
processedArgumentsCount=1
return 0
;;
--addon-list)
echo "${addons[@]}"
exit 0
;;
--addon)
checkArg "$1" "$2"
addon="$2"
if ! elementIn "$addon" "${addons[@]}"; then
bail "Unknown addon $addon. Try --addon-list to see them"
fi
processedArgumentsCount=2
return 0
;;
--addon-info)
checkAddonArgument
n="addon_${addon}_info"
n=${n//-/_}
isFunction "$n" || bail "Addon does not expose information function"
$n
exit 0
;;
--addon-run)
checkArg "$1" "$2"
checkAddonArgument
n="addon_${addon}_$2"
n=${n//-/_}
isFunction "$n" || bail "Addon does not expose that functionality"
terminalSupportsColors
$n
exit 0
;;
esac
processedArgumentsCount=0
}
arguments=()
while [[ $# -gt 0 ]]
do
# split --x=y to have them separated
[[ $1 == --*=* ]] && set -- "${1%%=*}" "${1#*=}" "${@:2}"
processMainArguments "$@"
if [ "$processedArgumentsCount" == 0 ]; then
# no processing so far. Let's ask selected addon to parse argument
if [ -n "$addon" ]; then
func="addon_${addon}_parse_arg"
func=${func//-/_}
if isFunction "$func"; then
"$func" "$@"
fi
fi
fi
if [ "$processedArgumentsCount" != "0" ]; then
shift "$processedArgumentsCount"
continue
fi
case "$1" in
--) # end argument parsing
shift
break
;;
--*|-*) # unsupported flags
echo "Error: Unsupported flag $1" >&2
usage
exit 1
;;
*) # preserve positional arguments
arguments+=("$1")
shift
;;
esac
done
warn "${EMOTICON_CONFUSED}Let me know what to do. See below." # FIXME: better message
printf "\n\n"
usage