-
Notifications
You must be signed in to change notification settings - Fork 13
/
setup_worker_node.sh
326 lines (261 loc) · 11.6 KB
/
setup_worker_node.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
#!/bin/bash
# Define Variables, Default Values & Parameters
# --------------------------------------------------------------------------------------------------------------------------------------------------------
# ------------------------------
# Host TCP/IP Settings
# ------------------------------
# These options configure the TCP/IP settings of this server. These options have been added for your convenience however, you may not want to
# do this if your settings are already configured. You will still need to specify this machines IP address though as it will be required by
# other parts of the script.
#
# WARNING: If this is enabled and the IP address will be changed, make sure you are not running this script from a remote shell.
#
export configureTCPIPSetting=false
export interface="eth0" # Find with 'ip addr'
export ipAddress=""
export netmask=""
export defaultGateway=""
export dnsServers=("8.8.8.8" "4.4.4.4") # Don't specify more than 3. K8s will only use the first three and throw errors.
export dnsSearch=("domain.local") # Your local DNS search domain if you have one.
# ------------------------------
# Kubernetes
# ------------------------------
#
export k8sVersion="latest"
export k8sMasterIP=""
export k8sMasterPort="6443"
export k8sToken="" # This and the cert hash can be found by running 'kubeadm token create --print-join-command'
export k8sTokenDiscoveryCaCertHash="" # on the master node
# ------------------------------
# Parameters
# ------------------------------
#
while [[ $# -gt 0 ]]; do
key="$1"
case $key in
--configure-tcpip) configureTCPIPSetting="$2"; shift; shift;;
--interface) interface="$2"; shift; shift;;
--ip-address) ipAddress="$2"; shift; shift;;
--netmask) netmask="$2"; shift; shift;;
--default-gateway) defaultGateway="$2"; shift; shift;;
--dns-servers) dnsServers=($2); shift; shift;;
--dns-search) dnsSearch=($2); shift; shift;;
--k8s-version) k8sVersion="$2"; shift; shift;;
--k8s-master-ip) k8sMasterIP="$2"; shift; shift;;
--k8s-master-port) k8sMasterPort="$2"; shift; shift;;
--token) k8sToken="$2"; shift; shift;;
--discovery-token-ca-cert-hash) k8sTokenDiscoveryCaCertHash="$2"; shift; shift;;
*) echo -e "\e[31mError:\e[0m Parameter \e[35m$key\e[0m is not recognised."; exit 1;;
esac
done
echo -e '\e[35m _ _ \e[36m _ ___ \e[0m'
echo -e '\e[35m / \ _ _| |_ ___ \e[36m| | _( _ ) ___ \e[0m'
echo -e '\e[35m / _ \| | | | __/ _ \ \e[36m| |/ / _ \/ __| \e[0m'
echo -e '\e[35m / ___ \ |_| | || (_) |\e[36m| < (_) \__ \ \e[0m'
echo -e '\e[35m /_/ \_\__,_|\__\___/ \e[36m|_|\_\___/|___/ \e[0m\n'
echo -e '\e[35m Kubernetes Installation Script:\e[36m Worker Node Edition\e[0m\n'
# Perform Validation
# --------------------------------------------------------------------------------------------------------------------------------------------------------
export HARDWARE_CHECK_PASS=true
export MIN_CPUS=2
export CPU_COUNT=$(grep -c "^processor" /proc/cpuinfo)
if [ $CPU_COUNT -lt $MIN_CPUS ]; then
echo -e "\e[31mError:\e[0m The system must have at least \e[35m$MIN_CPUS\e[0m CPU's to run Kubernetes. You currently have \e[35m${CPU_COUNT}\e[0m."
HARDWARE_CHECK_PASS=false
else
echo -e "\e[32mInfo:\e[0m The system has \e[35m$CPU_COUNT\e[0m CPU's."
fi
export MIN_RAM=1700
export RAM_TOTAL=$(awk '/^MemTotal:/{print $2}' /proc/meminfo)
export RAM_MB=$((RAM_TOTAL / 1024))
if [ $RAM_MB -lt $MIN_RAM ]; then
echo -e "\e[31mError:\e[0m The system must have at least \e[35m${MIN_RAM} MB\e[0m of memory to run Kubernetes. You currently have \e[35m${RAM_MB} MB\e[0m."
HARDWARE_CHECK_PASS=false
else
echo -e "\e[32mInfo:\e[0m The system has \e[35m${RAM_MB} MB\e[0m of memory."
fi
if [ $HARDWARE_CHECK_PASS == false ]; then
exit 1
fi
export PARAM_CHECK_PASS=true
if [[ ! "$configureTCPIPSetting" =~ ^(true|false)$ ]]; then
echo -e "\e[31mError:\e[0m \e[35m--configure-tcpip\e[0m must be set to either \e[35mtrue\e[0m or \e[35mfalse\e[0m."
PARAM_CHECK_PASS=false
fi
if [[ "$configureTCPIPSetting" == true ]]; then
if [[ -z "$interface" ]]; then
echo -e "\e[31mError:\e[0m \e[35m--interface\e[0m is required when \e[35m--configure-tcpip\e[0m is set to \e[35mtrue\e[0m."
PARAM_CHECK_PASS=false
fi
if [[ -z "$ipAddress" ]]; then
echo -e "\e[31mError:\e[0m \e[35m--ip-address\e[0m is required when \e[35m--configure-tcpip\e[0m is set to \e[35mtrue\e[0m."
PARAM_CHECK_PASS=false
elif [[ ! $ipAddress =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
echo -e "\e[31mError:\e[0m \e[35m--ip-address\e[0m value \e[35m$ipAddress\e[0m is not a valid IP address."
PARAM_CHECK_PASS=false
fi
if [[ -z "$netmask" ]]; then
echo -e "\e[31mError:\e[0m \e[35m--netmask\e[0m is required when \e[35m--configure-tcpip\e[0m is set to \e[35mtrue\e[0m."
PARAM_CHECK_PASS=false
elif [[ ! "$netmask" =~ ^(255|254|252|248|240|224|192|128|0)\.((255|254|252|248|240|224|192|128|0)\.){2}(255|254|252|248|240|224|192|128|0)$ ]]; then
echo -e "\e[31mError:\e[0m \e[35m--netmask\e[0m value \e[35m$netmask\e[0m is not a valid network mask."
PARAM_CHECK_PASS=false
fi
if [[ -z "$defaultGateway" ]]; then
echo -e "\e[31mError:\e[0m \e[35m--default-gateway\e[0m is required when \e[35m--configure-tcpip\e[0m is set to \e[35mtrue\e[0m."
PARAM_CHECK_PASS=false
elif [[ ! $defaultGateway =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
echo -e "\e[31mError:\e[0m \e[35m--default-gateway\e[0m value \e[35m$defaultGateway\e[0m is not a valid IP address."
PARAM_CHECK_PASS=false
fi
if [[ "${#dnsServers[@]}" -gt 3 ]]; then
echo -e "\e[33mWarning:\e[0m Number of DNS servers should not be greater than 3. Kubernetes may display errors but will continue to work."
fi
for ip in "${dnsServers[@]}"; do
if [[ ! $ip =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
echo -e "\e[31mError:\e[0m DNS server \e[35m$ip\e[0m is not a valid IP address."
PARAM_CHECK_PASS=false
fi
done
fi
if [[ -z "$k8sMasterIP" ]]; then
echo -e "\e[31mError:\e[0m \e[35m--k8s-master-ip\e[0m is required."
PARAM_CHECK_PASS=false
elif [[ ! $k8sMasterIP =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
echo -e "\e[31mError:\e[0m \e[35m--k8s-master-ip\e[0m value \e[35m$k8sMasterIP\e[0m is not a valid IP address."
PARAM_CHECK_PASS=false
fi
if [[ -z "$k8sMasterIP" ]]; then
echo -e "\e[31mError:\e[0m \e[35m--k8s-master-ip\e[0m is required."
PARAM_CHECK_PASS=false
fi
if [[ -z "$k8sMasterPort" ]]; then
echo -e "\e[31mError:\e[0m \e[35m--k8s-master-port\e[0m is required."
PARAM_CHECK_PASS=false
fi
if [[ -z "$k8sToken" ]]; then
echo -e "\e[31mError:\e[0m \e[35m--token\e[0m is required."
PARAM_CHECK_PASS=false
fi
if [[ -z "$k8sTokenDiscoveryCaCertHash" ]]; then
echo -e "\e[31mError:\e[0m \e[35m--discovery-token-ca-cert-hash\e[0m is required."
PARAM_CHECK_PASS=false
fi
if [ $PARAM_CHECK_PASS == false ]; then
exit 1
fi
# Install Kubernetes
# --------------------------------------------------------------------------------------------------------------------------------------------------------
# Check sudo & keep sudo running
echo -e "\033[32mChecking root access\033[0m"
if [ "$(id -u)" -ne 0 ]
then
echo -e "\033[31mYou must run this script as root\033[0m"
exit
fi
sudo -v
while true; do
sudo -nv; sleep 1m
kill -0 $$ 2>/dev/null || exit
done &
# Prevent interactive needsrestart command
export NEEDSRESART_CONF="/etc/needrestart/needrestart.conf"
if [ -f $NEEDSRESART_CONF ]; then
echo -e "\033[32mDisabling needsrestart interactive mode\033[0m"
sed -i "/#\$nrconf{restart} = 'i';/s/.*/\$nrconf{restart} = 'a';/" $NEEDSRESART_CONF
fi
# Configure IP Settings
if [ $configureTCPIPSetting == true ]; then
echo -e "\033[32mConfiguring Network Settings\033[0m"
IFS=. read -r i1 i2 i3 i4 <<< "$ipAddress"
IFS=. read -r m1 m2 m3 m4 <<< "$netmask"
cidr=$(echo "obase=2; $(( (m1 << 24) + (m2 << 16) + (m3 << 8) + m4 ))" | bc | tr -d '\n' | sed 's/0*$//' | wc -c)
cat <<EOF | tee /etc/netplan/01-netcfg.yaml > /dev/null
network:
version: 2
ethernets:
$interface:
dhcp4: false
dhcp6: false
addresses: [$ipAddress/$cidr]
routes:
- to: default
via: $defaultGateway
nameservers:
search: [$(echo "${dnsSearch[@]}" | tr ' ' ',')]
addresses: [$(echo "${dnsServers[@]}" | tr ' ' ',')]
EOF
netplan apply
fi
# Install Prerequsites
echo -e "\033[32mInstalling prerequisites\033[0m"
apt-get update -q
apt-get install -qqy apt-transport-https ca-certificates curl software-properties-common gzip gnupg lsb-release
# Add Docker Repository https://docs.docker.com/engine/install/ubuntu/
export KEYRINGS_DIR="/etc/apt/keyrings"
if [ ! -d $KEYRINGS_DIR ]; then
mkdir -m 0755 -p $KEYRINGS_DIR
fi
if [ ! -f /etc/apt/sources.list.d/docker.list ]; then
echo -e "\033[32mAdding Docker repository\033[0m"
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o $KEYRINGS_DIR/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=$KEYRINGS_DIR/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
fi
# Add Kubernetes Respository
if [ ! -f /etc/apt/sources.list.d/kubernetes.list ]; then
echo -e "\033[32mAdding Google Kubernetes repository\033[0m"
curl -fsSLo $KEYRINGS_DIR/kubernetes-archive-keyring.gpg https://dl.k8s.io/apt/doc/apt-key.gpg
echo "deb [signed-by=$KEYRINGS_DIR/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | tee /etc/apt/sources.list.d/kubernetes.list
fi
apt-get update -q
# Install Docker https://docs.docker.com/engine/install/ubuntu/
echo -e "\033[32mInstalling Docker\033[0m"
apt-get install -qqy docker-ce docker-ce-cli containerd.io
tee /etc/docker/daemon.json >/dev/null <<EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
mkdir -p /etc/systemd/system/docker.service.d
# Replace default config file to enable CRI plugin and SystemdCgroup
# https://kubernetes.io/docs/setup/production-environment/container-runtimes/#containerd-systemd
tee /etc/containerd/config.toml >/dev/null <<EOF
version = 2
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
runtime_type = "io.containerd.runc.v2"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
EOF
systemctl daemon-reload
systemctl restart docker
systemctl restart containerd
# Disabling Swap
echo -e "\033[32mDisabling Swapping\033[0m"
if grep -v '^#' /etc/fstab | grep -q swap; then
export BACKUP_FSTAB="/etc/fstab.backup.$(date +%s)"
cp /etc/fstab $BACKUP_FSTAB
sed -i '/swap/ s/^/#/' /etc/fstab
swapoff -a
echo "The file /etc/fstab has been backed-up to $BACKUP_FSTAB"
echo "Swap is now disabled"
else
echo "Swap is already disabled"
fi
# Install Kubernetes https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
echo -e "\033[32mInstalling Kubernetes\033[0m"
if [ $k8sVersion == "latest" ]; then
apt-get install -qqy kubelet kubeadm kubectl
else
apt-get install -qqy kubelet=$k8sVersion kubeadm=$k8sVersion kubectl=$k8sVersion
fi
# Join Cluster
echo -e "\033[32mJoining Kubernetes Cluster\033[0m"
kubeadm join $k8sMasterIP:$k8sMasterPort --token $k8sToken --discovery-token-ca-cert-hash $k8sTokenDiscoveryCaCertHash
# Print success message and tips
echo -e "\033[32m\nInstallation Complete!\n\033[0m"