Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@jslay88
Last active March 2, 2020 06:31
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jslay88/83d4729413d53c2ba485f4ffcaeb9bf9 to your computer and use it in GitHub Desktop.
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)
#!/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