Skip to content

Instantly share code, notes, and snippets.

@davidjsanders
Last active May 22, 2019 01:42
Show Gist options
  • Save davidjsanders/16ae9a92d78dc0ae4cd4807ada422558 to your computer and use it in GitHub Desktop.
Save davidjsanders/16ae9a92d78dc0ae4cd4807ada422558 to your computer and use it in GitHub Desktop.
Vagrantfile to prepare and build VMs for LFD259 - Certified Kubernetes Application Developer environment
#
# To run...
# LFDUrl=https://.../LFD259_...tar.bz2 LFDUser=theusername LFDPassword=thepassword vagrant up
#
# Thanks to Raj Rajaratnam for his original Medium article:
# https://medium.com/@wso2tech/multi-node-kubernetes-cluster-with-vagrant-virtualbox-and-kubeadm-9d3eaac28b98
#
$bothScript = <<-SCRIPT
#
# Set the timezone to Toronto
#
echo "Set timezone to Eastern (Toronto)"
timedatectl set-timezone America/Toronto
#
# Get the tarball from the LFD URL and the
# credentials passed with the vagrant up
# command
#
echo "Fetch LFD259 tarball"
wget \
--user=$LFDUser \
--password=$LFDPassword \
--quiet \
$LFDUrl
#
# Because running as root, change to the
# vagrant home directory
#
echo "Change directory to /home/vagrant"
cd /home/vagrant
#
# Find the tarball; there should be no
# other. Then extract the contents.
#
filename=$(ls -1 *.tar.bz2)
echo "Extract LFD contents from ${filename}"
tar -xvf ${filename}
#
# Do and apt-get update to update packages
#
echo "Do apt-get update"
apt-get update
#
# Install sshpass
#
echo "Install required packages"
DEBIAN_FRONTEND=noninteractive \
apt-get -o Dpkg::Options::="--force-confold" \
-q \
install sshpass --yes
#
# Upgrade all packages
#
echo "Upgrade all packages"
DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confold" -q upgrade --yes
#
# Update password auth for ssh to allow
# the use of sshpass to get and push
# files to/from the master
#
echo "Update password auth"
sudo sed -i \
"s/PasswordAuthentication no/PasswordAuthentication yes"/g \
/etc/ssh/sshd_config
#
# Restart SSH to make the change take
# effect.
#
echo "Restart SSH service"
sudo service sshd restart
#
# Generate an ssh key
#
echo "Generate key"
ssh-keygen -t rsa -b 4096 -N "" -f /home/vagrant/.ssh/id_rsa
#
# Finally, change the owner of all
# files in /home/vagrant to vagrant
#
echo "Change owner to vagrant on all files in /home/vagrant"
chown -R vagrant /home/vagrant
echo
echo "General provisioning done"
echo
SCRIPT
$masterScript = <<-SCRIPT
#
# Note, running as vagrant
#
#
# Copy the k8sMaster.sh script from the
# extracted tarball to the home directory
#
echo "Copy k8sMaster.sh to home directory"
cp /home/vagrant/LFD259/SOLUTIONS/s_02/k8sMaster.sh .
#
# Get the IP address of the virtual box
# so we can setup K8S properly.
#
echo "Define IP Address"
export IP_ADDR=`ifconfig enp0s8 | grep Mask | awk '{print $2}'| cut -f2 -d:`
echo "IP Address is: \$IP_ADDR"
#
# Update the course script to add the
# IP address as the API Server Advertise
# Address.
#
echo "Update k8sMaster.sh to use \$IP_ADDR as advertise address"
sed -i "/kubeadm init/ s/$/ --apiserver-advertise-address=$IP_ADDR/" \
/home/vagrant/k8sMaster.sh
#
# Add k8s-node-1 to the /etc/hosts file
# to make it easier to ssh to
#
echo "Add k8s-node-1 to /etc/hosts"
echo "${K8SNODE1} k8s-node-1 k8s-node-1" | sudo tee -a /etc/hosts
#
# Run the k8sMaster.sh script that was
# extracted from the tarball and
# modified
#
echo "Run k8sMaster.sh"
echo "----------------"
echo
bash /home/vagrant/k8sMaster.sh | tee /home/vagrant/master.out
#
# Create a join command script that
# k8s-node-1 can copy over ssh and
# execute to join the cluster.
#
echo -n "sudo " > kubeadm_join_cmd.sh
kubeadm token \
create \
--print-join-command \
>> kubeadm_join_cmd.sh
echo "source <(kubectl completion bash)" >> ~/.bashrc
echo
echo "Master provisioning done."
echo
SCRIPT
$workerScript = <<-SCRIPT
#
# Note, running as vagrant
#
#
# Copy the k8sSecond.sh script from the
# extracted tarball to the home directory
#
echo "Copy k8sSecond.sh to home directory"
cp ~/LFD259/SOLUTIONS/s_02/k8sSecond.sh /home/vagrant/
#
# Get the IP address of the virtual box
# so we can setup K8S properly.
#
echo "Define IP Address"
export IP_ADDR=`ifconfig enp0s8 | grep Mask | awk '{print $2}'| cut -f2 -d:`
echo "IP Address is: \$IP_ADDR"
#
# Add k8s-master to the /etc/hosts file
# to make it easier to ssh to
#
echo "${K8SMASTER} k8s-master k8s-master" | sudo tee -a /etc/hosts
#
# Run the k8sMaster.sh script that was
# extracted from the tarball
#
echo "Run k8sSecond.sh"
echo "----------------"
echo
bash /home/vagrant/k8sSecond.sh | tee /home/vagrant/second.out
#
# Set the KUBELET_EXTRA_ARGS so when we
# join the cluster, the correct IP Address
# is used rather than the duplicate private
# host IP address (10.0.2.15).
#
echo "Set KUBELET_EXTRA_ARGS to use IP address $IP_ADDR"
echo "KUBELET_EXTRA_ARGS=--node-ip $IP_ADDR" | sudo tee -a /etc/default/kubelet
echo
echo "Validate /etc/default/kubelet"
echo "-----------------------------"
cat /etc/default/kubelet
#
# Fetch the join command from the
# master node
#
echo "Get kubeadm_join_cmd.sh from k8s-master"
sshpass \
-p "vagrant" \
scp -o StrictHostKeyChecking=no \
vagrant@k8s-master:/home/vagrant/kubeadm_join_cmd.sh .
#
# Get the master node's public key via ssh
#
echo "Get public key from k8s-master"
sshpass \
-p "vagrant" \
scp -o StrictHostKeyChecking=no \
vagrant@k8s-master:/home/vagrant/.ssh/id_rsa.pub /tmp/prkey.pub
#
# Add the id_rsa.pub key to authorized_keys
#
echo "Add k8s-master public key to Authorized keys"
cat /tmp/prkey.pub >> /home/vagrant/.ssh/authorized_keys
#
# Remove the temporary key
#
echo "Remove k8s-master temporary public key"
rm /tmp/prkey.pub
#
# Send the k8s-node-1 public key to the
# master via ssh
#
echo "Send public key to k8s-master"
sshpass \
-p "vagrant" \
scp -o StrictHostKeyChecking=no \
/home/vagrant/.ssh/id_rsa.pub vagrant@k8s-master:/tmp/temp.pub
#
# Run the command to cat the public key
# to the authorized keys and then remove
# it
#
echo "Add public key to authorized keys on k8s-master"
sshpass \
-p "vagrant" \
ssh -o StrictHostKeyChecking=no \
vagrant@k8s-master \
"cat /tmp/temp.pub >> /home/vagrant/.ssh/authorized_keys && rm /tmp/temp.pub"
#
# Set the password to an md5sum value that
# should be difficult to guess and/or crack
#
passwd=$(date | md5sum | cut -c -32)
#
# Create a simple script to change the
# password via ssh
#
echo "passwd=$passwd" > ~/chpwd.sh
echo "echo 'vagrant:'\$passwd | sudo chpasswd" >> ~/chpwd.sh
chmod +x chpwd.sh
#
# Send the script to k8s-master
#
echo "Send chpwd to master"
sshpass \
-p "vagrant" \
scp -o StrictHostKeyChecking=no \
/home/vagrant/chpwd.sh vagrant@k8s-master:~/chpwd.sh
#
# Execute the script on k8s-master
#
echo "Change password on k8s-master"
sshpass \
-p "vagrant" \
ssh -o StrictHostKeyChecking=no \
vagrant@k8s-master ~/chpwd.sh
#
# Remove the script file
#
echo "Remove password script on k8s-master"
sshpass \
-p $passwd \
ssh -o StrictHostKeyChecking=no \
vagrant@k8s-master rm -rf ~/chpwd.sh
#
# Change the password locally
#
echo "Change password locally"
~/chpwd.sh
#
# Remove the script file
#
echo "Remove password file"
rm chpwd.sh
#
# Execute the kubeadm join command
#
echo "Execute kubeadm_join_cmd.sh"
. kubeadm_join_cmd.sh
echo
echo "k8s-node-1 provisioning done."
echo
SCRIPT
servers = [
{
:name => "k8s-master",
:type => "master",
:box => "ubuntu/xenial64",
:box_version => "20190516.0.0 ",
:eth1 => "192.168.205.10",
:hostip => "10.0.2.15",
:mem => "2048",
:cpu => "2",
:provision => "yes"
},
{
:name => "k8s-node-1",
:type => "node",
:box => "ubuntu/xenial64",
:box_version => "20190516.0.0 ",
:eth1 => "192.168.205.11",
:hostip => "10.0.2.16",
:mem => "2048",
:cpu => "2",
:provision => "yes"
}
]
Vagrant.configure("2") do |config|
servers.each do |opts|
if opts[:provision] == "yes"
config.vm.define opts[:name] do |config|
config.vm.box = opts[:box]
config.vm.box_version = opts[:box_version]
config.vm.hostname = opts[:name]
config.vm.network :private_network, ip: opts[:eth1]
config.vm.provider "virtualbox" do |v|
v.name = opts[:name]
v.customize ["modifyvm", :id, "--memory", opts[:mem]]
v.customize ["modifyvm", :id, "--cpus", opts[:cpu]]
end
config.vm.provision "shell",
inline: $bothScript,
env: {
LFDUser:ENV['LFDUser'],
LFDPassword:ENV['LFDPassword'],
LFDUrl:ENV['LFDUrl']
}
if opts[:type] == "master"
config.vm.provision "shell",
inline: $masterScript,
privileged: false,
env: {
K8SNODE1:servers[1][:eth1],
}
else
config.vm.provision "shell",
inline: $workerScript,
privileged: false,
env: {
K8SMASTER:servers[0][:eth1],
}
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment