Last active
April 12, 2022 11:22
-
-
Save inductor/32116c486095e5dde886b55ff6e568c8 to your computer and use it in GitHub Desktop.
kubeadm-ha.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#/bin/bash -eu | |
# Set global variables | |
KUBE_API_SERVER_VIP=192.168.0.100 | |
NODE_IPS=( 192.168.0.11 192.168.0.12 192.168.0.13 ) | |
# Install HAProxy | |
apt-get install -y --no-install-recommends software-properties-common | |
add-apt-repository ppa:vbernat/haproxy-2.4 -y | |
sudo apt-get install -y haproxy=2.4.\* | |
cat > /etc/haproxy/haproxy.cfg <<EOF | |
global | |
log /dev/log local0 | |
log /dev/log local1 notice | |
chroot /var/lib/haproxy | |
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners | |
stats timeout 30s | |
user haproxy | |
group haproxy | |
daemon | |
defaults | |
log global | |
mode http | |
option httplog | |
option dontlognull | |
timeout connect 5000 | |
timeout client 50000 | |
timeout server 50000 | |
errorfile 400 /etc/haproxy/errors/400.http | |
errorfile 403 /etc/haproxy/errors/403.http | |
errorfile 408 /etc/haproxy/errors/408.http | |
errorfile 500 /etc/haproxy/errors/500.http | |
errorfile 502 /etc/haproxy/errors/502.http | |
errorfile 503 /etc/haproxy/errors/503.http | |
errorfile 504 /etc/haproxy/errors/504.http | |
frontend k8s-api | |
bind ${KUBE_API_SERVER_VIP}:6443 | |
mode tcp | |
option tcplog | |
default_backend k8s-api | |
backend k8s-api | |
mode tcp | |
option tcplog | |
option tcp-check | |
balance roundrobin | |
default-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 250 maxqueue 256 weight 100 | |
server k8s-api-1 ${NODE_IPS[0]}:6443 check | |
server k8s-api-2 ${NODE_IPS[1]}:6443 check | |
server k8s-api-3 ${NODE_IPS[2]}:6443 check | |
EOF | |
# Install Keepalived | |
echo "net.ipv4.ip_nonlocal_bind = 1" >> /etc/sysctl.conf | |
sysctl -p | |
apt-get update && apt-get -y install keepalived | |
cat > /etc/keepalived/keepalived.conf <<EOF | |
# Define the script used to check if haproxy is still working | |
vrrp_script chk_haproxy { | |
script "/usr/bin/killall -0 haproxy" | |
interval 2 | |
weight 2 | |
} | |
# Configuration for Virtual Interface | |
vrrp_instance LB_VIP { | |
interface eth0 | |
state MASTER # set to BACKUP on the peer machine | |
priority 101 # set to 99 on the peer machine | |
virtual_router_id 51 | |
smtp_alert # Enable Notifications Via Email | |
authentication { | |
auth_type AH | |
auth_pass zaq12wsx # Password for accessing vrrpd. Same on all devices | |
} | |
unicast_src_ip ${NODE_IPS[0]} # Private IP address of master | |
unicast_peer { | |
${NODE_IPS[2]} # Private IP address of the backup haproxy | |
} | |
# The virtual ip address shared between the two loadbalancers | |
virtual_ipaddress { | |
${KUBE_API_SERVER_VIP} | |
} | |
# Use the Defined Script to Check whether to initiate a fail over | |
track_script { | |
chk_haproxy | |
} | |
} | |
EOF | |
# Enable VIP services | |
systemctl enable keepalived --now | |
systemctl enable haproxy --now | |
# Install Containerd | |
cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf | |
overlay | |
br_netfilter | |
EOF | |
sudo modprobe overlay | |
sudo modprobe br_netfilter | |
# Setup required sysctl params, these persist across reboots. | |
cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf | |
net.bridge.bridge-nf-call-iptables = 1 | |
net.ipv4.ip_forward = 1 | |
net.bridge.bridge-nf-call-ip6tables = 1 | |
EOF | |
# Apply sysctl params without reboot | |
sudo sysctl --system | |
## Install containerd | |
sudo apt-get update && sudo apt-get install -y containerd | |
# Configure containerd | |
sudo mkdir -p /etc/containerd | |
sudo containerd config default > /etc/containerd/config.toml | |
if grep -q "SystemdCgroup = true" "/etc/containerd/config.toml"; then | |
echo "Config found, skip rewriting..." | |
else | |
sed -i -e "s/SystemdCgroup \= false/SystemdCgroup \= true/g" /etc/containerd/config.toml | |
fi | |
sudo systemctl restart containerd | |
# Modify kernel parameters for Kubernetes | |
cat <<EOF | tee /etc/sysctl.d/k8s.conf | |
net.bridge.bridge-nf-call-ip6tables = 1 | |
net.bridge.bridge-nf-call-iptables = 1 | |
vm.overcommit_memory = 1 | |
vm.panic_on_oom = 0 | |
kernel.panic = 10 | |
kernel.panic_on_oops = 1 | |
kernel.keys.root_maxkeys = 1000000 | |
kernel.keys.root_maxbytes = 25000000 | |
EOF | |
sysctl --system | |
# Install kubeadm | |
apt-get update && apt-get install -y apt-transport-https curl gnupg2 | |
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - | |
cat <<EOF | tee /etc/apt/sources.list.d/kubernetes.list | |
deb https://apt.kubernetes.io/ kubernetes-xenial main | |
EOF | |
apt-get update | |
apt-get install -y kubelet kubeadm kubectl | |
apt-mark hold kubelet kubeadm kubectl | |
# Set kubeadm bootstrap token using openssl | |
KUBEADM_BOOTSTRAP_TOKEN=$(openssl rand -hex 3).$(openssl rand -hex 8) | |
# Set init configuration for the first control plane | |
cat > ~/init_kubeadm.yaml <<EOF | |
apiVersion: kubeadm.k8s.io/v1beta3 | |
kind: InitConfiguration | |
bootstrapTokens: | |
- token: "$KUBEADM_BOOTSTRAP_TOKEN" | |
description: "kubeadm bootstrap token" | |
ttl: "24h" | |
nodeRegistration: | |
criSocket: "/var/run/containerd/containerd.sock" | |
--- | |
apiVersion: kubeadm.k8s.io/v1beta3 | |
kind: ClusterConfiguration | |
networking: | |
serviceSubnet: "10.96.0.0/16" | |
podSubnet: "10.128.0.0/16" | |
kubernetesVersion: "v1.23.5" | |
controlPlaneEndpoint: "${KUBE_API_SERVER_VIP}:6443" | |
--- | |
apiVersion: kubelet.config.k8s.io/v1beta1 | |
kind: KubeletConfiguration | |
cgroupDriver: "systemd" | |
protectKernelDefaults: true | |
EOF | |
# Disable swap | |
swapoff -a | |
# Pull images first | |
kubeadm config images pull | |
# Install Kubernetes without kube-proxy | |
kubeadm init --config init_kubeadm.yaml --skip-phases=addon/kube-proxy | |
mkdir -p $HOME/.kube | |
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config | |
chown $(id -u):$(id -g) $HOME/.kube/config | |
# Install Helm CLI | |
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash | |
# Install Cilium Helm chart | |
helm repo add cilium https://helm.cilium.io/ | |
helm install cilium cilium/cilium \ | |
--namespace kube-system \ | |
--set kubeProxyReplacement=strict \ | |
--set k8sServiceHost=${KUBE_API_SERVER_VIP} \ | |
--set k8sServicePort=6443 | |
# Generate control plane certificate | |
KUBEADM_UPLOADED_CERTS=$(kubeadm init phase upload-certs --upload-certs | tail -n 1) | |
# Set join configuration for other control plane nodes | |
cat > ~/join_kubeadm_cp.yaml <<EOF | |
apiVersion: kubelet.config.k8s.io/v1beta1 | |
kind: KubeletConfiguration | |
cgroupDriver: "systemd" | |
protectKernelDefaults: true | |
--- | |
apiVersion: kubeadm.k8s.io/v1beta3 | |
kind: JoinConfiguration | |
nodeRegistration: | |
criSocket: "/var/run/containerd/containerd.sock" | |
discovery: | |
bootstrapToken: | |
apiServerEndpoint: "${KUBE_API_SERVER_VIP}:6443" | |
token: "$KUBEADM_BOOTSTRAP_TOKEN" | |
unsafeSkipCAVerification: true | |
controlPlane: | |
certificateKey: "$KUBEADM_UPLOADED_CERTS" | |
EOF | |
# Set join configuration for worker nodes | |
cat > ~/join_kubeadm_wk.yaml <<EOF | |
apiVersion: kubelet.config.k8s.io/v1beta1 | |
kind: KubeletConfiguration | |
cgroupDriver: "systemd" | |
protectKernelDefaults: true | |
--- | |
apiVersion: kubeadm.k8s.io/v1beta3 | |
kind: JoinConfiguration | |
nodeRegistration: | |
criSocket: "/var/run/containerd/containerd.sock" | |
discovery: | |
bootstrapToken: | |
apiServerEndpoint: "${KUBE_API_SERVER_VIP}:6443" | |
token: "$KUBEADM_BOOTSTRAP_TOKEN" | |
unsafeSkipCAVerification: true | |
EOF |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment