I will create vagrant multi-node configuration and use it for my future labs. These nodes have very basic provisioning like hostname, ip and some useful packages.
It is really simple to setup VMs using vagrant. You can read more about vagrant here.In this lab I am creating 3 VM configuration using vagrant box centos/7. I will add basic packages and then save them as vagrant boxes for future use.
you check vagrant registry for boxes here.
Below is the procedure I followed to build my multi-node infrastructure
- Download and install Vagrant. I am using Centos 7 host machine select vagrant package according to your machine here
- Install vagrant package
$ sudo rpm -Uvh vagrant_1.9.1_x86_64.rpm We trust you have received the usual lecture from the local System Administrator. It usually boils down to these three things: #1) Respect the privacy of others. #2) Think before you type. #3) With great power comes great responsibility. [sudo] password for divine: Preparing... ################################# [100%] Updating / installing... 1:vagrant-1:1.9.1-1 ################################# [100%]
3. Install Virtual box. Below is the procedure from official Centos site. I am using virtualbox for my VMs, it is a default provider for vagrant other options are vmware,hyper-v and docker
$sudo yum update -y $sudo yum install dkms $sudo wget -P /etc/yum.repos.d http://download.virtualbox.org/virtualbox/rpm/rhel/virtualbox.repo $sudo yum install VirtualBox-5.0 $sudo usermod -a -G vboxusers <your_user_name>
4. Create vagrantfile in the directory where you want to work from. Note: vagrant checks current directory for vagrantfile
This command will create a generic vagrantfile.
$vagrant init
5. Open vagrantfile and add below commands. These commands will spin 3 VMs. I have named them Master, Node1 & Node2. Each VM assigned 2048 MB RAM, 2 CPU core, IP address and hostname.
As can be seen I am using centos/7 in vm.box
$ cat Vagrantfile Vagrant.configure("2") do |config| #VM1: Master config.vm.define "master" do |master| master.vm.box = "centos/7" master.vm.hostname = "Master" master.vm.network :private_network, ip: "192.168.11.11" master.ssh.insert_key = false config.vm.provider :virtualbox do |v| v.customize ["modifyvm", :id, "--memory", 2048] v.customize ["modifyvm", :id, "--cpus", 2] end end #VM2: Node1 config.vm.define "node1" do |node1| node1.vm.box = "centos/7" node1.vm.hostname = "Node1" node1.vm.network :private_network, ip: "192.168.11.12" node1.ssh.insert_key = false config.vm.provider :virtualbox do |v| v.customize ["modifyvm", :id, "--memory", 2048] v.customize ["modifyvm", :id, "--cpus", 2] end end #VM3: Node2 config.vm.define "node2" do |node2| node2.vm.box = "centos/7" node2.vm.hostname = "Node2" node2.vm.network :private_network, ip: "192.168.11.13" node2.ssh.insert_key = false config.vm.provider :virtualbox do |v| v.customize ["modifyvm", :id, "--memory", 2048] v.customize ["modifyvm", :id, "--cpus", 2] end end end
5. Bring up VMs. This command will spin VMs, setup two network interface 1) eth0:NAT and 2)eth1:host only with IP address provided in vagrantfile
$ vagrant up Bringing machine 'master' up with 'virtualbox' provider... Bringing machine 'node1' up with 'virtualbox' provider... Bringing machine 'node2' up with 'virtualbox' provider... ==> master: Importing base box 'centos/7'... ==> master: Matching MAC address for NAT networking... ==> master: Checking if box 'centos/7' is up to date... ==> master: Setting the name of the VM: kubernetes_master_1487800004247_23604 ==> master: Clearing any previously set network interfaces... ==> master: Preparing network interfaces based on configuration... master: Adapter 1: nat master: Adapter 2: hostonly ==> master: Forwarding ports... master: 22 (guest) => 2222 (host) (adapter 1) ==> master: Booting VM... ==> master: Waiting for machine to boot. This may take a few minutes... master: SSH address: 127.0.0.1:2222 master: SSH username: vagrant master: SSH auth method: private key master: master: Vagrant insecure key detected. Vagrant will automatically replace master: this with a newly generated keypair for better security. master: master: Inserting generated public key within guest... master: Removing insecure key from the guest if it's present... master: Key inserted! Disconnecting and reconnecting using new SSH key... ==> master: Machine booted and ready! ==> master: Checking for guest additions in VM... master: No guest additions were detected on the base box for this VM! Guest master: additions are required for forwarded ports, shared folders, host only master: networking, and more. If SSH fails on this machine, please install master: the guest additions and repackage the box to continue. master: master: This is not an error message; everything may continue to work properly, master: in which case you may ignore this message. ==> master: Setting hostname... ==> master: Configuring and enabling network interfaces... <--------> output truncated
6. Check VM status
//this command gives ssh port info for each VM $ vagrant ssh-config Host master HostName 127.0.0.1 User vagrant Port 2222 UserKnownHostsFile /dev/null StrictHostKeyChecking no PasswordAuthentication no IdentityFile /home/divine/vagrant/proj/kubernetes/.vagrant/machines/master/virtualbox/private_key IdentitiesOnly yes LogLevel FATAL Host node1 HostName 127.0.0.1 User vagrant Port 2200 UserKnownHostsFile /dev/null StrictHostKeyChecking no PasswordAuthentication no IdentityFile /home/divine/vagrant/proj/kubernetes/.vagrant/machines/node1/virtualbox/private_key IdentitiesOnly yes LogLevel FATAL Host node2 HostName 127.0.0.1 User vagrant Port 2201 UserKnownHostsFile /dev/null StrictHostKeyChecking no PasswordAuthentication no IdentityFile /home/divine/vagrant/proj/kubernetes/.vagrant/machines/node2/virtualbox/private_key IdentitiesOnly yes LogLevel FATAL $ vagrant status Current machine states: master running (virtualbox) node1 running (virtualbox) node2 running (virtualbox) This environment represents multiple VMs. The VMs are all listed above with their current state. For more information about a specific VM, run `vagrant status NAME`.
7. login to VMs do housekeeping and load packages. Below example of my master node
Note:The root password for vagrant box is vagrant
//ssh to Master node $vagrant ssh master //bring up eth1 interface by default eth1 is down [vagrant@Master ~]$ sudo ifup eth1 [vagrant@Master ~]$ ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 52:54:00:22:5b:53 brd ff:ff:ff:ff:ff:ff inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic eth0 valid_lft 74600sec preferred_lft 74600sec inet6 fe80::5054:ff:fe22:5b53/64 scope link valid_lft forever preferred_lft forever 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 08:00:27:f8:f1:21 brd ff:ff:ff:ff:ff:ff inet 192.168.11.11/24 brd 192.168.11.255 scope global eth1 valid_lft forever preferred_lft forever inet6 fe80::a00:27ff:fef8:f121/64 scope link valid_lft forever preferred_lft forever //load some useful packages {vagrant@Master ~]$ sudo yum update -y [vagrant@Master ~]$ sudo yum install net-tools [vagrant@Master ~]$ sudo yum install wget [vagrant@Master ~]$ sudo yum //setup ssh key [vagrant@Master ~]$ wget https://raw.githubusercontent.com/mitchellh/vagrant/master/keys/vagrant.pub -O .ssh/authorized_keys [vagrant@Master ~]$ chmod 700 .ssh [vagrant@Master ~]$ chmod 600 .ssh/authorized_keys [vagrant@Master ~]$ chown -R vagrant:vagrant .ssh
8. Package VMs into vagrant box. I will create 3 boxes named: Master, Node1 & Node2
//we need virtualbox name to create box, below command will provide virtualbox names $ ps -ef | grep virtualbox divine 366 19858 0 22:52 pts/2 00:00:00 grep --color=auto virtualbox divine 9630 1 0 19:29 ? 00:00:14 /usr/lib/virtualbox/VBoxXPCOMIPCD divine 9635 1 0 19:29 ? 00:00:39 /usr/lib/virtualbox/VBoxSVC --auto-shutdown divine 10449 9635 1 19:29 ? 00:02:01 /usr/lib/virtualbox/VBoxHeadless --comment kubernetes_master_1487800004247_23604 --startvm c2acbdc8-457a-40e3-ac21-fe151b886ca7 --vrde config divine 12633 9635 0 19:30 ? 00:01:52 /usr/lib/virtualbox/VBoxHeadless --comment kubernetes_node1_1487800067490_38506 --startvm 3bedc067-befc-4b81-9042-4a08c126ca45 --vrde config divine 14735 9635 0 19:30 ? 00:01:51 /usr/lib/virtualbox/VBoxHeadless --comment kubernetes_node2_1487800127574_14083 --startvm cb10ab77-0940-4243-b01b-9ce2e3fcf2af --vrde config //create box $ vagrant package --base kubernetes_master_1487800004247_23604 --output Master --vagrantfile Vagrantfile $ vagrant package --base kubernetes_node1_1487800067490_38506 --output Node1 --vagrantfile Vagrantfile $ vagrant package --base kubernetes_node2_1487800127574_14083 --output Node2 --vagrantfile Vagrantfile $ ls Master Node1 Node2 Vagrantfile
9.Now that I have created my boxes. I will destroy current VMs
$vagrant destroy
10. The last step is to modify vagrantfile to use my newly minted boxes. The change is in vm.box parameter, instead of centos/7 I am providing my boxes name
$ cat Vagrantfile Vagrant.configure("2") do |config| #VM1: Master config.vm.define "master" do |master| master.vm.box = "Master" master.vm.hostname = "Master" master.vm.network :private_network, ip: "192.168.11.11" master.ssh.insert_key = false config.vm.provider :virtualbox do |v| v.customize ["modifyvm", :id, "--memory", 2048] v.customize ["modifyvm", :id, "--cpus", 2] end end #VM2: Node1 config.vm.define "node1" do |node1| node1.vm.box = "Node1" node1.vm.hostname = "Node1" node1.vm.network :private_network, ip: "192.168.11.12" node1.ssh.insert_key = false config.vm.provider :virtualbox do |v| v.customize ["modifyvm", :id, "--memory", 2048] v.customize ["modifyvm", :id, "--cpus", 2] end end #VM3: Node2 config.vm.define "node2" do |node2| node2.vm.box = "Node2" node2.vm.hostname = "Node2" node2.vm.network :private_network, ip: "192.168.11.13" node2.ssh.insert_key = false config.vm.provider :virtualbox do |v| v.customize ["modifyvm", :id, "--memory", 2048] v.customize ["modifyvm", :id, "--cpus", 2] end end end