blob: f54f9e9087749cce38ef461303636d56aad2e6f3 [file] [log] [blame]
garciadeblasb3797412024-06-06 14:26:24 +02001#!/bin/bash
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14#
15
16set +eux
17
18# K3s releases: https://github.com/k3s-io/k3s/releases/
garciadeblas13b73b02025-09-24 11:48:23 +020019K8S_VERSION="v1.34.2+k3s1"
garciadeblasb3797412024-06-06 14:26:24 +020020
garciadeblas117fd4a2024-08-21 18:18:14 +020021# configure registry
22function configure_registry() {
23 if [ -n "${DOCKER_PROXY_URL}" ]; then
24 echo "Configuring docker proxy URL in /etc/rancher/k3s/registries.yaml"
garciadeblas89cee5e2024-11-18 12:58:29 +010025 sudo mkdir -p /etc/rancher/k3s/
garciadeblas117fd4a2024-08-21 18:18:14 +020026 cat << EOF | sudo tee /etc/rancher/k3s/registries.yaml > /dev/null
27mirrors:
garciadeblas918c61a2025-11-21 10:16:25 +010028 ghcr.io:
29 endpoint:
30 - "${DOCKER_PROXY_URL}"
garciadeblas117fd4a2024-08-21 18:18:14 +020031 docker.io:
32 endpoint:
33 - "${DOCKER_PROXY_URL}"
34EOF
35 fi
garciadeblas2efb98b2024-08-21 21:19:36 +020036 if [ -n "${DOCKER_REGISTRY_URL}" ]; then
37 echo "Configuring docker private registry in /etc/rancher/k3s/registries.yaml"
38 cat << EOF | sudo tee -a /etc/rancher/k3s/registries.yaml > /dev/null
39configs:
40 ${DOCKER_REGISTRY_URL}:
41 auth:
42 username: ${DOCKER_REGISTRY_USER}
43 password: ${DOCKER_REGISTRY_PASSWORD}
44EOF
45 fi
garciadeblas117fd4a2024-08-21 18:18:14 +020046}
47
garciadeblasb3797412024-06-06 14:26:24 +020048# installs k3s
49function install_k3s() {
50 [ -z "${DEBUG_INSTALL}" ] || DEBUG beginning of function
51 export INSTALL_K3S_EXEC="--disable traefik"
garciadeblase3a84a52024-09-27 11:34:55 +020052
53 # Regular installation of K3s
garciadeblasb3797412024-06-06 14:26:24 +020054 curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=${K8S_VERSION} sh -s -
garciadeblase3a84a52024-09-27 11:34:55 +020055
56 # If specified a public IP, K3s service is updated accordingly and restarted
57 if [ -n "${K3S_PUBLIC_IP}" ]; then
58 # Back-up service config file to home
59 cp /etc/systemd/system/k3s.service ~/BASE-k3s.service
60
61 # Generate new service config file with additions for using a public IP
62 (
63 cat ~/BASE-k3s.service | sed '${/^$/d}'
64 echo -e "\t'--node-external-ip' \\"
65 echo -e "\t'${K3S_PUBLIC_IP}' \\"
66 echo
67 )| \
68 tee ~/PUBLIC-k3s.service
69
70 # Replace service config and apply
71 sudo cp ~/PUBLIC-k3s.service /etc/systemd/system/k3s.service
72 sudo systemctl daemon-reload
73 sudo systemctl restart k3s
74
75 # Cleanup
76 rm ~/BASE-k3s.service ~/PUBLIC-k3s.service
77 fi
78
79 # Make kubeconfig permissions less restrictive
garciadeblasb3797412024-06-06 14:26:24 +020080 sudo chmod 644 /etc/rancher/k3s/k3s.yaml
81 [ -z "${DEBUG_INSTALL}" ] || DEBUG end of function
82}
83
84# updates service nodeport range
85function update_service_nodeport_range() {
86 [ -z "${DEBUG_INSTALL}" ] || DEBUG beginning of function
87 sudo k3s server --kube-apiserver-arg=service-node-port-range=80-32767
88 [ -z "${DEBUG_INSTALL}" ] || DEBUG end of function
89}
90
91# checks cluster readiness
92function check_for_readiness() {
93 [ -z "${DEBUG_INSTALL}" ] || DEBUG beginning of function
94 # Check for Ready node, takes ~30 seconds
95 echo "Waiting for K8s nodes to be ready"
96 local time_for_failure=60 # seconds broken
97 local sampling_period=5 # seconds
98 local counter=0
99 local cluster_ready=""
100 while (( counter < time_for_failure ))
101 do
garciadeblas13b73b02025-09-24 11:48:23 +0200102 kubectl get nodes |grep control-plane |grep -v none | grep Ready
garciadeblasb3797412024-06-06 14:26:24 +0200103 if [ $? -eq 0 ] ; then
104 echo "K8s cluster is ready"
105 cluster_ready="y"
106 break
107 else
108 echo "K8s cluster is not ready yet"
109 counter=$((counter + sampling_period))
110 sleep ${sampling_period}
111 fi
112 done
113 [ -n "$cluster_ready" ] || FATAL_TRACK k8scluster "K3s cluster nodes not ready after $time_for_failure seconds."
114
115 echo "Waiting for pods to be ready"
116 local time_for_readiness=20 # seconds ready
117 local time_for_failure=100 # seconds broken
118
119 # Equivalent number of samples
120 oks_threshold=$((time_for_readiness/${sampling_period})) # No. ok samples to declare the system ready
121 failures_threshold=$((time_for_failure/${sampling_period})) # No. nok samples to declare the system broken
122 failures_in_a_row=0
123 oks_in_a_row=0
124 ####################################################################################
125 # Loop to check system readiness
126 ####################################################################################
127 K3S_NAMESPACE=kube-system
128 while [[ (${failures_in_a_row} -lt ${failures_threshold}) && (${oks_in_a_row} -lt ${oks_threshold}) ]]
129 do
130 # State of pods rather than completed jobs
131 K3S_PODS_STATE=$(kubectl get pod -n ${K3S_NAMESPACE} --no-headers |grep -v Completed 2>&1)
132 K3S_PODS_READY=$(echo "${K3S_PODS_STATE}" | awk '$2=="1/1" || $2=="2/2" {printf ("%s\t%s\t\n", $1, $2)}')
133 K3S_PODS_NOT_READY=$(echo "${K3S_PODS_STATE}" | awk '$2!="1/1" && $2!="2/2" {printf ("%s\t%s\t\n", $1, $2)}')
134 COUNT_K3S_PODS_READY=$(echo "${K3S_PODS_READY}"| grep -v -e '^$' | wc -l)
135 COUNT_K3S_PODS_NOT_READY=$(echo "${K3S_PODS_NOT_READY}" | grep -v -e '^$' | wc -l)
136
137 # OK sample
138 if [[ ${COUNT_K3S_PODS_NOT_READY} -eq 0 ]]
139 then
140 ((++oks_in_a_row))
141 failures_in_a_row=0
142 echo -ne ===\> Successful checks: "${oks_in_a_row}"/${oks_threshold}\\r
143 # NOK sample
144 else
145 ((++failures_in_a_row))
146 oks_in_a_row=0
147 echo
148 echo Bootstraping... "${failures_in_a_row}" checks of ${failures_threshold}
149
150 # Reports failed pods in K3S
151 if [[ "${COUNT_K3S_PODS_NOT_READY}" -ne 0 ]]
152 then
153 echo "K3S kube-system: Waiting for ${COUNT_K3S_PODS_NOT_READY} of $((${COUNT_K3S_PODS_NOT_READY}+${COUNT_K3S_PODS_READY})) pods to be ready:"
154 echo "${K3S_PODS_NOT_READY}"
155 echo
156 fi
157 fi
158
159 #------------ NEXT SAMPLE
160 sleep ${sampling_period}
161 done
162
163 ####################################################################################
164 # OUTCOME
165 ####################################################################################
166 if [[ (${failures_in_a_row} -ge ${failures_threshold}) ]]
167 then
168 echo
169 FATAL_TRACK k8scluster "K8S CLUSTER IS BROKEN"
170 else
171 echo
172 echo "K8S CLUSTER IS READY"
173 fi
174 [ -z "${DEBUG_INSTALL}" ] || DEBUG end of function
175}
176
garciadeblas1f338482024-07-04 19:26:54 +0200177# Initializes kubeconfig file
178function save_kubeconfig() {
garciadeblasb3797412024-06-06 14:26:24 +0200179 [ -z "${DEBUG_INSTALL}" ] || DEBUG beginning of function
180 KUBEDIR="${HOME}/.kube"
181 KUBEFILE="$KUBEDIR/config"
182 mkdir -p "${KUBEDIR}"
garciadeblas1f338482024-07-04 19:26:54 +0200183 K3S_KUBECONFIG="/etc/rancher/k3s/k3s.yaml"
184 sudo cp "${K3S_KUBECONFIG}" "${KUBEFILE}"
garciadeblasb3797412024-06-06 14:26:24 +0200185 sudo chown $(id -u):$(id -g) "${KUBEFILE}"
garciadeblas1f338482024-07-04 19:26:54 +0200186 sed -i "s#server: https://127.0.0.1#server: https://${DEFAULT_IP}#g" "${KUBEFILE}"
garciadeblasb3797412024-06-06 14:26:24 +0200187 chmod 700 "${KUBEFILE}"
188 echo
189 echo "Credentials saved at ${KUBEFILE}"
190 echo
191 [ -z "${DEBUG_INSTALL}" ] || DEBUG end of function
192}
193
garciadeblas82981162024-07-23 15:24:00 +0200194DEBUG_INSTALL=${DEBUG_INSTALL:-}
195DEFAULT_IP=${DEFAULT_IP:-"127.0.0.1"}
garciadeblasdb368c32024-11-20 12:55:45 +0100196DOCKER_PROXY_URL=${DOCKER_PROXY_URL:-}
197DOCKER_REGISTRY_URL=${DOCKER_REGISTRY_URL:-}
198DOCKER_REGISTRY_USER=${DOCKER_REGISTRY_USER:-}
199DOCKER_REGISTRY_PASSWORD=${DOCKER_REGISTRY_PASSWORD:-}
garciadeblase3a84a52024-09-27 11:34:55 +0200200K3S_PUBLIC_IP=${K3S_PUBLIC_IP:-}
garciadeblas1f338482024-07-04 19:26:54 +0200201echo "DEBUG_INSTALL=${DEBUG_INSTALL}"
202echo "DEFAULT_IP=${DEFAULT_IP}"
garciadeblas117fd4a2024-08-21 18:18:14 +0200203echo "DOCKER_PROXY_URL=${DOCKER_PROXY_URL}"
garciadeblas2efb98b2024-08-21 21:19:36 +0200204echo "DOCKER_REGISTRY_URL=${DOCKER_REGISTRY_URL}"
205echo "DOCKER_REGISTRY_USER=${DOCKER_REGISTRY_USER}"
garciadeblase3a84a52024-09-27 11:34:55 +0200206echo "K3S_PUBLIC_IP=${K3S_PUBLIC_IP}"
garciadeblasb3797412024-06-06 14:26:24 +0200207
garciadeblascf603f52025-06-04 11:57:28 +0200208export HERE=$(dirname "$(readlink --canonicalize "$BASH_SOURCE")")
209source "${HERE}/../../../library/logging"
210source "${HERE}/../../../library/track"
garciadeblas82981162024-07-23 15:24:00 +0200211
garciadeblas117fd4a2024-08-21 18:18:14 +0200212configure_registry
garciadeblasb3797412024-06-06 14:26:24 +0200213install_k3s
garciadeblascf603f52025-06-04 11:57:28 +0200214save_kubeconfig
garciadeblasb3797412024-06-06 14:26:24 +0200215track k8scluster k3s_install_ok
216check_for_readiness
217track k8scluster k3s_node_ready_ok
218# update_service_nodeport_range
219# check_for_readiness
garciadeblasb3797412024-06-06 14:26:24 +0200220track k8scluster k3s_creds_ok