provisioning/taskservs/kubernetes/default/install-kubernetes.sh
2025-09-22 23:11:41 +01:00

419 lines
14 KiB
Bash
Executable File

#!/bin/bash
# Info: Script to install/create/delete/update Kubernetes from file settings
# Author: JesusPerezLorenzo
# Release: 1.0
# Date: 30-10-2023
USAGE="install-kubernetes.sh full-path-settings-file [ -m controlplane (hostname -cp-) | worker] [*install | update | makejoin | remove | fullremove]"
[ "$1" == "-h" ] && echo "$USAGE" && exit 1
_save_target() {
[ -z "$TARGET_SAVE_PATH" ] && return
local file_path=$1
mkdir -p "$TARGET_SAVE_PATH"
if cp "$file_path" "$TARGET_SAVE_PATH" ; then
echo "$file_path saved in $TARGET_SAVE_PATH"
fi
}
# shellcheck disable=SC1090
[[ "$1" == *setting* ]] && [ -r "$1" ] && . "$1" && shift
# shellcheck disable=SC1090
[[ "$1" == env-* ]] && [ -r "$1" ] && . "$1" && shift
[ -r "env-kubernetes" ] && . env-kubernetes
[ -z "$CLUSTER_NAME" ] && echo "No CLUSTER_NAME value " && exit 1
[ -z "$VERSION" ] && echo "No VERSION value " && exit 1
INSTALL_LOG=${INSTALL_LOG:-/tmp/k8s.log}
WORK_PATH=${WORK_PATH:-/tmp}
[ ! -d "$WORK_PATH" ] && sudo mkdir -p "$WORK_PATH"
export LC_CTYPE=C.UTF-8
export LANG=C.UTF-8
cmd_out=/dev/null
echo "Log path to $INSTALL_LOG"
[ ! -d "$(dirname "$INSTALL_LOG")" ] && mkdir -p "$(dirname "$INSTALL_LOG")"
echo "Work path to $WORK_PATH"
if [ -z "$K8S_MODE" ] ; then
if [[ "$HOSTNAME" == *-cp-* ]] ; then
K8S_MODE="controlplane"
else
K8S_MODE="worker"
fi
fi
[ "$1" == "-m" ] && K8S_MODE=$2 && shift 2
[ -n "$1" ] && CMD_TSK=$1 && shift
_check_resolution() {
local hostname=""
hostname=$HOSTNAME
local clustername=""
local ip=""
[ "$K8S_MODE" == "controlplane" ] && clustername="$CLUSTER_NAME"
#sudo sed -i /^127.0.1.1/d /etc/hosts 2>>$cmd_out
ip=$(grep "$hostname" /etc/hosts | grep -v "^#" | awk '{print $1}')
[ -n "$ip" ] && [ "$ip" == "127.0.1.1" ] && sudo sed -i /^"$ip"/d /etc/hosts 2>>$cmd_out
ip=$(grep "$MAIN_IP" /etc/hosts | grep -v "^#" | awk '{print $1}')
[ -z "$ip" ] && echo "$MAIN_IP $hostname $clustername" | sudo tee -a /etc/hosts 2>>$cmd_out
if [ "$hostname" != "$(cat /etc/hostname)" ] ; then
echo "$hostname" | sudo tee /etc/hostname 2>>$cmd_out
sudo hostname "$hostname"
fi
}
_off_swap() {
local fs_swap
local fs_tab
fs_tab=/etc/fstab
fs_swap=$(grep -v "^#" $fs_tab | grep swap)
if [ -n "$fs_swap" ] ; then
sudo sed -i "s;$fs_swap;#$fs_swap;g" $fs_tab
fi
sudo swapoff -a
}
_kubernetes_init() {
[ -z "$VERSION" ] && exit 1
_check_resolution
curr_vers=$(kubectl version 2>/dev/null | grep Client | awk '{print $3}' | sed 's/^v//g' 2>/dev/null)
chmod 1777 /tmp
if [ "v$curr_vers" != "$K8S_VERSION" ]; then
echo "Install packages"
#if [ "$CMD_TSK" != "update" ] && [ ! -r "/etc/apt/keyrings/kubernetes-apt-keyring.gpg" ]; then
sudo DEBIAN_FRONTEND=noninteractive apt-get update && sudo DEBIAN_FRONTEND=noninteractive apt-get install -y apt-transport-https gnupg2 curl
sudo rm -f /etc/apt/keyrings/kubernetes-apt-keyring.gpg
curl -fsSL https://pkgs.k8s.io/core:/stable:/v"$MAJOR_VERSION"/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v$MAJOR_VERSION/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list
#fi
_off_swap
sudo DEBIAN_FRONTEND=noninteractive apt-get update -q
sudo DEBIAN_FRONTEND=noninteractive apt-mark unhold kubelet kubectl kubeadm
if ! sudo DEBIAN_FRONTEND=noninteractive apt-get install -y kubectl kubelet kubeadm ; then
echo "error installing kubernetes"
return 1
fi
# Hold your horse !
sudo DEBIAN_FRONTEND=noninteractive apt-mark hold kubelet kubectl kubeadm
echo "init done"
fi
}
_kubernetes_taint() {
case "$TAINT_NODE" in
no_schedule)
kubectl taint nodes "$HOSTNAME" node-role.kubernetes.io/master:NoSchedule
;;
schedule)
kubectl taint nodes "$HOSTNAME" node-role.kubernetes.io/master:NoSchedule
kubectl taint nodes "$HOSTNAME" node-role.kubernetes.io/master:NoSchedule- 2>>$cmd_out
;;
esac
return 0
}
_kubernetes_cri() {
[ ! -d "/etc/${K8S_CRI}" ] && echo "No /etc/${K8S_CRI} path found! " && exit 1
# if [ -r "cri/$K8S_CRI/install.sh" ] ; then
# #PKG_ORG=cri/"$K8S_CRI"
# echo "cri $K8S_CRI"
# # shellcheck disable=SC1090
# . "cri/$K8S_CRI/install.sh" | sudo tee -a "$INSTALL_LOG" >>$cmd_out
# else
# echo "$K8S_CRI not defined" && exit 1
# fi
return 0
}
_kubernetes_cni() {
if [ -r "cni/$K8S_CNI/install.sh" ] ; then
echo "cni $K8S_CNI"
# shellcheck disable=SC1090
. "cni/$K8S_CNI/install.sh" | sudo tee -a "$INSTALL_LOG" 2>>$cmd_out
else
echo "mode $K8S_CNI not defined" && exit 1
fi
}
_kubernetes_addons() {
local yaml_file
for item in ${K8S_ADDONS//,/ } #ls addons 2>/dev/null)
do
if [ -r "addons/$item/install.sh" ] ; then
echo "Install addon $item "| sudo tee -a "$INSTALL_LOG"
# shellcheck disable=SC1090
. "addons/$item/install.sh"
if [ "$item" == "istio" ] && [ -n "$K8S_EXTERNAL_IPS" ]; then
yaml_file=/tmp/externalIPs.yaml
echo "spec:" > $yaml_file
echo " externalIPs: " >> $yaml_file
for ip in ${K8S_EXTERNAL_IPS//,/ }
do
echo " - $ip" >> "$yaml_file"
done
# Patch istio ingressgateway to use ExternalIPs
kubectl patch service -n istio-system istio-ingressgateway --type merge --patch-file $yaml_file
fi
fi
done
}
_kubernetes_kube() {
local user=${1:-root}
local home_user=${2:-/home/root}
local uid
local gid
local has_aliases
uid=$(sudo id -u "$user" 2>/dev/null)
gid=$(sudo id -g "$user" 2>/dev/null)
if [ -f "/etc/kubernetes/admin.conf" ] ; then
sudo mkdir -p /root/.kube
sudo cp /etc/kubernetes/admin.conf /root/.kube/config
sudo chown root:root /root/.kube/config
if [ "$uid" == "0" ] ; then
mkdir -p "$home_user"/.kube
sudo cp /etc/kubernetes/admin.conf "$home_user"/.kube/config
sudo chown -R "$uid:$gid" "$home_user"/.kube
fi
has_aliases=$(grep bash_aliases "$HOME"/.bashrc)
[ -z "$has_aliases" ] && echo "[ -f ~/.bash_aliases ] && . ~/.bash_aliases" | sudo tee -a "$HOME"/.bashrc
if [ -r "$USER_HOME" ] && [ -n "$USER" ] ; then
mkdir -p "$USER_HOME"/.kube
sudo cp /etc/kubernetes/admin.conf "$USER_HOME"/.kube/config
sudo chown -R "$USER" "$USER_HOME"/.kube
if [ -r "$USER_HOME/.bash_aliases" ] && [ ! -r "$HOME/.bash_aliases" ] ; then
has_aliases=$(grep bash_aliases "$USER_HOME"/.bashrc)
[ -z "$has_aliases" ] && echo "[ -f ~/.bash_aliases ] && . ~/.bash_aliases" | sudo tee -a "$USER_HOME"/.bashrc
sudo cp "$USER_HOME"/.bash_aliases "$HOME"
sudo chown -R "$uid:$gid" "$HOME"/.bash_aliases
fi
fi
fi
}
_kubectl_appy() {
export KUBECONFIG=/etc/kubernetes/admin.conf
[ ! -r "$KUBECONFIG" ] && echo "$KUBECONFIG not found " && return 1
[ ! -r "$1" ] && echo "File $1 not found" && return 1
if ! kubectl apply -f "$1" ; then
echo "Error kubectl apply $1 "
fi
}
_kubernetes_install_master_0() {
_check_resolution
local has_apiserver=""
has_apiserver=$(sudo ps -aux | awk '{print $11}'| grep "kube-apiserver")
if [ ! -r "resources/$K8S_CONFIG" ] ; then
echo "resources/$K8S_CONFIG not found"
exit 1
fi
if [ "$ETCD_MODE" == "external" ] && [ -d "etcd_certs" ] ; then
[ ! -d "/etc/kubernetes/pki/etcd" ] && sudo mkdir -p /etc/kubernetes/pki/etcd
sudo cp -pr etcd_certs/* /etc/kubernetes/pki/etcd
if [ -n "$HOSTNAME" ] && [ "$HOSTNAME" != "$INSTALL_MASTER" ] && [ -d "pki" ] ; then
sudo cp -pr pki/* /etc/kubernetes/pki
fi
fi
echo "Install kubernetes master"
[ ! -r "resources/$K8S_CONFIG" ] && echo "Error resources/$K8S_CONFIG not found !" && exit 1
[ "resources/$K8S_CONFIG" != "$WORK_PATH/kubeadm-config.yaml" ] && cp "resources/$K8S_CONFIG" "$WORK_PATH"/kubeadm-config.yaml
if [ -z "$has_apiserver" ] ; then
sudo systemctl start kubelet 2>>$cmd_out
echo "You can follow kubeadm installation by using in another terminal: tail -f $INSTALL_LOG"
sudo kubeadm init --config "$WORK_PATH"/kubeadm-config.yaml --ignore-preflight-errors=all | sudo tee "$INSTALL_LOG"
_save_target "$WORK_PATH"/kubeadm-config.yaml
fi
local has_success=""
has_success=$(sudo grep "initialized successfully" "$INSTALL_LOG")
if [ -n "$has_success" ]; then
echo "$has_success"
_save_target "$INSTALL_LOG"
sudo grep -A1 "^kubeadm join" "$INSTALL_LOG" | sudo tee "$WORK_PATH"/k8s_join.sh
sudo chmod +x "$WORK_PATH/k8s_join.sh"
[ "$WORK_PATH" != "/tmp" ] && cp "$WORK_PATH/k8s_join.sh" /tmp
_kubernetes_kube "$(whoami)"
_kubernetes_cni
_kubernetes_addons
sudo mv "$INSTALL_LOG" "$WORK_PATH"
[ -r "runtimes.yaml" ] && _kubectl_appy runtimes.yaml
fi
}
_make_join_kubernetes() {
if ! kubeadm token create --print-join-command > "$WORK_PATH"/k8s_join.sh ; then
echo "Error to get token for join node "
exit 1
fi
}
_join_kubernetes() {
local join_path
[ -r "k8s_join.sh" ] && join_path="k8s_join.sh"
[ -r "/tmp/k8s_join.sh" ] && join_path="/tmp/k8s_join.sh"
if [ -r "$join_path" ] ; then
local cmd_join
if [ "$1" == "controlplane" ] ; then
cmd_join=$(sed 's/join /join --control-plane /g' < $join_path)
else
cmd_join=$(cat $join_path | sed 's/\\//g')
fi
[ -z "$cmd_join" ] && echo "Error cmd_join content" && exit 1
# shellcheck disable=SC2086
if ! sudo $cmd_join --ignore-preflight-errors=all | sudo tee "$INSTALL_LOG" >"$cmd_out"; then
echo "Error $HOSTNAME join command -> $cmd_join "
exit 1
fi
else
echo "No k8s_join.sh found"
return 0
fi
return 0
}
_install_kubernetes_controlplane() {
if [ "$ETCD_MODE" == "external" ] && [ -d "etcd_certs" ] ; then
[ ! -d "/etc/kubernetes/pki/etcd" ] && sudo mkdir -p /etc/kubernetes/pki/etcd
sudo cp -pr etcd_certs/* /etc/kubernetes/pki/etcd
if [ -n "$HOSTNAME" ] && [ "$HOSTNAME" != "$INSTALL_MASTER" ] && [ -d "pki" ] ; then
sudo cp -pr pki/* /etc/kubernetes/pki
fi
fi
if ! _join_kubernetes controlplane ; then
exit 2
else
_kubernetes_kube "$USER" "$USER_HOME"
_kubernetes_cni
_kubernetes_addons
fi
return 0
}
_install_kubernetes_worker() {
if ! _join_kubernetes worker ; then
exit 2
fi
return 0
}
_install_kubernetes() {
[ ! -d "/etc/${K8S_CRI}" ] && echo "No /etc/${K8S_CRI} path found! " && exit 1
sudo systemctl start "${K8S_CRI}"
_check_resolution
if [ -f "/etc/kubernetes/admin.conf" ] ; then
local server=""
local has_apiserver=""
has_apiserver=$(sudo ps -aux | awk '{print $11}'| grep "kube-apiserver")
server=$(sudo grep "server: " /etc/kubernetes/admin.conf | awk '{print $2}')
echo "$(date +%Y_%m_%d_%H%M%S) | Kubernetes already installed in $HOSTNAME with server: $server ($has_apiserver)" | sudo tee -a "$INSTALL_LOG"
if [ "$CMD_TSK" == "reinstall" ] ; then
echo "$(date +%Y_%m_%d_%H%M%S) | Kubernetes RESET installation in $HOSTNAME with server: $server ($has_apiserver) ..." | sudo tee -a "$INSTALL_LOG"
if sudo kubeadm reset -f ; then
echo "$(date +%Y_%m_%d_%H%M%S) | Kubernetes ready to be re-installed in $HOSTNAME " | sudo tee -a "$INSTALL_LOG"
fi
else
_kubernetes_kube "$USER" "$USER_HOME"
return
fi
elif [ -f "/etc/kubernetes/kubelet.conf" ] ; then
echo "$(date +%Y_%m_%d_%H%M%S) | Kubernetes kubelet already running in $HOSTNAME"
if [ "$CMD_TSK" == "reinstall" ] ; then
echo "$(date +%Y_%m_%d_%H%M%S) | Kubernetes kubelet RESET in $HOSTNAME ..."
if sudo kubeadm reset -f ; then
echo "$(date +%Y_%m_%d_%H%M%S) | Kubernetes ready to be re-installed in $HOSTNAME " | sudo tee -a "$INSTALL_LOG"
fi
else
return
fi
fi
has_kubelet=$(sudo ps -aux | awk '{print $11}'| grep "kubelet")
if [ -n "$has_kubelet" ] ; then
if [ "$CMD_TSK" == "reinstall" ] ; then
if sudo kubeadm reset -f ; then
echo "$(date +%Y_%m_%d_%H%M%S) | Kubernetes ready to be re-installed in $HOSTNAME " | sudo tee -a "$INSTALL_LOG"
fi
else
echo "$(date +%Y_%m_%d_%H%M%S) | Kubernetes kubelet already runnint in $HOSTNAME"
return
fi
fi
if [ -n "$HOSTNAME" ] && [ "$HOSTNAME" == "$K8S_MASTER" ] ; then
#IS_MASTER_0="yes"
_kubernetes_install_master_0
_kubernetes_taint
else
case "$K8S_MODE" in
controlplane)
_install_kubernetes_controlplane
_kubernetes_taint
;;
worker)
_install_kubernetes_worker
;;
*) echo "mode $K8S_MODE not defined" && exit 1
esac
fi
}
_config_kubernetes() {
[ ! -d "/etc/${K8S_CRI}" ] && echo "No /etc/${K8S_CRI} path found! " && exit 1
sudo systemctl start "${K8S_CRI}"
sudo sed -i 's/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/' /etc/sysctl.conf
has_nolocal_bind=$(sudo grep "net.ipv4.ip_nonlocal_bind = 1" /etc/sysctl.conf)
if [ -z "$has_nolocal_bind" ] ; then
echo "net.ipv4.ip_nonlocal_bind = 1" | sudo tee -a /etc/sysctl.conf >>$cmd_out
#echo "net.bridge.bridge-nf-call-iptables=1" | sudo tee -a /etc/sysctl.conf
sudo modprobe br_netfilter
echo 1 | sudo tee -a /proc/sys/net/bridge/bridge-nf-call-iptables >>$cmd_out
fi
sudo sysctl -p >>$cmd_out
return 0
}
_remove_kubernetes() {
sudo systemctl stop kubelet
sudo systemctl disable kubelet
}
_full_remove_kubernetes() {
_remove_kubernetes
sudo kubeadm reset -y
sudo rm -r /etc/kubernetes /etc/cni
}
_start_kubernetes() {
if [ "$SYSTEMCTL_MODE" == "enabled" ] ; then
sudo systemctl enable kubelet
else
sudo systemctl disable kubelet
fi
sudo systemctl start kubelet
}
_restart_kubernetes() {
sudo systemctl restart kubelet
}
case "$CMD_TSK" in
remove)
_remove_kubernetes
exit 0
;;
fullremove|full-remove)
_full_remove_kubernetes
exit 0
;;
update)
_restart_kubernetes
;;
makejoin)
_make_join_kubernetes
exit 0
;;
reinstall) ;;
esac
if ! _kubernetes_cri ; then
echo "error CRI install"
exit 1
fi
if ! _kubernetes_init ; then
echo "error kubernetes install"
exit 1
fi
if ! _config_kubernetes ; then
echo "error kubernetes config"
exit 1
fi
if ! _install_kubernetes ; then
echo "error kubernetes install"
exit 1
fi
if ! _start_kubernetes ; then
echo "error kubernetes start"
exit 1
fi
echo "Work path: $WORK_PATH"
echo "Log info: $INSTALL_LOG"