-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdeploy-virtual-machines.sh
executable file
·184 lines (156 loc) · 5.46 KB
/
deploy-virtual-machines.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
#!/usr/bin/env bash
# When VMs are deleted, IPs remain allocated in dhcpdb
# IP reclaim: https://discourse.ubuntu.com/t/is-it-possible-to-either-specify-an-ip-address-on-launch-or-reset-the-next-ip-address-to-be-used/30316
ARG=$1
set -euo pipefail
# Set the build mode
# "BRIDGE" - Places VMs on your local network so cluster can be accessed from browser.
# You must have enough spare IPs on your network for the cluster nodes.
# "NAT" - Places VMs in a private virtual network. Cluster cannot be accessed
# without setting up a port forwarding rule for every NodePort exposed.
# Use this mode if for some reason BRIDGE doesn't work for you.
BUILD_MODE="BRIDGE"
RED="\033[1;31m"
YELLOW="\033[1;33m"
GREEN="\033[1;32m"
BLUE="\033[1;34m"
NC="\033[0m"
if ! command -v jq > /dev/null
then
echo -e "${RED}'jq' not found. Please install it${NC}"
echo "https://github.com/stedolan/jq/wiki/Installation#macos"
exit 1
fi
if ! command -v multipass > /dev/null
then
echo -e "${RED}'multipass' not found. Please install it${NC}"
echo "https://multipass.run/install"
exit 1
fi
NUM_WORKER_NODES=2
MEM_GB=$(( $(sysctl hw.memsize | cut -d ' ' -f 2) / 1073741824 ))
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )/scripts
VM_MEM_GB=3G
if [ $MEM_GB -lt 8 ]
then
echo -e "${RED}System RAM is ${MEM_GB}GB. This is insufficient to deploy a working cluster.${NC}"
exit 1
fi
if [ $MEM_GB -lt 16 ]
then
echo -e "${YELLOW}System RAM is ${MEM_GB}GB. Deploying only one worker node.${NC}"
NUM_WORKER_NODES=1
VM_MEM_GB=2G
sleep 1
fi
workers=$(for n in $(seq 1 $NUM_WORKER_NODES) ; do echo -n "node0$n " ; done)
# Determine interface for bridge
interface=""
bridge_arg="--bridged"
for iface in $(multipass networks --format json | jq -r '.list[] | .name')
do
if netstat -rn -f inet | grep "^default.*${iface}" > /dev/null
then
interface=$iface
break
fi
done
if [ "$(multipass get local.bridged-network)" = "<empty>" ]
then
echo -e "${BLUE}Configuring bridge network...${NC}"
if [ -z "${interface}" ]
then
echo -e "${YELLOW}No suitable interface detected to use as bridge"
echo "Falling back to NAT installation"
echo -e "You will not be able to use your browser to connect to NodePort services.${NC}"
BUILD_MODE="NAT"
bridge_arg=""
else
# Set the bridge
echo -e "${GREEN}Configuring bridge to interface '$(multipass networks | grep ${interface})'${NC}"
multipass set local.bridged-network=${interface}
fi
fi
# If the nodes are running, reset them
if multipass list --format json | jq -r '.list[].name' | egrep '(controlplane|node01|node02)' > /dev/null
then
echo -n -e $RED
read -p "VMs are running. Delete and rebuild them (y/n)? " ans
echo -n -e $NC
[ "$ans" != 'y' ] && exit 1
fi
# Boot the nodes
for node in controlplane $workers
do
if multipass list --format json | jq -r '.list[].name' | grep "$node"
then
echo -e "${YELLOW}Deleting $node${NC}"
multipass delete $node
multipass purge
fi
echo -e "${BLUE}Launching ${node}${NC}"
if ! multipass launch $bridge_arg --disk 5G --memory $VM_MEM_GB --cpus 2 --name $node jammy 2>/dev/null
then
# Did it actually launch?
sleep 1
if [ "$(multipass list --format json | jq -r --arg no $node '.list[] | select (.name == $no) | .state')" != "Running" ]
then
echo -e "${RED}$node failed to start!${NC}"
exit 1
fi
fi
echo -e "${GREEN}$node booted!${NC}"
done
# Create hostfile entries
echo -e "${BLUE}Setting hostnames${NC}"
hostentries=/tmp/hostentries
set -x
network=$(netstat -rn -f inet | grep "^default.*${interface}" | awk '{print $2}' | awk 'BEGIN { FS="." } { printf "%s.%s.%s", $1, $2, $3 }')
[ -f $hostentries ] && rm -f $hostentries
for node in controlplane $workers
do
if [ "$BUILD_MODE" = "BRIDGE" ]
then
ip=$(multipass info $node --format json | jq -r --arg nw $network 'first( .info[] )| .ipv4 | .[] | select(startswith($nw))')
else
ip=$(multipass info $node --format json | jq -r 'first( .info[] | .ipv4[0] )')
fi
echo "$ip $node" >> $hostentries
done
for node in controlplane $workers
do
multipass transfer $hostentries $node:/tmp/
multipass transfer $SCRIPT_DIR/01-setup-hosts.sh $node:/tmp/
multipass exec $node -- /tmp/01-setup-hosts.sh $BUILD_MODE $network
done
echo -e "${GREEN}Done!${NC}"
if [ "$ARG" = "-auto" ]
then
# Set up hosts
echo -e "${BLUE}Setting up common components${NC}"
join_command=/tmp/join-command.sh
for node in controlplane $workers
do
echo -e "${BLUE}- ${node}${NC}"
multipass transfer $hostentries $node:/tmp/
multipass transfer $SCRIPT_DIR/*.sh $node:/tmp/
for script in 02-setup-kernel.sh 03-setup-cri.sh 04-kube-components.sh
do
multipass exec $node -- /tmp/$script
done
done
echo -e "${GREEN}Done!${NC}"
# Configure control plane
echo -e "${BLUE}Setting up control plane${NC}"
multipass exec controlplane /tmp/05-deploy-controlplane.sh
multipass transfer controlplane:/tmp/join-command.sh $join_command
echo -e "${GREEN}Done!${NC}"
# Configure workers
for n in $workers
do
echo -e "${BLUE}Setting up ${n}${NC}"
multipass transfer $join_command $n:/tmp
multipass exec $n -- sudo $join_command
echo -e "${GREEN}Done!${NC}"
done
fi