AKAI TSUKI

System development or Technical something

KVM with cloud-init

CentOS 8 VM Image

I get CentOS 8 VM Image.

[root@pm01 images]# wget https://cloud.centos.org/centos/8/x86_64/images/CentOS-8-GenericCloud-8.2.2004-20200611.2.x86_64.qcow2
[root@pm01 ~]# qemu-img info images/CentOS-8-GenericCloud-8.2.2004-20200611.2.x86_64.qcow2
image: images/CentOS-8-GenericCloud-8.2.2004-20200611.2.x86_64.qcow2
file format: qcow2
virtual size: 10G (10737418240 bytes)
disk size: 1.1G
cluster_size: 65536
Format specific information:
    compat: 0.10
[root@pm01 ~]#
[root@pm01 ~]# cp -vp images/CentOS-8-GenericCloud-8.2.2004-20200611.2.x86_64.qcow2 /var/lib/libvirt/images/vm05.qcow2
‘images/CentOS-8-GenericCloud-8.2.2004-20200611.2.x86_64.qcow2’ -> ‘/var/lib/libvirt/images/vm05.qcow2’
[root@pm01 ~]#

I resize VM Image from 10G to 20G.

[root@pm01 ~]# cd /var/lib/libvirt/images/
[root@pm01 images]# qemu-img resize vm05.qcow2 20G
Image resized.
[root@pm01 images]#

prepare for cloud-init

I get hashed pass by python command like below.

[root@pm01 images]# python -c 'import crypt,getpass; print(crypt.crypt(getpass.getpass(), crypt.mksalt(crypt.METHOD_SHA512)))'
Password: <input password>
<hashed pass>
[root@pm01 images]#

I create cloud-confg file.
This file makes hostname "testnode" and creates "centos" user in a VM.

[root@pm01 images]# vi config.yaml
[root@pm01 images]# cat config.yaml
#cloud-config
fqdn: testnode
users:
  - name: centos
    groups: wheel
    lock_passwd: false
    passwd: '<hashed pass>'
    shell: /bin/bash
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
[root@pm01 images]#
[root@pm01 images]# yum install -y cloud-utils

 *snip*

Installed:
  cloud-utils.x86_64 0:0.27-20.el7.centos

Dependency Installed:
  cloud-utils-growpart.noarch 0:0.29-5.el7 euca2ools.noarch 0:3.4.1-1.el7 python-lxml.x86_64 0:3.2.1-4.el7 python-progressbar.noarch 0:2.3-4.el7 python-requestbuilder.noarch 0:0.7.1-1.el7
  rsync.x86_64 0:3.1.2-10.el7

Complete!
[root@pm01 images]#

I generate config.iso file by cloud-localds command.

[root@pm01 images]# cloud-localds config.iso config.yaml
wrote config.iso with filesystem=iso9660 and diskformat=raw
[root@pm01 images]#

Unfortunantly, I could not find "CentOS 8".

[root@pm01 images]# osinfo-query  os | grep -i centos
 centos5.0            | CentOS 5.0                                         | 5.0      | http://centos.org/centos/5.0
 centos5.1            | CentOS 5.1                                         | 5.1      | http://centos.org/centos/5.1
 centos5.10           | CentOS 5.10                                        | 5.10     | http://centos.org/centos/5.10
 centos5.11           | CentOS 5.11                                        | 5.11     | http://centos.org/centos/5.11
 centos5.2            | CentOS 5.2                                         | 5.2      | http://centos.org/centos/5.2
 centos5.3            | CentOS 5.3                                         | 5.3      | http://centos.org/centos/5.3
 centos5.4            | CentOS 5.4                                         | 5.4      | http://centos.org/centos/5.4
 centos5.5            | CentOS 5.5                                         | 5.5      | http://centos.org/centos/5.5
 centos5.6            | CentOS 5.6                                         | 5.6      | http://centos.org/centos/5.6
 centos5.7            | CentOS 5.7                                         | 5.7      | http://centos.org/centos/5.7
 centos5.8            | CentOS 5.8                                         | 5.8      | http://centos.org/centos/5.8
 centos5.9            | CentOS 5.9                                         | 5.9      | http://centos.org/centos/5.9
 centos6.0            | CentOS 6.0                                         | 6.0      | http://centos.org/centos/6.0
 centos6.1            | CentOS 6.1                                         | 6.1      | http://centos.org/centos/6.1
 centos6.10           | CentOS 6.10                                        | 6.10     | http://centos.org/centos/6.10
 centos6.2            | CentOS 6.2                                         | 6.2      | http://centos.org/centos/6.2
 centos6.3            | CentOS 6.3                                         | 6.3      | http://centos.org/centos/6.3
 centos6.4            | CentOS 6.4                                         | 6.4      | http://centos.org/centos/6.4
 centos6.5            | CentOS 6.5                                         | 6.5      | http://centos.org/centos/6.5
 centos6.6            | CentOS 6.6                                         | 6.6      | http://centos.org/centos/6.6
 centos6.7            | CentOS 6.7                                         | 6.7      | http://centos.org/centos/6.7
 centos6.8            | CentOS 6.8                                         | 6.8      | http://centos.org/centos/6.8
 centos6.9            | CentOS 6.9                                         | 6.9      | http://centos.org/centos/6.9
 centos7.0            | CentOS 7                                           | 7        | http://centos.org/centos/7.0
[root@pm01 images]#

Excute command(virt-install) to create CentOS 8 with cloud-init on KVM.

I use above all information.
and then I prepare script file to create VM.

[root@pm01 kvm_work]# vi create_vm05.sh
[root@pm01 kvm_work]#
[root@pm01 kvm_work]# cat create_vm05.sh
#!/bin/bash

name=vm05
cpu=1
memory=4096
# disk=30

# cd /var/lib/libvirt/images/
# cp -vp CentOS-8-GenericCloud-8.2.2004-20200611.2.x86_64.qcow2 ${name}.qcow2
# qemu-img resize ${name}.qcow2 ${disk}G

virt-install \
 --name=${name} \
 --disk /var/lib/libvirt/images/${name}.qcow2,device=disk \
 --disk /var/lib/libvirt/images/config.iso,device=cdrom \
 --network network=default,model=virtio \
 --vcpus=${cpu} \
 --ram=${memory} \
 --accelerate \
 --hvm \
 --virt-type kvm \
 --graphics none \
 --os-type Linux \
 --arch=x86_64 \
 --import

[root@pm01 kvm_work]#

Finally, CentOS 8 VM was created by cloud-init with cloud config on KVM.
and I can log in to this VM.

[root@pm01 kvm_work]# bash create_vm05.sh
 *snip*

CentOS Linux 8 (Core)
Kernel 4.18.0-193.6.3.el8_2.x86_64 on an x86_64

Activate the web console with: systemctl enable --now cockpit.socket

testnode login: centos
Password:
[centos@testnode ~]$ id
uid=1000(centos) gid=1000(centos) groups=1000(centos),10(wheel) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[centos@testnode ~]$

build and install tmux 3.1b on CentOS 7.

github.com

install some packages "Run Packages" and "Build Packages"

[root@vm02 ~]# yum install libevent ncurses libevent-devel ncurses-devel gcc make bison pkg-config

*snip*

Installed:
  bison.x86_64 0:3.0.4-2.el7             gcc.x86_64 0:4.8.5-39.el7                      libevent.x86_64 0:2.0.21-4.el7
  libevent-devel.x86_64 0:2.0.21-4.el7   ncurses-devel.x86_64 0:5.9-14.20130511.el7_4

Dependency Installed:
  cpp.x86_64 0:4.8.5-39.el7                   glibc-devel.x86_64 0:2.17-307.el7.1 glibc-headers.x86_64 0:2.17-307.el7.1
  kernel-headers.x86_64 0:3.10.0-1127.8.2.el7 libmpc.x86_64 0:1.0.1-3.el7         m4.x86_64 0:1.4.16-10.el7
  mpfr.x86_64 0:3.1.1-4.el7

Dependency Updated:
  glibc.x86_64 0:2.17-307.el7.1                           glibc-common.x86_64 0:2.17-307.el7.1

Complete!
[root@vm02 ~]#

make and make install

[root@vm02 ~]# wget https://github.com/tmux/tmux/releases/download/3.1b/tmux-3.1b.tar.gz
[root@vm02 ~]# ls -l tmux-3.1b.tar.gz
-rw-r--r-- 1 root root 561152 May  4 17:10 tmux-3.1b.tar.gz
[root@vm02 ~]#

[root@vm02 ~]# tar -zxf tmux-3.1b.tar.gz
[root@vm02 ~]#

[root@vm02 ~]# cd tmux-3.1b
-rwxr-xr-x 1 1000 1000 239664 May  4 17:08 configure
[root@vm02 tmux-3.1b]# ./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /usr/bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking whether gcc understands -c and -o together... yes
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
checking for gcc option to accept ISO C99... -std=gnu99
checking how to run the C preprocessor... gcc -std=gnu99 -E
checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking for bison... bison -y
checking for pkg-config... /usr/bin/pkg-config
checking pkg-config is at least version 0.9.0... yes
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking minix/config.h usability... no
checking minix/config.h presence... no
checking for minix/config.h... no
checking whether it is safe to define __EXTENSIONS__... yes
checking bitstring.h usability... no
checking bitstring.h presence... no
checking for bitstring.h... no
checking dirent.h usability... yes
checking dirent.h presence... yes
checking for dirent.h... yes
checking fcntl.h usability... yes
checking fcntl.h presence... yes
checking for fcntl.h... yes
checking for inttypes.h... (cached) yes
checking libutil.h usability... no
checking libutil.h presence... no
checking for libutil.h... no
checking ndir.h usability... no
checking ndir.h presence... no
checking for ndir.h... no
checking paths.h usability... yes
checking paths.h presence... yes
checking for paths.h... yes
checking pty.h usability... yes
checking pty.h presence... yes
checking for pty.h... yes
checking for stdint.h... (cached) yes
checking sys/dir.h usability... yes
checking sys/dir.h presence... yes
checking for sys/dir.h... yes
checking sys/ndir.h usability... no
checking sys/ndir.h presence... no
checking for sys/ndir.h... no
checking sys/tree.h usability... no
checking sys/tree.h presence... no
checking for sys/tree.h... no
checking util.h usability... no
checking util.h presence... no
checking for util.h... no
checking for library containing flock... none required
checking for dirfd... yes
checking for flock... yes
checking for prctl... yes
checking for sysconf... yes
checking for asprintf... yes
checking for cfmakeraw... yes
checking for closefrom... no
checking for explicit_bzero... no
checking for fgetln... no
checking for freezero... no
checking for getdtablecount... no
checking for getprogname... no
checking for memmem... yes
checking for recallocarray... no
checking for reallocarray... no
checking for setenv... yes
checking for setproctitle... no
checking for strcasestr... yes
checking for strlcat... no
checking for strlcpy... no
checking for strndup... yes
checking for strsep... yes
checking for strtonum... no
checking for working strnlen... yes
checking for library containing clock_gettime... none required
checking for LIBEVENT... yes
checking event.h usability... yes
checking event.h presence... yes
checking for event.h... yes
checking for LIBTINFO... yes
checking for b64_ntop... no
checking for b64_ntop with -lresolv... yes
checking for library containing inet_ntoa... none required
checking for library containing socket... none required
checking for socket in -lxnet... no
checking for CMSG_DATA... yes
checking for err... yes
checking for errx... yes
checking for warn... yes
checking for warnx... yes
checking err.h usability... yes
checking err.h presence... yes
checking for err.h... yes
checking for library containing imsg_init... no
checking for daemon... yes
checking whether daemon is declared... yes
checking for stravis... no
checking for library containing fdforkpty... no
checking for library containing forkpty... -lutil
checking for library containing kinfo_getfile... no
checking whether TAILQ_CONCAT is declared... yes
checking whether TAILQ_PREV is declared... yes
checking whether TAILQ_REPLACE is declared... no
checking for __progname... yes
checking for program_invocation_short_name... yes
checking whether PR_SET_NAME is declared... yes
checking whether F_CLOSEM is declared... no
checking for /proc/$$... yes
checking platform... linux
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: executing depfiles commands
[root@vm02 tmux-3.1b]#

execute "make" and "make install" command

[root@vm02 tmux-3.1b]# make

*snip*

[root@vm02 tmux-3.1b]# make install
make[1]: Entering directory `/root/tmux-3.1b'
 /usr/bin/mkdir -p '/usr/local/bin'
  /usr/bin/install -c tmux '/usr/local/bin'
make  install-exec-hook
make[2]: Entering directory `/root/tmux-3.1b'
if test xmdoc = xmdoc; then \
        sed -e "s|@SYSCONFDIR@|/etc|g" ./tmux.1 \
                >./tmux.1.mdoc; \
else \
        sed -e "s|@SYSCONFDIR@|/etc|g" ./tmux.1| \
                gawk -f ./mdoc2man.awk >./tmux.1.man; \
fi
/usr/bin/mkdir -p /usr/local/share/man/man1
/usr/bin/install -c -m 644 ./tmux.1.mdoc \
        /usr/local/share/man/man1/tmux.1
make[2]: Leaving directory `/root/tmux-3.1b'
make[1]: Nothing to be done for `install-data-am'.
make[1]: Leaving directory `/root/tmux-3.1b'
[root@vm02 tmux-3.1b]#

check version

[root@vm02 tmux-3.1b]# tmux -V
tmux 3.1b
[root@vm02 tmux-3.1b]#

Create a new VM in CentOS 7.x(KVM)

create Hash Password

1) execute below command and input root's Password

[root@pm01 ~]# python -c 'import crypt,getpass; pw=getpass.getpass(); print(crypt.crypt(pw) if (pw==getpass.getpass("Re-Password: ")) else exit())'
Password: <<input password>>
Re-Password: <<re-input password>>
<<can see Hash password>>
[root@pm01 ~]#

kickstart config file

1) creat kickstart config file
2) change "< Hash root's Password >" to actual hash password

[root@pm01 ~]# cat vm03.ks
#version=DEVEL

# Use CDROM installation media
cdrom

# Use text install
text
cmdline
skipx

# # Run the Setup Agent on first boot
# firstboot --enable
ignoredisk --only-use=vda

# Keyboard layouts
keyboard --vckeymap=jp --xlayouts='jp','us'
# System language
lang en_US.UTF-8

# Network information
network  --bootproto=dhcp --device=eth0 --onboot=on --noipv6 --activate
# network  --bootproto=static --device=eth0 --ip=192.168.122.102 --netmask=255.255.255.0 --gateway=192.168.122.1 --nameserver=192.168.122.1 --noipv6 --activate
# network  --bootproto=dhcp --device=eth0 --onboot=on --activate
network  --hostname=vm03.localdomain

# System authorization information
auth --enableshadow --passalgo=sha512
# Root password
rootpw --iscrypted < Hash root's Password >

# # System services
# services --disabled="chronyd"

# System timezone
timezone Asia/Tokyo --isUtc --nontp


# System bootloader configuration
bootloader --append=" crashkernel=auto" --location=mbr --boot-drive=vda
autopart --type=lvm
# Partition clearing information
clearpart --all --initlabel --drives=vda

selinux --disabled

%packages
@^minimal
@core
kexec-tools

%end

%addon com_redhat_kdump --enable --reserve-mb='auto'

%end

reboot --eject
[root@pm01 ~]#

execute script for virt-install

1) create script file using virt-install

[root@pm01 ~]# cat create_vm03.sh
#!/bin/bash

name=vm03
cpu=1
memory=4096
disk=30

qemu-img create -f qcow2 /var/lib/libvirt/images/${name}.qcow2 ${disk}G

# virt-install --connect=qemu:///system \
virt-install \
 --name=${name} \
 --disk /var/lib/libvirt/images/${name}.qcow2,format=qcow2,bus=virtio \
 --network network=default,model=virtio \
 --initrd-inject=./${name}.ks \
 --extra-args="ks=file:/${name}.ks biosdevname=0 net.ifnames=0 console=tty0 console=ttyS0,115200n8" \
 --vcpus=${cpu} \
 --ram=${memory} \
 --accelerate \
 --hvm \
 --virt-type kvm \
 --location='/var/lib/libvirt/images/CentOS-7-x86_64-Minimal-1908.iso' \
 --nographics \
 --os-type=linux \
 --os-variant=centos7.0 \
 --arch=x86_64

[root@pm01 ~]#

2) start to create a new VM by below command

[root@pm01 ~]# sh create_vm03.sh

try to use hash in Bash

This is sample script.

[root@pm01 ~]# cat get_log.sh
#!/bin/bash

nodes=(
vm01
vm02
vm03
)

declare -A IP_ADDRESSES;
IP_ADDRESSES=(
  ["vm01"]="192.168.122.62"
  ["vm02"]="192.168.122.68"
  ["vm03"]="192.168.122.12"
  ["vm04"]="192.168.122.11"
)

declare -A PORTS;
PORTS=(
  ["vm01"]="10021"
  ["vm02"]="10022"
  ["vm03"]="10023"
  ["vm04"]="10024"
)

cnt=0
for node in "${nodes[@]}"
do
    echo "$cnt => $node"
    echo ${IP_ADDRESSES[${node}]}
    echo ${PORTS[${node}]}
    echo ""
    let cnt++
done

[root@pm01 ~]#

Try to execute this script.

[root@pm01 ~]# sh get_log.sh
0 => vm01
192.168.122.62
10021

1 => vm02
192.168.122.68
10022

2 => vm03
192.168.122.12
10023

[root@pm01 ~]#

for loop sample by Bash

try loop sample

[root@pm01 ~]# sh get_log.sh
0 => vm01
1 => vm02
2 => vm03
[root@pm01 ~]#
[root@pm01 ~]# cat get_log.sh
#!/bin/bash

nodes=(
vm01
vm02
vm03
)


cnt=0
for node in "${nodes[@]}"
do
    echo "$cnt => $node"
    let cnt++
done


[root@pm01 ~]#

try dnsmasq

Install Dnsmasq

[root@cent7devops ~]# yum -y install dnsmasq

initial state after yum install

[root@cent7devops ~]# grep -v -e "^#.*" -e "^$" /etc/dnsmasq.conf
conf-dir=/etc/dnsmasq.d,.rpmnew,.rpmsave,.rpmorig
[root@cent7devops ~]#
[root@cent7devops ~]# systemctl status dnsmasq
● dnsmasq.service - DNS caching server.
   Loaded: loaded (/usr/lib/systemd/system/dnsmasq.service; disabled; vendor preset: disabled)
   Active: inactive (dead)
[root@cent7devops ~]#
[root@cent7devops ~]# ls -l /etc/dnsmasq.conf
-rw-r--r-- 1 root root 26832 Apr 11 09:53 /etc/dnsmasq.conf
[root@cent7devops ~]#
[root@cent7devops ~]# ls -l /etc/dnsmasq.d/
total 0
[root@cent7devops ~]#

Configure 'dnsmasq.conf' and hosts file

[root@cent7devops ~]# diff /etc/dnsmasq.conf /etc/dnsmasq.conf.org
19c19
< domain-needed
---
> #domain-needed
21c21
< bogus-priv
---
> #bogus-priv
53c53
< strict-order
---
> #strict-order
[root@cent7devops ~]#
[root@cent7devops ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
172.16.10.111 gitlab.node01.devlocal node01
172.16.10.112 node02.devlocal node02
172.16.10.113 node03.devlocal node03
172.16.10.90 devops.devlocal devops
[root@cent7devops ~]#

and Start Dnsmasq

[root@cent7devops ~]# systemctl start dnsmasq
[root@cent7devops ~]#
[root@cent7devops ~]# systemctl is-active dnsmasq
active
[root@cent7devops ~]#

operation check

confirm to access Dnsmasq. In this case, "172.16.10.90" is the IP Address of server running Dnsmasq.

[root@localhost ~]# nmcli -t -f ipv4.dns c s enp0s3
ipv4.dns:172.16.10.90
[root@localhost ~]#

[root@localhost ~]# cat /etc/resolv.conf
# Generated by NetworkManager
nameserver 172.16.10.90
[root@localhost ~]#

The hosts file in server for test have only localhost.

[root@localhost ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
[root@localhost ~]#

Try to execute dig command.

[root@localhost ~]# dig node02 +noall +answer

; <<>> DiG 9.9.4-RedHat-9.9.4-61.el7_5.1 <<>> node02 +noall +answer
;; global options: +cmd
node02.                 0       IN      A       172.16.10.112
[root@localhost ~]#
[root@localhost ~]# dig node03 +short
172.16.10.113
[root@localhost ~]#