Last active
March 2, 2020 06:31
-
-
Save jslay88/83d4729413d53c2ba485f4ffcaeb9bf9 to your computer and use it in GitHub Desktop.
Simple shell script to initialize the first k8s master. This was needed, because of some networking discrepancies with minikube testing in relation to a production cluster. This allows you to fire up a single node master/worker, single master multiple workers, or HA k8s via kubeadm. Installs Flannel and MetalLB (cause layer2 for local devel)
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 | |
# Simple shell script to initialize the first k8s master. | |
# This was needed, because of some networking discrepancies with minikube testing in relation to a production cluster. | |
# This allows you to fire up a single node master/worker, single master multiple workers, or HA k8s via kubeadm. | |
# Installs Flannel and MetalLB (cause layer2 for local devel) | |
# Pardon my terrible shell coding skills. Whipped this up on a late night. | |
### Settings ### | |
FLANNEL_MANIFEST="https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml" | |
METALLB_MANIFEST="https://raw.githubusercontent.com/google/metallb/v0.8.3/manifests/metallb.yaml" | |
# Any out-of-the-box manifests you'd like to apply from the start. | |
APP_MANIFESTS="~/manifests" | |
### DO NOT EDIT BELOW THIS LINE UNLESS YOU KNOW WHAT YOU ARE DOING ### | |
# Reset existing cluster (if any) | |
echo "Cleaning up existing installs (if any)..." | |
sudo kubeadm reset -f > /dev/null 2>&1 | |
# Cleanup | |
sudo rm -rf /var/lib/etcd | |
sudo rm -rf /var/lib/kubelet | |
sudo rm -rf /etc/kubernetes | |
sudo rm -rf /home/$USER/.kube | |
sudo rm -rf /root/.kube | |
IP=$(hostname --all-ip-addresses | awk '{print $1;}') | |
# Create cluster.yaml | |
cat <<EOF >/tmp/cluster.yaml | |
apiVersion: kubeadm.k8s.io/v1beta2 | |
certificatesDir: /etc/kubernetes/pki | |
clusterName: kubernetes | |
controllerManager: {} | |
dns: | |
type: CoreDNS | |
etcd: | |
local: | |
dataDir: /var/lib/etcd | |
imageRepository: k8s.gcr.io | |
kind: ClusterConfiguration | |
controlPlaneEndpoint: $IP:6443 | |
networking: | |
dnsDomain: cluster.local | |
podSubnet: 10.244.0.0/16 | |
serviceSubnet: 10.96.0.0/12 | |
scheduler: {} | |
apiServer: | |
extraArgs: | |
authorization-mode: Node,RBAC | |
timeoutForControlPlane: 4m0s | |
EOF | |
# Collect informationi | |
HA=false | |
OTHER_MASTERS_IPS=() | |
OTHER_MASTERS_NAMES=() | |
whiptail --title "Untaint Master?" --yesno --defaultno "Untaint Master for single node operation?" 8 78 | |
TAINT=$? | |
if [ $TAINT = 1 ]; then | |
if (whiptail --title "HA Deployment?" --yesno "Is this a High-Availability Cluster?" 8 78 ); then | |
HA=true | |
while (true); do | |
NEXT_MASTER=$(whiptail --inputbox "Additional Master IP (Empty for finished)" 8 78 --title "Additional Master IP" 3>&1 1>&2 2>&3) | |
if [[ $NEXT_MASTER = "" ]]; then | |
break | |
fi | |
NEXT_MASTER_NAME=$(whiptail --inputbox "$NEXT_MASTER FQDN for API Certificate" 8 78 --title "$NEXT_MASTER FQDN" 3>&1 1>&2 2>&3) | |
OTHER_MASTERS_IPS+=($NEXT_MASTER) | |
OTHER_MASTERS_NAMES+=($NEXT_MASTER_NAME) | |
done | |
HA_API_IP=$(whiptail --inputbox "HA API IP Address" 8 78 --title "HA API IP Address" 3>&1 1>&2 2>&3) | |
HA_API_FQDN=$(whiptail --inputbox "HA API FQDN" 8 78 --title "HA API FQDN" 3>&1 1>&2 2>&3) | |
echo " certSANs:" >> /tmp/cluster.yaml | |
for i in $OTHER_MASTERS_IPS; do | |
echo " - $i" >> /tmp/cluster.yaml | |
done | |
for i in $OTHER_MASTERS_NAMES; do | |
echo " - $i" >> /tmp/cluster.yaml | |
done | |
echo " - $HA_API_IP" >> /tmp/cluster.yaml | |
echo " - $HA_API_FQDN" >> /tmp/cluster.yaml | |
fi | |
fi | |
# Initialize Cluster | |
sudo kubeadm init --config=/tmp/cluster.yaml | |
echo "Copying kubeconfig..." | |
sudo mkdir -p /home/$USER/.kube | |
sudo cp -i /etc/kubernetes/admin.conf /home/$USER/.kube/config | |
sudo chown $USER:$USER /home/$USER/.kube/config | |
if [ $TAINT = 0 ]; then | |
echo "Untainting Master..." | |
kubectl taint nodes --all node-role.kubernetes.io/master- | |
fi | |
echo "Installing Flannel..." | |
kubectl apply -f $FLANNEL_MANIFEST | |
echo "Installing MetalLB..." | |
kubectl apply -f $METALLB_MANIFEST | |
START_IP=$(whiptail --inputbox "Starting LoadBalancer Range Address" 8 78 --title "MetalLB Configuration" 3>&1 1>&2 2>&3) | |
END_IP=$(whiptail --inputbox "Ending LoadBalancer Range Address" 8 78 --title "MetalLB Configuration" 3>&1 1>&2 2>&3) | |
if ($HA); then | |
cat <<EOF | kubectl apply -f - | |
apiVersion: v1 | |
kind: ConfigMap | |
metadata: | |
namespace: metallb-system | |
name: config | |
data: | |
config: | | |
address-pools: | |
- name: default | |
protocol: layer2 | |
addresses: | |
- $START_IP-$END_IP | |
- name: ha-api | |
protocol: layer2 | |
addresses: | |
- $HA_API_IP-$HA_API_IP | |
EOF | |
# There is probably a much better way to do this, but I am no bash coder | |
cat <<EOF >/tmp/nginx-ha-api-proxy.yaml | |
--- | |
apiVersion: v1 | |
kind: ConfigMap | |
metadata: | |
name: nginx-ha-api-proxy | |
namespace: kube-system | |
data: | |
nginx.conf: | | |
error_log stderr notice; | |
worker_processes auto; | |
events { | |
multi_accept on; | |
use epoll; | |
worker_connections 1024; | |
} | |
stream { | |
upstream kube_apiserver { | |
EOF | |
echo " server $IP:6443;" >> /tmp/nginx-ha-api-proxy.yaml | |
for i in $OTHER_MASTERS_IPS; do | |
echo " server $i:6443;" >> /tmp/nginx-ha-api-proxy.yaml | |
done | |
cat <<EOF >>/tmp/nginx-ha-api-proxy.yaml | |
} | |
server { | |
listen 6443; | |
proxy_pass kube_apiserver; | |
proxy_timeout 30; | |
proxy_connect_timeout 2s; | |
} | |
} | |
--- | |
apiVersion: apps/v1 | |
kind: DaemonSet | |
metadata: | |
name: nginx-ha-api-proxy | |
namespace: kube-system | |
spec: | |
selector: | |
matchLabels: | |
app: nginx-ha-api-proxy | |
template: | |
metadata: | |
labels: | |
app: nginx-ha-api-proxy | |
spec: | |
containers: | |
- name: nginx | |
image: nginx | |
volumeMounts: | |
- name: config-volume | |
mountPath: /etc/nginx | |
ports: | |
- containerPort: 6443 | |
volumes: | |
- name: config-volume | |
configMap: | |
name: nginx-ha-api-proxy | |
restartPolicy: Always | |
--- | |
apiVersion: v1 | |
kind: Service | |
metadata: | |
name: nginx-ha-api-proxy | |
namespace: kube-system | |
annotations: | |
metallb.universe.tf/address-pool: ha-api | |
spec: | |
sessionAffinity: ClientIP | |
selector: | |
app: nginx-ha-api-proxy | |
type: LoadBalancer | |
ports: | |
- protocol: TCP | |
port: 443 | |
targetPort: 6443 | |
EOF | |
kubectl apply -f /tmp/nginx-ha-api-proxy.yaml | |
else | |
cat <<EOF | kubectl apply -f - | |
apiVersion: v1 | |
kind: ConfigMap | |
metadata: | |
namespace: metallb-system | |
name: config | |
data: | |
config: | | |
address-pools: | |
- name: default | |
protocol: layer2 | |
addresses: | |
- $START_IP-$END_IP | |
EOF | |
fi | |
echo "Applying Application Manifests..." | |
kubectl apply -f $APP_MANIFESTS/ | |
echo -e "\n\n\n\n" | |
echo "Finished! It can take up to 2 minutes for the cluster to finish coming up." | |
if [ $HA = true ]; then | |
sudo tar cfz certs.tar.gz /etc/kubernetes/pki/ca.{crt,key} /etc/kubernetes/pki/sa.{pub,key} /etc/kubernetes/pki/front-proxy-ca.{crt,key} /etc/kubernetes/pki/etcd/ca.{crt,key} > /dev/null 2>&1 | |
echo "Copy $(pwd)/certs.tar.gz to remaining masters, extract with \`sudo tar xvfz certs.tar.gz -C /\`, then join the masters using the above join command with --control-plane" | |
fi | |
if [ $TAINT = 1 ]; then | |
echo "You may now use the join command above to join additional workers." | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment