highlight.js

Thursday, December 22, 2016

Moving virtual machine from oVirt (or KVM base) to ESXi

Introduction:

These configuration steps are about the migration of the virtual machine from oVirt or KVM based to ESXi with qemu-img command.

Related Posts:


Environment:

  ESXi: ESXi 6.0 Update 2 Build 3620759
  oVirt(engine and node): 4.0.4
  qemu-img: qemu-img-1.5.3-105.el7.x86_64

Configuration Summary:

This configuration steps assume that 5 servers are existing as follows (It's helpful to reading the related post):
  • esxi.host.local: ESXi hypervisor host. (ESXi 6.0 U2)
  • ovirt.host.local: oVirt hypervisor host. (oVirt node 4.0.4)
  • nfs.host.local: NFS server for the oVirt Export/Import Storage Domain (':/nfs/shares' is exported shares path) (CentOS 7.2)
  • conv.host.local: one server for converting the VM image from ESXi format to oVirt format with qemu-img. (CentOS 7.2)
  • guest.vmhost.local: The guest virtual machine for moving to ESXi. (CentOS 7.2)
In practice any one server can have mutiple roles such as nfs and converting vm image roles can be together on the one server.
I think that the servers just separated by roles are more helpful for understanding and appyling your enviroments.

The process flow across all the servers as follows (Figure 1):

Configuration steps:

We assume that moving guest VM(guest.vmhost.local) is existing on the oVirt host server before working for the migration tasks.
The moving target ESXi host server need to enable the SSH server service and open the SSH client port in advance.

Step1: Export the guest VM from oVirt to Export Storage Domain NFS server.

First the moving VM guest server should shutdown before export the VM.
You remember the VM DISK image UUID from 'Disks' tag to search the correct image file for converting. (The UUID is 57b5bf87-4bee-42ab-8910-f7e93419e0dc through this post.)
Select the stopped VM in the 'Virtual Machines' tag and click the 'Export' link.
And then the dialog window appeared for Export process you can complete the tasks according to the instructions on the dialog.

The following image for supplementary explanation.

Step2: Convert the guest VM's image file to VMDK(Virtual Machine Disk) format.

The 'conv.host.local' server should mount the 'nfs.host.local' NFS server without permission problems.

There is a directory tree for the Export Storage NFS Domain. (reference link at the RHEV manual)

|-- [ Export Storage Domain UUID ] |-- images | |-- [ Exported virtual machine DISK image UUID] | |--- [ Exported image UUID ] | |--- [ Exported image UUID ].meta |-- master |---vms |--- [Arbitrary UUID] |--- [Arbitrary UUID].ovf
It's the real directory tree at this task step.
You can verify the image file identity from OVF xml file and you can convert the correct raw image file without making mistakes.

[conv ]# mount -t nfs nfs.host.local:/nfs/shares /mnt
[conv ]# ls -l /mnt
/mnt |-- b068bd53-60f2-4270-8257-0bc962de834f |-- images | |-- 57b5bf87-4bee-42ab-8910-f7e93419e0dc | |--- deb5a3fd-a818-4d6a-82cf-e566756c37b8 | |--- deb5a3fd-a818-4d6a-82cf-e566756c37b8.meta |-- master |---vms |--- 480d5d47-e6e6-487f-95c3-286c3ad21fec |--- 480d5d47-e6e6-487f-95c3-286c3ad21fec.ovf ...snip...
[conv ]# cat /mnt/b068bd53-60f2-4270-8257-0bc962de834f/master/vms/480d5d47-e6e6-487f-95c3-286c3ad21fec/480d5d47-e6e6-487f-95c3-286c3ad21fec.ovf | xmllint --format - | grep File
<File ovf:href="57b5bf87-4bee-42ab-8910-f7e93419e0dc/deb5a3fd-a818-4d6a-82cf-e566756c37b8" ovf:id="deb5a3fd-a818-4d6a-82cf-e566756c37b8" ovf:size="17179869184" ovf:description="Active VM" ovf:disk_storage_type="IMAGE" ovf:cinder_volume_type=""/>
[conv ]# cd /mnt//b068bd53-60f2-4270-8257-0bc962de834f/images/57b5bf87-4bee-42ab-8910-f7e93419e0dc [conv ]# cat ./deb5a3fd-a818-4d6a-82cf-e566756c37b8.meta
DOMAIN=b068bd53-60f2-4270-8257-0bc962de834f CTIME=1482389127 FORMAT=RAW DISKTYPE=1 LEGALITY=LEGAL SIZE=33554432 VOLTYPE=LEAF DESCRIPTION= IMAGE=57b5bf87-4bee-42ab-8910-f7e93419e0dc PUUID=00000000-0000-0000-0000-000000000000 MTIME=0 POOL_UUID= TYPE=SPARSE EOF
[conv ]# qemu-img info ./deb5a3fd-a818-4d6a-82cf-e566756c37b8
image: ./deb5a3fd-a818-4d6a-82cf-e566756c37b8 file format: raw virtual size: 16G (17179869184 bytes) disk size: 1.0G
[conv ]#
It's the coverting command with qemu-img as follows: (The options details are referenced by -h or simply executing without no switches.)

[conv ]# qemu-img convert -p ./deb5a3fd-a818-4d6a-82cf-e566756c37b8 -O vmdk /mnt/guest.vmhost.local.vmdk
(100.00/100%)
[conv ]#

Step3: Converting the vmdk file to ESXi main data store as the compatiable format.

I remind you one more the prerequisites for this tasks.
You need to add the Export NFS Storage Domain as additional storage on the ESXi host server through vSphere client console. (look below the image.)
And you should do not only starting the SSH server service but also open the SSH client port with FW configuration.

The following commands will be executing on the ESXi host server through SSH terminal.

First, create the directory for deploy the converted the vmdk file having compatible to ESXi.

login as: root
Using keyboard-interactive authentication.
Password:
The time and date of this login have been sent to the system logs. VMware offers supported, powerful system administration tools. Please see www.vmware.com/go/sysadmintools for details. The ESXi Shell can be disabled by an administrative user. See the vSphere Security documentation for more information.
[root@esxi:~] mkdir /vmfs/volumes/datastore1/guest.vmhost.local.disk [root@esxi:~]

In succession we convert the vmdk format file from the oVirt to ESXi compatible vmdk image file as the VMFS thin-provisioned format.
(vmkfstools reference link)

[root@esxi:~] vmkfstools -i /vmfs/volumes/nfs_store/guest.vmhost.local.vmdk \
                                   /vmfs/volumes/datastore1/guest.vmhost.local.disk/guest.vmhost.local.vmdk -d thin
Destination disk format: VMFS thin-provisioned Cloning disk '/vmfs/volumes/nfs_store/guest.vmhost.local.vmdk'... Clone: 100% done.
[root@esxi:~]

Step4: Register the virtual machine with converted vmdk image file.

The last step for the VM migration from oVirt to ESXi is registering the ESXi guest virtual machine with same name attached converted vmdk image file.

Create new virtual machine attached the converted vmdk image with same name as follows:
Let's check the moved virtual machine from oVirt to ESXi.


Moving virtual machine from ESXi to oVirt

Introduction:

There are the configuration sequences for the virtual machine migration from ESXi to oVirt(upstream for RHEV) with virt-v2v command.

Related Posts:


Environment:

  ESXi: ESXi 6.0 Update 2 Build 3620759
  oVirt(engine and node): 4.0.4
  virt-v2v: virt-v2v-1.28.1-1.55.el7.x86_64

Configuration Summary:

This configuration steps assume that 5 servers are existing as follows:
  • esxi.host.local: ESXi hypervisor host. (ESXi 6.0 U2)
  • ovirt.host.local: oVirt hypervisor host. (oVirt node 4.0.4)
  • nfs.host.local: NFS server for the oVirt Export/Import Storage Domain (':/nfs/shares' is exported shares path) (CentOS 7.2)
  • conv.host.local: one server for converting the VM image from ESXi format to oVirt format with virt-v2v. (CentOS 7.2)
  • guest.vmhost.local: The guest virtual machine for moving to oVirt. (CentOS 7.2)

In practice any one server can have mutiple roles such as nfs and converting vm image roles can be together on the one server.
I think that the servers just separated by roles are more helpful for understanding and appyling your enviroments.

The process flow across all the servers as follows(Figure 1):

Configuration steps:

In advance the virtual machine should instatall minimally as a guest OS to ESXi because it can minimize the converting process time at this demonstration. At real work you would take account of the target virtual machine size because of the processing time.

Step1: Export the virtual machine from ESXi with vSphere management console.

The target guest VM should be stopped to export to OVA file.

The operation example is as follows on the vSphere client.
The exported OVA file is named 'guest.vmhost.local.ova' as default if the export task has completed.
And then we should transfer the OVA file to the 'conv.host.local' server to convert the OVA file to oVirt format.

Step2: Convert and transfer the guest VM to oVirt Export Storage Domain.

You might be encountered the following errors while convert processing with virt-v2v.

Common error1: It's a permission error if you process as root account.
virt-v2v: error: libguestfs error: could not create appliance through libvirt. Try running qemu directly without libvirt using this environment variable: export LIBGUESTFS_BACKEND=direct Original error from libvirt: Cannot access backing file '/var/tmp/ova.vuHiQ6/guest.vmhost.local-disk1.vmdk' of storage file '/var/tmp/v2vovl67af1b.qcow2' (as uid:107, gid:107): Permission denied [code=38 domain=18] If reporting bugs, run virt-v2v with debugging enabled and include the complete output: virt-v2v -v -x [...]
This error is caused by using libvirt backend as 'qemu' account (detailed reference link). I recommend directly processing the converting as root account without libvirtd bacause it can avoid the errors about permission around libvirt, if your environment is allowed using root account to convert the VM.
It specify the 'LIBGUESTFS_BACKEND=direct' to process the task directly without libvirtd.
# LIBGUESTFS_BACKEND=direct virt-v2v -i ova ./guest.vmhost.local.ova ...snip...

Common error2: The NFS access permission error.
virt-v2v: error: mount command failed, see earlier errors. This probably means you didn't specify the right Export Storage Domain path [-os nfs.host.local:/nfs/shares], or else you need to rerun virt-v2v as root. If reporting bugs, run virt-v2v with debugging enabled and include the complete output: virt-v2v -v -x [...]
This error is caused by not adding the 'conv.host.local' server to NFS access allowed list.
You should allow the 'conv.host.local' server to be accessible to 'nfs.host.local' NFS server before converting.

I started executing the 'virt-v2v' command with the following options. (options reference link)

[conv ]# LIBGUESTFS_BACKEND=direct virt-v2v -i ova ./guest.vmhost.local.ova \
                                            -o rhev -of qcow2 -os nfs.host.local:/nfs/shares -v -x
virt-v2v: libguestfs 1.28.1 (x86_64) [ 0.0] Opening the source -i ova ./guest.vmhost.local.ova tar -xf './guest.vmhost.local.ova' -C '/var/tmp/ova.ZflJ8V' source name: guest.vmhost.local hypervisor type: vmware memory: 2147483648 (bytes) nr vCPUs: 2 CPU features: firmware: bios display: sound: ...snip... [ 116.0] Creating output metadata [ 116.0] Finishing off umount '/tmp/v2v.TZcelY' OVF: <ovf:envelope ovf:version="0.9" xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1/" xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData" xmlns:vssd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <references> <file ovf:description="Exported by virt-v2v 1.28.1" ovf:href="25534d4f-d07d-459d-a9ef-3ed733cbcdef/90b62105-4ae8-4a4b-826b-dfe970ae28d9" ovf:id="90b62105-4ae8-4a4b-826b-dfe970ae28d9" ovf:size="17179869184"> </file></references> </ovf:envelope> <section xsi:type="ovf:NetworkSection_Type"> <info>List of networks</info> <network ovf:name="Ethernet 1"> </network></section> <section xsi:type="ovf:DiskSection_Type"> <info>List of Virtual Disks</info> <disk ovf:actual_size="2" ovf:boot="True" ovf:disk-interface="VirtIO" ovf:disk-type="System" ovf:diskid="90b62105-4ae8-4a4b-826b-dfe970ae28d9" ovf:fileref="25534d4f-d07d-459d-a9ef-3ed733cbcdef/90b62105-4ae8-4a4b-826b-dfe970ae28d9" ovf:format="http://en.wikipedia.org/wiki/Byte" ovf:parentref="" ovf:size="16" ovf:vm_snapshot_id="61569757-5a3d-4342-b470-6dd174d8edab" ovf:volume-format="COW" ovf:volume-type="Sparse"> </disk></section> <content ovf:id="out" xsi:type="ovf:VirtualSystem_Type"> <name>guest.vmhost.local</name> <templateid>00000000-0000-0000-0000-000000000000</templateid> <templatename>Blank</templatename> ...snip... <rasd:instanceid>3de59667-835c-41cf-b3dc-a00684e3a4e2</rasd:instanceid> <rasd:caption>Ethernet adapter on Ethernet 1</rasd:caption> <rasd:resourcetype>10</rasd:resourcetype> <rasd:resourcesubtype>3</rasd:resourcesubtype> <type>interface</type> <rasd:connection>Ethernet 1</rasd:connection> <rasd:name>eth0</rasd:name> </content>
[conv ]#

Step3: Import the VM on the Export Storage Domain to the oVirt.

Lastly we import the VM into oVirt with oVrit web management console and startup the VM as guest virtual machine.
We would log into the oVirt web console and then click the 'Storage' tag, you can see your Export NFS Storage Domain.
It would appear the details below the window after selecting the Export Storage Domain.
Click the 'Import' sub tags, I'll be represented the dialog about Import details menu.
You can Import with optional details (such as DISK allocation method and so on) the VM through the dialog.

It's the image about above process flows.

Addtionally you might configure the VM about installing agent package, networking setup and so on.

Monday, December 12, 2016

The usage of targetcli command for iSCSI target configurations.

Introduction:

As of RHEL7/CentOS7, the iSCSI target configuration sequences were changed, so I note that configurations here.

Environment:

  OS: CentOS 7.2.1511
  Packages: targetcli-2.1.fb41-3.el7.noarch (for target configuration)
            iscsi-initiator-utils-6.2.0.873-33.el7_2.2.x86_64 (for initiator configuration)

Configuration steps:

We are going to describe about the target configuration ,and then subsequently the initiator configurations on the other server.

We assume the target configurations are with two virtual disks(1GB) and 1 image file(1GB).

Step1: The prerequisite tasks for the target configuration.

The iSCSI stand for Internet Small Computer System Interface, the target serve the storage device over the network.
The target meaning like a server on the server-client model.

It'll be enabled and started

# systemctl is-enabled target.service
disabled
# systemctl enable target.service
Created symlink from /etc/systemd/system/multi-user.target.wants/target.service to /usr/lib/systemd/system/target.service.
# systemctl start target # firewall-cmd --permanent --add-service=iscsi-target
success
# firewall-cmd --reload
success

Step2: the target main configurations with targetcli command.

We are going to configure the target by tergetcli based on the interactive mode.
It is the sequences of the target configuraion as follows:
  • Create backend storage object.
  • Define the IQN(iSCSI Qualified Name).
  • Define the Portal meta data.(Listen IP and port)
  • Specify the ACL.
The targetcli have the virtual directory tree that have the target components by hierarchy.
The 'ls' command in the targetcli can list the configurations data at that layers such like bash 'ls' command.

It's the inital output that have no configurations about the target as follows:

# targetcli
targetcli shell version 2.1.fb41 Copyright 2011-2013 by Datera, Inc and others. For help on commands, type 'help'. /> ls o- / ............................................................ [...] o- backstores ................................................. [...] | o- block ..................................... [Storage Objects: 0] | o- fileio .................................... [Storage Objects: 0] | o- pscsi ..................................... [Storage Objects: 0] | o- ramdisk ................................... [Storage Objects: 0] o- iscsi ............................................... [Targets: 0] o- loopback ............................................ [Targets: 0] />

First, make the block backend stores with one disk storage and one image file.

/> cd backstores/block /backstores/block> ls o- block ......................................... [Storage Objects: 0] /backstores/block> create name=diskblock1 dev=/dev/vdb1 Created block storage object diskblock1 using /dev/vdb1. /backstores/block> cd ../fileio /backstores/fileio> create name=fileblock1 file_or_dev=/fimg/1gbfile.img Created fileio fileblock1 with size 1073741824 /backstores/block> cd / /> ls o- / ................................................................ [...] o- backstores ..................................................... [...] | o- block ......................................... [Storage Objects: 1] | | o- diskblock1 ........ [/dev/vdb1 (1023.0MiB) write-thru deactivated] | o- fileio ........................................ [Storage Objects: 1] | | o- fileblock1 ... [/fimg/1gbfile.img (1.0GiB) write-back deactivated] | o- pscsi ......................................... [Storage Objects: 0] | o- ramdisk ....................................... [Storage Objects: 0] o- iscsi ................................................... [Targets: 0] o- loopback ................................................ [Targets: 0] />

Subsequently, define the IQN. (IQN naming convention is in the RFC 3720.)

/> cd iscsi /iscsi> create iqn.2016-12.local.host.target:dskarray1 Created target iqn.2016-12.local.host.target:dskarray1. Created TPG 1. Global pref auto_add_default_portal=true Created default portal listening on all IPs (0.0.0.0), port 3260. /iscsi> ls / o- / ................................................................ [...] o- backstores ..................................................... [...] | o- block ......................................... [Storage Objects: 1] | | o- diskblock1 ........ [/dev/vdb1 (1023.0MiB) write-thru deactivated] | o- fileio ........................................ [Storage Objects: 1] | | o- fileblock1 ... [/fimg/1gbfile.img (1.0GiB) write-back deactivated] | o- pscsi ......................................... [Storage Objects: 0] | o- ramdisk ....................................... [Storage Objects: 0] o- iscsi ................................................... [Targets: 1] | o- iqn.2016-12.local.host.target:dskarray1 .................. [TPGs: 1] | o- tpg1 ...................................... [no-gen-acls, no-auth] | o- acls ................................................. [ACLs: 0] | o- luns ................................................. [LUNs: 0] | o- portals ........................................... [Portals: 1] | o- 0.0.0.0:3260 ............................................ [OK] o- loopback ................................................ [Targets: 0] /iscsi>
The portal was created by default value '0.0.0.0:3260' when the IQN defined.
But we'll change the specific IP '192.168.1.28'.

/iscsi> cd iqn.2016-12.local.host.target:dskarray1/tpg1/portals/ /iscsi/iqn.20.../tpg1/portals> delete 0.0.0.0 ip_port=3260 Deleted network portal 0.0.0.0:3260 /iscsi/iqn.20.../tpg1/portals> create 192.168.1.28 ip_port=3260 Using default IP port 3260 Created network portal 192.168.1.28:3260. /iscsi/iqn.20.../tpg1/portals> ls / o- / ................................................................ [...] o- backstores ..................................................... [...] | o- block ......................................... [Storage Objects: 1] | | o- diskblock1 ........ [/dev/vdb1 (1023.0MiB) write-thru deactivated] | o- fileio ........................................ [Storage Objects: 1] | | o- fileblock1 ... [/fimg/1gbfile.img (1.0GiB) write-back deactivated] | o- pscsi ......................................... [Storage Objects: 0] | o- ramdisk ....................................... [Storage Objects: 0] o- iscsi ................................................... [Targets: 1] | o- iqn.2016-12.local.host.target:dskarray1 .................. [TPGs: 1] | o- tpg1 ...................................... [no-gen-acls, no-auth] | o- acls ................................................. [ACLs: 0] | o- luns ................................................. [LUNs: 0] | o- portals ........................................... [Portals: 1] | o- 192.168.1.28:3260 ....................................... [OK] o- loopback ................................................ [Targets: 0] /iscsi/iqn.20.../tpg1/portals>
It's the configuration to make the backend stores establish to LUNs into the IQN.

/iscsi/iqn.20.../tpg1/portals> cd ../luns /iscsi/iqn.20...ay1/tpg1/luns> create /backstores/block/diskblock1 Created LUN 0. /iscsi/iqn.20...ay1/tpg1/luns> create /backstores/fileio/fileblock1 Created LUN 1. /iscsi/iqn.20...ay1/tpg1/luns> ls / o- / ................................................................ [...] o- backstores ..................................................... [...] | o- block ......................................... [Storage Objects: 1] | | o- diskblock1 .......... [/dev/vdb1 (1023.0MiB) write-thru activated] | o- fileio ........................................ [Storage Objects: 1] | | o- fileblock1 ..... [/fimg/1gbfile.img (1.0GiB) write-back activated] | o- pscsi ......................................... [Storage Objects: 0] | o- ramdisk ....................................... [Storage Objects: 0] o- iscsi ................................................... [Targets: 1] | o- iqn.2016-12.local.host.target:dskarray1 .................. [TPGs: 1] | o- tpg1 ...................................... [no-gen-acls, no-auth] | o- acls ................................................. [ACLs: 0] | o- luns ................................................. [LUNs: 2] | | o- lun0 .......................... [block/diskblock1 (/dev/vdb1)] | | o- lun1 ................. [fileio/fileblock1 (/fimg/1gbfile.img)] | o- portals ........................................... [Portals: 1] | o- 192.168.1.28:3260 ....................................... [OK] o- loopback ................................................ [Targets: 0] /iscsi/iqn.20...ay1/tpg1/luns>
It need the ACL configurations if you need access control over the allowed clients.
It is based on the client initiator name to identify the clients whether allowed or not from the target.
We assume the allowed initiator name is 'iqn.2016-12.local.host.initiator:client1' that will be configured later at the initiator configurations part.

/iscsi/iqn.20...ay1/tpg1/luns> cd ../acls /iscsi/iqn.20...ay1/tpg1/acls> create iqn.2016-12.local.host.initiator:client1 Created Node ACL for iqn.2016-12.local.host.initiator:client1 Created mapped LUN 1. Created mapped LUN 0. /iscsi/iqn.20...ay1/tpg1/acls> ls / o- / ................................................................ [...] o- backstores ..................................................... [...] | o- block ......................................... [Storage Objects: 1] | | o- diskblock1 .......... [/dev/vdb1 (1023.0MiB) write-thru activated] | o- fileio ........................................ [Storage Objects: 1] | | o- fileblock1 ..... [/fimg/1gbfile.img (1.0GiB) write-back activated] | o- pscsi ......................................... [Storage Objects: 0] | o- ramdisk ....................................... [Storage Objects: 0] o- iscsi ................................................... [Targets: 1] | o- iqn.2016-12.local.host.target:dskarray1 .................. [TPGs: 1] | o- tpg1 ...................................... [no-gen-acls, no-auth] | o- acls ................................................. [ACLs: 1] | | o- iqn.2016-12.local.host.initiator:client1 .... [Mapped LUNs: 2] | | o- mapped_lun0 ................... [lun0 block/diskblock1 (rw)] | | o- mapped_lun1 .................. [lun1 fileio/fileblock1 (rw)] | o- luns ................................................. [LUNs: 2] | | o- lun0 .......................... [block/diskblock1 (/dev/vdb1)] | | o- lun1 ................. [fileio/fileblock1 (/fimg/1gbfile.img)] | o- portals ........................................... [Portals: 1] | o- 192.168.1.28:3260 ....................................... [OK] o- loopback ................................................ [Targets: 0] /iscsi/iqn.20...ay1/tpg1/acls>
Finally, the target configuration is complete after saving the configurations, but the auto save is default setting.

/iscsi/iqn.20...ay1/tpg1/acls> exit Global pref auto_save_on_exit=true Last 10 configs saved in /etc/target/backup. Configuration saved to /etc/target/saveconfig.json
# targetcli saveconfig
Last 10 configs saved in /etc/target/backup. Configuration saved to /etc/target/saveconfig.json

Step3: The prerequisite tasks for the initiator configuration.

The initiator means the client for the iSCSI target.
It's same as the configurations as of RHEL6/CentOS6 unlike the target configurations.

The 'iscsid.service' processes the iSCSI command from the backend, and 'iscsi.service' recognizes automatically the registration of the target when the system start.

# systemctl is-enabled iscsi
enabled
# systemctl is-enabled iscsid
disabled
# systemctl enable iscsid
Created symlink from /etc/systemd/system/multi-user.target.wants/iscsid.service to /usr/lib/systemd/system/iscsid.service.
# systemctl start iscsid
I said the initiator is named the 'iqn.2016-12.local.host.initiator:client1' at the previous ACL configuration of the target part.

# vim /etc/iscsi/initiatorname.iscsi
InitiatorName=iqn.2016-12.local.host.initiator:client1
# systemctl restart iscsid

Step4: The main initiator configurations.

This initiator configurations are based on the iscsiadm command as follows.

Firstly, we need to discovery the target to identify the IQN, the node mode is the setting for the specific IQN.

# iscsiadm --mode discovery --type sendtargets --portal 192.168.1.28:3260
192.168.1.28:3260,1 iqn.2016-12.local.host.target:dskarray1
# iscsiadm --mode node --targetname iqn.2016-12.local.host.target:dskarray1 --portal 192.168.1.28:3260 --login
Logging in to [iface: default, target: iqn.2016-12.local.host.target:dskarray1, portal: 192.168.1.28,3260] (multiple) Login to [iface: default, target: iqn.2016-12.local.host.target:dskarray1, portal: 192.168.1.28,3260] successful.
Check the iscsi session status.

# iscsiadm --mode session -P 3
iSCSI Transport Class version 2.0-870 version 6.2.0.873-33.2 Target: iqn.2016-12.local.host.target:dskarray1 (non-flash) Current Portal: 192.168.1.28:3260,1 Persistent Portal: 192.168.1.28:3260,1 ********** Interface: ********** Iface Name: default Iface Transport: tcp Iface Initiatorname: iqn.2016-12.local.host.initiator:client1 ...snip... ************************ Attached SCSI devices: ************************ Host Number: 5 State: running scsi5 Channel 00 Id 0 Lun: 0 Attached scsi disk sda State: running scsi5 Channel 00 Id 0 Lun: 1 Attached scsi disk sdb State: running

Tuesday, December 6, 2016

The SQL and Optimizer trace on the Oracle Database for diagnosing

Introduction:


It's the snippet note for SQL trace on session level in Oracle DB to take the execution plans, wait events and so on.

Environment:

  DBMS: Oracle Database Standard Edition 12.1.0.2.0
  Client: SQL*Plus
  Requirements: SYSDBA or ALTER SESSION system privilege is needed

Configuration steps:


Step1: Extended SQL trace by using 10046 event.

The 10046 is a event code for tracing SQL_TRACE type of internal Oracle, it break into the several levels.
  • level 1 - Default value, standard sql trace information (resonponse time, physical/logical reads and so on).
  • level 4 - As Level 1 + trace bind values, the same syntax is 'bind=true'
  • level 8 - As Level 1 + trace waits, the same syntax is 'wait=true'
    e.g.> latch wait, full scan, index scan and so on.
  • As of 11g as follows.
  • level 16 - Generate traces for each execution, the same syntax is 'plan_stat=all_executions'
  • level 32 - Not to trace about execution statistics, the same syntax is 'plan_stat=never'
  • As of 11.2.0.2 as follows.
  • level 64 - Generate extensive traces for slow SQL, the same syntax is 'plan_stat=adaptive'
    e.g.>1 additional minute of DB time.

And the level is used by following format:
  • level 12 = level 4 + level 8 : level 4 and 8 are enabled at the same time.
  • level 28 = level 4 + level 8 + level 16 : level 4, 8 and 16 are enabled at the same time.
Additionally the resulting trace files need to be translated by tkprof utility for checking SQL trace results.

The settings for enabling to sql trace on the session level as follows.

SQL> ALTER SESSION SET TRACEFILE_IDENTIFIER = '10046';
SQL> ALTER SESSION SET TIMED_STATISTICS = true;
SQL> ALTER SESSION SET STATITICS_LEVEL = all;
SQL> ALTER SESSION SET MAX_DUMP_FILE_SIZE = unlimited;
SQL> -- Pattern1
SQL> ALTER SESSION SET EVENTS '10046 trace name context forever, level 28';
SQL> -- Pattern2: The alternative is as follows at 11g or more than it.
SQL> ALTER SESSION SET EVENTS 'sql_trace bind=true, wait=true, plan_stat=all_executions';
And then execute the sql statements for check to trace.

The statement for disabling to sql trace as follows.

SQL> -- Pattern1
SQL> ALTER SESSION SET EVENTS '10046 trace name context off';
SQL> -- Pattern2: The alternative is as follows at 11g or more than it.
SQL> ALTER SESSION SET EVENTS 'sql_trace off';
Display the resulting tracefile path.

SQL> SELECT value FROM v$diag_info WHERE name = 'Default Trace File';
VALUE
-------------------------------------------------------------
/u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_18830_10046.trc
Finally the trace file is translated into the human readable report file with the following command format.
$ tkprof [trace file path] [output file as report]
The output executed actually is as follows.

$ tkprof /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_18830_10046.trc /tmp/orcl_18830_10046.txt
TKPROF: Release 12.1.0.2.0 - Development on Tue Dec 6 15:56:20 2016 Copyright (c) 1982, 2015, Oracle and/or its affiliates. All rights reserved.
$ cat /tmp/orcl_18830_10046.txt
TKPROF: Release 12.1.0.2.0 - Development on Tue Dec 6 15:56:20 2016 Copyright (c) 1982, 2015, Oracle and/or its affiliates. All rights reserved. Trace file: /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_18830_10046.trc Sort options: default ******************************************************************************** count = number of times OCI procedure was executed cpu = cpu time in seconds executing elapsed = elapsed time in seconds executing disk = number of physical reads of buffers from disk query = number of buffers gotten for consistent read current = number of buffers gotten in current mode (usually for update) rows = number of rows processed by the fetch or execute call ******************************************************************************** SQL ID: 1p5grz1gs7fjq Plan Hash: 813480514 select obj#,type#,ctime,mtime,stime, status, dataobj#, flags, oid$, spare1, spare2, spare3, signature, spare7, spare8, spare9 from obj$ where owner#=:1 and name=:2 and namespace=:3 and remoteowner is null and linkname is null and subname is null call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 1 0.00 0.00 0 0 0 0 Execute 7 0.00 0.02 0 0 0 0 Fetch 7 0.00 0.00 0 28 0 7 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 15 0.00 0.02 0 28 0 7 Misses in library cache during parse: 1 Misses in library cache during execute: 1 Optimizer mode: CHOOSE Parsing user id: SYS (recursive depth: 1) Number of plan statistics captured: 7 Rows (1st) Rows (avg) Rows (max) Row Source Operation ---------- ---------- ---------- --------------------------------------------------- 1 1 1 TABLE ACCESS BY INDEX ROWID BATCHED OBJ$ (cr=4 pr=0 pw=0 time=44 us cost=4 size=100 card=1) 1 1 1 INDEX RANGE SCAN I_OBJ2 (cr=3 pr=0 pw=0 time=36 us cost=3 size=0 card=1)(object id 37) ******************************************************************************** ...snip... Trace file: /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_18830_10046.trc Trace file compatibility: 11.1.0.7 Sort options: default 1 session in tracefile. 9 user SQL statements in trace file. 33 internal SQL statements in trace file. 42 SQL statements in trace file. 38 unique SQL statements in trace file. 2131 lines in trace file. 9180 elapsed seconds in trace file.

Step2: Optimizer trace by using 10053 event.

This event code is used of optimizer tracing such as query transformation process, query optimization process to diagnose optimizer decisions and behaviour.
SQL> ALTER SESSION SET TRACEFILE_IDENTIFIER = '10053';
SQL> ALTER SESSION SET MAX_DUMP_FILE_SIZE = unlimited;
SQL> ALTER SESSION SET EVENTS '10053 trace name context forever, level 1';
Execute the sql statements to diagnose.

Stop the tracing and take the trace file name and path.

SQL> -- stop the tracing with 10053 event.
SQL> ALTER SESSION SET EVENTS '10053 trace name context off';
SQL> -- get the trace file path from v$diag_info view.
SQL> SELECT value FROM v$diag_info WHERE name = 'Default Trace File';
VALUE -------------------------------------------------------------------------------- /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_33842_10053.trc

If you can't get the valid trace information, you should execute the sql statements with a meaningless spaces or hint comment again.
The 10053 event code needs the hard parse of the sql statements for getting the valid trace informations.

Thursday, December 1, 2016

The limited two-way(bidirectional) synchronization with Lsync + rsync as non-root user

Introduction:

One day a project manager had consulted me about the file share solutions which are good cost-performance between 2 web servers under the Load balancer. The project manager said that the NFS or DRBD is overkill to that system and having the budget problem, so he wanted to implement the file share with the Lsyncd + rsync. But the Lsyncd didn't support the bidirectional synchronizaion (related link) and it's difficult to implement the complete bidirectional synchronization according to the limited architecture which didn't have the mechanism for concurrency control like the DBMS.

The file synchronization with Lsync + rsync seems to work well in common conditions but it will be the critical problems if either of the 2 web servers have the problems; such as network or OS troubles. No servers can know which data condition is right, and can't control over the synchronization as one transaction across the two servers. So we would need the rules to comply with the file synchronization principles between 2 web servers if either of the 2 web servers make problems.


In advance, I defined that this post is just written as the provision of information, I won't be not responsible for data-loss caused by this post.


Related Posts:


Environment:

  Host: tgt-a.host.local(tgt-a), tgt-b.host.local(tgt-b)
  OS: CentOS 7 (All the hosts are same.)
  Packages: lsyncd-2.1.5-6.el7, rsync-3.0.9-17.el7

Configuration Summary:

We assume that the required configurations have been completed such as key-based authentication, directories tree and test users.
This post is helpful to you: (related post)

You would test the configuraion with non-critical data or must do the backup before test.

I recommend the other soultions (DRBD, NFS, GlusterFS and so on) about the systems follows:(in bidirectional synchronization perspective)
  • Frequently updated the files as same name.
  • The synchronization unit is not a file.
  • The need for updating the same file from some or many sessions.
  • The synchronizaion task is critical to the business systems.
  • You need to synchronize the contents on the more than 2 servers.

This configuration is going well in normal conditions as long as my cases, but you need to know this configuration in details to troubleshoot if there is a malfunction in this lsyncd + rsync stack.

Simple features summary:
  • No files are deleted as soon as the lsyncd daemon started.
  • It is added the files with each other without deleting as soon as the lsync daemon started if the synchronization is inconsistent.
  • It is updated the newer file, if there was different contents file as same name in the other server.
  • It is deleted the files as soon as the other server delete the files.
  • It is changed the permission of the files as soon as the other server change the permission of the ones.
  • It is added the files as soon as the other server create or add the new files.

Specially you should be careful of starting the lsyncd in the inconsistent synchronizaion status.

The below flow diagram is helpful to your understanding.


Configuration steps:


Step1: Creating the rsync temporaty work directories.


This directory is used by rsync process as temporary work directory which save the transmitted files until the synchronization success.

Creating the temporary directory on the 'tgt-a.host.local'.

[tgt-a webmgr]$ mkdir -p ~/tmpdir/{imgcms,cgicms}
The directory tree on the 'tgt-a.host.local'.
/home ├── [drwx------ webmgr.webmgr] webmgr │ └── [drwxrwxr-x webmgr.webmgr ] contents │ ├── [drwxrwxr-x webmgr.webmgr] images │ └── [drwxrwxr-x webmgr.webmgr] cgi-bins └── [drwxrwxr-x webmgr.webmgr ] tmpdir ├── [drwxrwxr-x webmgr.webmgr] imgcms └── [drwxrwxr-x webmgr.webmgr] cgicms
Creating the temporary directory to the each remote account on the 'tgt-b.host.local'.

[tgt-b imgcms]$ mkdir  ~/tmpdir

[tgt-b cgicms]$ mkdir  ~/tmpdir
The directory tree on the 'tgt-b.host.local'.
/home ├── [drwx------ webmgr.webmgr] webmgr │ └── [drwxrwxr-x webmgr.webmgr] contents │ ├── [lrwxrwxrwx webmgr.webmgr] images -> /home/imgcms/images │ └── [lrwxrwxrwx webmgr.webmgr] cgi-bins -> /home/cgicms/cgi-bins ├── [drwx--x--- imgcms.imgcms] imgcms │ ├── [drwxrwxr-x imgcms.imgcms] images │ └── [drwxrwxr-x imgcms.imgcms] tmpdir └── [drwx--x--- cgicms.cgicms] cgicms ├── [drwxrwxr-x cgicms.cgicms] cgi-bins └── [drwxrwxr-x cgicms.cgicms] tmpdir

Step3: Configuration of the lsyncd.conf in the tgt-a.host.local.

The rsync block options(update, archive, compress) are same as '-uaz' options of the rsync command.(reference link: OPTIONS SUMMARY section)
The delete="running" option means that it delete no files when it start up. (reference link: Deletes section)

[tgt-a ]# vim /etc/lsyncd.conf
-------- ---- Description: the Lsyncd main configuration file - two-way ---- Host: tgt-a.host.local ---- ---- -- The settings for all layers. settings { logfile = "/var/log/lsyncd/lsyncd.log", statusFile = "/var/log/lsyncd/lsyncd.status", statusInterval = 30, insist = true, inotifyMode = "Modify", delay = 0, maxProcesses = 8 } ---- -- The local variables: the prefix is 'lcv_*'. -- -- The local variable of the 'rsh' directive in the rsync block. -- lcv_rsh = "/usr/bin/ssh -i /home/webmgr/.ssh/tgt-a-sync-rsa2048.key -o StrictHostKeyChecking=no" lcv_rsh = "/usr/bin/ssh -i /home/webmgr/.ssh/tgt-a-sync-rsa2048.key" -- The image contents target list local variable. lcv_tgtimg = "imgcms@tgt-b.host.local:/home/imgcms/images" -- The cgi contents target list local variable. lcv_tgtcgi = "cgicms@tgt-b.host.local:/home/cgicms/cgi-bins" ---- -- The main blocks -- -- The sync block of the image contents. sync { default.rsync, source = "/home/webmgr/contents/images/", target = lcv_tgtimg, delete = "running", -- init = false, rsync = { temp_dir = "/home/imgcms/tmpdir", update = true, archive = true, compress = true, rsh = lcv_rsh, } } -- The sync block of the cgi contents. sync { default.rsync, source = "/home/webmgr/contents/cgi-bins/", target = lcv_tgtcgi, delete = "running", -- init = false, rsync = { temp_dir = "/home/cgicms/tmpdir", update = true, archive = true, compress = true, rsh = lcv_rsh, } }

Step4: Configuration of the lsyncd.conf in the tgt-b.host.local.

It takes care that the each local source directory has the different target respectively.

[tgt-b ]# vim /etc/lsyncd.conf
-------- ---- Description: the Lsyncd main configuration file - two-way ---- Host: tgt-b.host.local ---- ---- -- The settings for all layers. settings { logfile = "/var/log/lsyncd/lsyncd.log", statusFile = "/var/log/lsyncd/lsyncd.status", statusInterval = 30, insist = true, inotifyMode = "Modify", delay = 0, maxProcesses = 8 } ---- -- The local variables: the prefix is 'lcv_*'. -- -- The local variable of the 'rsh' directive in the rsync block. -- lcv_rsh = "/usr/bin/ssh -i /home/webmgr/.ssh/tgt-b-sync-rsa2048.key -o StrictHostKeyChecking=no" lcv_rsh = "/usr/bin/ssh -i /home/webmgr/.ssh/tgt-b-sync-rsa2048.key" -- The image contents target list local variable. lcv_tgtimg = "webmgr@tgt-a.host.local:/home/webmgr/contents/images" -- The cgi contents target list local variable. lcv_tgtcgi = "webmgr@tgt-a.host.local:/home/webmgr/contents/cgi-bins" ---- -- The main blocks -- -- The sync block of the image contents. sync { default.rsync, source = "/home/imgcms/images/", target = lcv_tgtimg, delete = "running", -- init = false, rsync = { temp_dir = "/home/webmgr/tmpdir/imgcms", update = true, archive = true, compress = true, rsh = lcv_rsh, } } -- The sync block of the cgi contents. sync { default.rsync, source = "/home/cgicms/cgi-bins/", target = lcv_tgtcgi, delete = "running", -- init = false, rsync = { temp_dir = "/home/webmgr/tmpdir/cgicms", update = true, archive = true, compress = true, rsh = lcv_rsh, } }

Step5: Tests the configuration while running on the normal conditions.

You should make the log directory as follows if the inial start of the lsyncd before starting the daemon.

[tgt-a/tgt-b ]# mkdir /var/log/lsyncd
[tgt-a/tgt-b ]# systemctl start lsyncd
or
[tgt-a/tgt-b ]# lsyncd -nodaemon /etc/lsyncd.conf
You should take care of the prompt of the test commands as follows which present the hostname where the tests were performed on.
The prompt format is as follows:
[hostname username]$
First tests are the delete, create, update of the files.

[tgt-a webmgr]$ touch ~/contents/cgi-bins/willbecgicmsowneratremote.txt
[tgt-b imgcms]$ touch ~/images/willbewebmgrowneratremote.txt

[tgt-b imgcms]$ touch ~/images/imgfile{1..3}.png
[tgt-a webmgr]$ rm ~/contents/images/imgfile2.png
[tgt-b imgcms]$ rm ~/images/imgfile1.png

[tgt-a webmgr]$ mv ~/contents/cgi-bins/willbecgicmsowneratremote.txt ~/contents/cgi-bins/updatetestfile.cgi
[tgt-b cgicms]$ echo "this file size will be 32 bytes" > ~/cgi-bins/updatetestfile.cgi
[tgt-a webmgr]$ echo "added this data, so ths file size are 84 bytes now." >> ~/contents/cgi-bins/updatetestfile.cgi
The result of the tests in the 'tgt-a.host.local'.
[tgt-a webmgr]$ watch -d -n1 ls -lR /home/webmgr

Every 1.0s: ls -lR /home/webmgr Mon Dec 5 12:58:41 2016 /home/webmgr: 合計 0 drwxrwxr-x 4 webmgr webmgr 34 11月 29 16:27 contents /home/webmgr/contents: 合計 0 drwxrwxr-x 2 webmgr webmgr 31 12月 5 12:48 cgi-bins drwxrwxr-x 2 webmgr webmgr 61 12月 5 12:46 images /home/webmgr/contents/cgi-bins: 合計 4 -rw-rw-r-- 1 webmgr webmgr 84 12月 5 12:55 updatetestfile.cgi /home/webmgr/contents/images: 合計 0 -rw-rw-r-- 1 webmgr webmgr 0 12月 5 12:46 imgfile3.png -rw-rw-r-- 1 webmgr webmgr 0 12月 5 12:46 willbewebmgrowneratremote.txt
The result of the tests in the 'tgt-b.host.local'.
[tgt-b webmgr]$ watch -d -n1 ls -lRL /home/webmgr

Every 1.0s: ls -lRL /home/webmgr Mon Dec 5 13:01:33 2016 /home/webmgr: total 0 drwxrwxr-x. 2 webmgr webmgr 34 Nov 28 16:30 contents /home/webmgr/contents: total 0 drwxrwxr-x. 2 cgicms cgicms 31 Dec 5 12:48 cgi-bins drwxrwxr-x. 2 imgcms imgcms 61 Dec 5 12:46 images /home/webmgr/contents/cgi-bins: total 4 -rw-rw-r--. 1 cgicms cgicms 84 Dec 5 12:55 updatetestfile.cgi /home/webmgr/contents/images: total 0 -rw-rw-r--. 1 imgcms imgcms 0 Dec 5 12:46 imgfile3.png -rw-rw-r--. 1 imgcms imgcms 0 Dec 5 12:46 willbewebmgrowneratremote.txt

Step6: Test about starting the lsyncd daemon when the datas states were inconsistent.

This test is the replay of the situations at the Figure2 image above and the test data states are based on the Step5 subsequently.
You need to stop the lsyncd daemon on each server before test as follows.

Fisrt we should make the files inconsistent to replay the abnormal status for tests.

The changes on the 'tgt-a.host.local'.

[tgt-a webmgr]$ rm ~/contents/images/imgfile3.png
[tgt-a webmgr]$ touch ~/contents/images/tgt-a-new{1..2}.img
[tgt-a webmgr]$ echo "the file has updated before tgt-b host." >> ~/contents/cgi-bins/updatetestfile.cgi
[tgt-a webmgr]$ $ cat ~/contents/cgi-bins/updatetestfile.cgi
this file size will be 32 bytes added this data, so ths file size are 84 bytes now. the file has updated before tgt-b host.
[tgt-a webmgr]$ watch -d -n1 ls -lR /home/webmgr
Every 1.0s: ls -lR /home/webmgr Mon Dec 5 16:15:33 2016 /home/webmgr: 合計 0 drwxrwxr-x 4 webmgr webmgr 34 11月 29 16:27 contents /home/webmgr/contents: 合計 0 drwxrwxr-x 2 webmgr webmgr 31 12月 5 12:48 cgi-bins drwxrwxr-x 2 webmgr webmgr 84 12月 5 16:15 images /home/webmgr/contents/cgi-bins: 合計 4 -rw-rw-r-- 1 webmgr webmgr 124 12月 5 16:15 updatetestfile.cgi /home/webmgr/contents/images: 合計 0 -rw-rw-r-- 1 webmgr webmgr 0 12月 5 16:15 tgt-a-new1.img -rw-rw-r-- 1 webmgr webmgr 0 12月 5 16:15 tgt-a-new2.img -rw-rw-r-- 1 webmgr webmgr 0 12月 5 12:46 willbewebmgrowneratremote.txt
The changes on the 'tgt-b.host.local'.

[tgt-b imgcms]$ rm ~/images/willbewebmgrowneratremote.txt
[tgt-b imgcms]$ touch ~/images/tgt-b-new{3..4}.jpg
[tgt-b cgicms]$ echo "The changes after making changes for tgt-a." >> ~/cgi-bins/updatetestfile.cgi
[tgt-b cgicms]$ cat ~/cgi-bins/updatetestfile.cgi
this file size will be 32 bytes added this data, so ths file size are 84 bytes now. The changes after making changes for tgt-a.
[tgt-b webmgr]$ watch -d -n1 ls -lRL /home/webmgr
Every 1.0s: ls -lRL /home/webmgr Mon Dec 5 16:23:09 2016 /home/webmgr: total 0 drwxrwxr-x. 2 webmgr webmgr 34 Nov 28 16:30 contents /home/webmgr/contents: total 0 drwxrwxr-x. 2 cgicms cgicms 31 Dec 5 12:48 cgi-bins drwxrwxr-x. 2 imgcms imgcms 67 Dec 5 16:20 images /home/webmgr/contents/cgi-bins: total 4 -rw-rw-r--. 1 cgicms cgicms 128 Dec 5 16:21 updatetestfile.cgi /home/webmgr/contents/images: total 0 -rw-rw-r--. 1 imgcms imgcms 0 Dec 5 12:46 imgfile3.png -rw-rw-r--. 1 imgcms imgcms 0 Dec 5 16:20 tgt-b-new3.jpg -rw-rw-r--. 1 imgcms imgcms 0 Dec 5 16:20 tgt-b-new4.jpg

Let's start with the lsyncd in each server, at that time the startup order of between hosts is tgt-a -> tgt-b (to test for the 'updatetestfile.cgi' file overwriting test!),
and then check the file directories. I'll be same status as follows:

[tgt-a/tgt-b webmgr]$ watch -d -n1 ls -lRL /home/webmgr
/home/webmgr: 合計 0 drwxrwxr-x 4 webmgr webmgr 34 11月 29 16:27 contents /home/webmgr/contents: 合計 0 drwxrwxr-x 2 webmgr webmgr 31 12月 5 12:48 cgi-bins drwxrwxr-x 2 webmgr webmgr 145 12月 5 16:15 images /home/webmgr/contents/cgi-bins: 合計 4 -rw-rw-r-- 1 webmgr webmgr 128 12月 5 16:21 updatetestfile.cgi /home/webmgr/contents/images: 合計 0 -rw-rw-r-- 1 webmgr webmgr 0 12月 5 12:46 imgfile3.png -rw-rw-r-- 1 webmgr webmgr 0 12月 5 16:15 tgt-a-new1.img -rw-rw-r-- 1 webmgr webmgr 0 12月 5 16:15 tgt-a-new2.img -rw-rw-r-- 1 webmgr webmgr 0 12月 5 16:20 tgt-b-new3.jpg -rw-rw-r-- 1 webmgr webmgr 0 12月 5 16:20 tgt-b-new4.jpg -rw-rw-r-- 1 webmgr webmgr 0 12月 5 12:46 willbewebmgrowneratremote.txt
[tgt-a/tgt-b webmgr]$ cat ~/cgi-bins/updatetestfile.cgi
this file size will be 32 bytes added this data, so ths file size are 84 bytes now. The changes after making changes for tgt-a.

Tuesday, November 29, 2016

The simple one-way file synchronization with Lsyncd + rsync as non-root user

Introduction:

The Lsyncd + rsync combination stack is efficient and simple for the small-scale synchronizing systems.
For instance, the irregularly uploaded image files would be synchronied between one source host between some target hosts,
if your system doesn't strictly depend on sync speed.

This quick reference is the memo that I had simulated the one-way sync configuration with lsyncd as non-root user.

Environment:

  Host: tgt1.host.local(tgt1), tgt2.host.local(tgt2), org.host.local(org)
  OS: CentOS 7 (All the hosts are same.)
  Packages: lsyncd-2.1.5-6.el7, rsync-3.0.9-17.el7
All hosts are required the rsync package but the lsyncd package is installed at org.host.local only.

Related Posts:

Configuration Summary:

The webmgr user have just symbolic links that linked the contents of the other users: imgcms, imgcgi.
But the contents on the org.host.local will be synchronized to be real contents of webmgr on the tgt1,2.host.local, not be symbolic links.


Configuration steps:


Step1: Creating the test users and change the access permission of the home directories.


We need the test users and directory trees as follows.

This webmgr user is accessible to the contents of the imgcms, cgicms users through the symbolic links in the org.host.local host.
But the remote webmgr user will be synchronized as its own permission in the tgt1,tgt2.host.local hosts.
org.host.local : uid=12071(webmgr) gid=12071(webmgr) groups=12071(webmgr),12069(imgcms),12070(cgicms) tgt1.host.local, tgt2.host.local : uid=12071(webmgr) gid=12071(webmgr) groups=12071(webmgr)

We assume that the users as follows are the owners of the contents in the org.host.local host.
org.host.local : uid=12069(imgcms) gid=12069(imgcms) groups=12069(imgcms) org.host.local : uid=12070(cgicms) gid=12070(cgicms) groups=12070(cgicms)

The directory tree of the org.host.local host.
/home ├── [drwx------ webmgr.webmgr] webmgr │   └── [drwxrwxr-x webmgr.webmgr] contents │   ├── [lrwxrwxrwx webmgr.webmgr] images -> /home/imgcms/images │   └── [lrwxrwxrwx webmgr.webmgr] cgi-bins -> /home/cgicms/cgi-bins ├── [drwx--x--- imgcms.imgcms] imgcms │    └── [drwxrwxr-x imgcms.imgcms] images └── [drwx--x--- cgicms.cgicms] cgicms └── [drwxrwxr-x cgicms.cgicms] cgi-bins

The directory tree of the tgt1.host.local and tgt2.host.local hosts.
/home └── [drwx------ webmgr.webmgr] webmgr └── [drwxrwxr-x webmgr.webmgr ] contents ├── [drwxrwxr-x webmgr.webmgr] images └── [drwxrwxr-x webmgr.webmgr] cgi-bins

You should set up the password to the users with passwd command after creating the users as follows.

[org ]# useradd imgcms
[org ]# useradd cgicms
[org ]# useradd -G imgcms,cgicms webmgr
[org ]# setfacl -m u:webmgr:x /home/imgcms
[org ]# setfacl -m u:webmgr:x /home/cgicms

[tgt1 ]# useradd webmgr

[tgt2 ]# useradd webmgr

Step2: The Configuration of The key-based authentication through SSH.


The key-based authentication is required to the synchronization of the contents through the SSH without password.

The commands should be executed by webmgr user as follows.

[org webmgr]$ ssh-keygen -t rsa -b 2048
Generating public/private rsa key pair. Enter file in which to save the key (/home/webmgr/.ssh/id_rsa): /home/webmgr/.ssh/sync-rsa2048.key Created directory '/home/webmgr/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/webmgr/.ssh/sync-rsa2048.key. Your public key has been saved in /home/webmgr/.ssh/sync-rsa2048.key.pub. The key fingerprint is: db:4b:18:a8:a8:0a:df:84:01:a5:c5:53:e3:88:3c:f2 webmgr@org.host.local The key's randomart image is: +--[ RSA 2048]----+ | .o.o | |.=oo . | |=o... | |.o. . | | E . S | | + . = | |. o o o o | |.o o . . | |+ . . . | +-----------------+
The transportation of the public key to the remote hosts.

[org webmgr]$ ssh-copy-id -i ~/.ssh/sync-rsa2048.key.pub webmgr@tgt1.host.local
/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys webmgr@tgt1.host.local's password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh 'webmgr@tgt1.host.local'" and check to make sure that only the key(s) you wanted were added.

[org webmgr]$ ssh-copy-id -i ~/.ssh/sync-rsa2048.key.pub webmgr@tgt2.host.local
/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys webmgr@tgt2.host.local's password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh 'webmgr@tgt2.host.local'" and check to make sure that only the key(s) you wanted were added.
Test the key-based authentication through the SSH without password.
You should type "yes" to accept the authenticity of the remote host at the first time connection.

[org webmgr]$ ssh -i ~/.ssh/sync-rsa2048.key tgt1.host.local
... snip ...
[tgt1 webmgr]$ hostname -f
tgt1.host.local

[org webmgr]$ ssh -i ~/.ssh/sync-rsa2048.key tgt2.host.local
... snip ...
[tgt2 webmgr]$ hostname -f
tgt2.host.local

Step3: Configuration of the lsyncd.conf file.


I process the multiple targets list with lua loops in here (reference link), because you can use the lua into the 'lsyncd.conf' file.
And the variables that have prefix 'lcv_' are not the directives of the lsyncd, just temporarily defined local variables.
The rsync block options(archive, compress) are same as '-az' options of rsync command.


[org ]# vim /etc/lsyncd.conf
-------- ---- Description: the Lsyncd main configuration file - one-way ---- ---- -- The settings for all layers. settings { logfile = "/var/log/lsyncd/lsyncd.log", statusFile = "/var/log/lsyncd/lsyncd.status", statusInterval = 30, insist = true, inotifyMode = "Modify", delay = 0, maxProcesses = 8 } ---- -- The local variables: the prefix is 'lcv_*'. -- -- The local variable of the 'rsh' directive in the rsync block. -- lcv_rsh = "/usr/bin/ssh -i /home/webmgr/.ssh/sync-rsa2048.key -o StrictHostKeyChecking=no" lcv_rsh = "/usr/bin/ssh -i /home/webmgr/.ssh/sync-rsa2048.key" -- The image contents target list local variable. lcv_tgtlist_imgcms = { "webmgr@tgt1.host.local:/home/webmgr/contents/images", "webmgr@tgt2.host.local:/home/webmgr/contents/images" } -- The cgi contents target list local variable. lcv_tgtlist_cgicms = { "webmgr@tgt1.host.local:/home/webmgr/contents/cgi-bins", "webmgr@tgt2.host.local:/home/webmgr/contents/cgi-bins" } ---- -- The main loops -- -- The sync block of the image contents. for _, lcv_tgt in ipairs( lcv_tgtlist_imgcms ) do sync { default.rsync, source="/home/imgcms/images/", target=lcv_tgt, rsync = { archive = true, compress = true, rsh = lcv_rsh, } } end -- The sync block of the cgi contents. for _, lcv_tgt in ipairs( lcv_tgtlist_cgicms ) do sync { default.rsync, source="/home/cgicms/cgi-bins/", target=lcv_tgt, rsync = { archive = true, compress = true, rsh = lcv_rsh, } } end

Step4: Start the lsyncd and test the configurations.


You need to make the log directory: /var/log/lsyncd, if you start the lsyncd daemon initially.

[org ]# mkdir /var/log/lsyncd
[org ]# systemctl start lsyncd

There are tests for creating the file, changing the contents, changing the access mode and renaming under the symbolic link.


[org webmgr]$ touch ~/contents/images/owneriswebmgrundersymlinks.txt
[org webmgr]$ echo "Watch that the file size is changing" > ~/contents/images/owneriswebmgrundersymlinks.txt
[org webmgr]$ chmod 600 ~/contents/images/owneriswebmgrundersymlinks.txt
[org webmgr]$ mv ~/contents/images/owneriswebmgrundersymlinks.txt ~/contents/images/webmgrthroughsymlnk.txt

These tests are deleting files.


[org cgicms]$ touch ~/cgi-bins/cgi{1..9}.cgi
[org cgicms]$ rm -f ~/cgi-bins/cgi{5..9}.cgi

You should monitor the target directories in the remote hosts (tgt1, tgt2), while the tests are performing.
For example, on the tgt1 hosts as follows.


[tgt1 wegmgr]$ watch -d -n1 ls -lR ~/contents
Every 1.0s: ls -lR /home/webmgr/contents Tue Nov 29 18:29:41 2016 /home/webmgr/contents: total 0 drwxrwxr-x. 2 webmgr webmgr 66 Nov 29 18:29 cgi-bins drwxrwxr-x. 2 webmgr webmgr 36 Nov 29 18:28 images /home/webmgr/contents/cgi-bins: total 0 -rw-rw-r--. 1 webmgr webmgr 0 Nov 29 18:27 cgi1.cgi -rw-rw-r--. 1 webmgr webmgr 0 Nov 29 18:27 cgi2.cgi -rw-rw-r--. 1 webmgr webmgr 0 Nov 29 18:27 cgi3.cgi -rw-rw-r--. 1 webmgr webmgr 0 Nov 29 18:27 cgi4.cgi /home/webmgr/contents/images: total 4 -rw-------. 1 webmgr webmgr 37 Nov 29 18:24 webmgrthroughsymlnk.txt

Thursday, November 24, 2016

The configuration of FTPS - FTP over SSL/TLS with vsftpd

Introduction:

The implementation of the FTPS service with vsftpd(official site), when I had simulated the backend tasks.

Environment:

The vsftpd package was installed by yum
 Hostname: repov1.host.local
 OS: CentOS 7.2
 Packagename: vsftpd
 Version: 3.0.2-11.el7_2

Configuration steps:


Step1: Issuing a self-signed certificate with OpenSSL


I will create the certificate that signed with own root CA.

1. Issuing the self-signed certificate for Certificate Authority

# openssl genrsa -out /etc/pki/CA/private/root-cakey.pem 2048

# openssl req -x509 -nodes -new -days 3650 -sha256 -key /etc/pki/CA/private/root-cakey.pem \
          -out /etc/pki/CA/root-cacert.pem
You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [XX]:JP State or Province Name (full name) []:Tokyo Locality Name (eg, city) [Default City]:Minato Organization Name (eg, company) [Default Company Ltd]:Local Company Organizational Unit Name (eg, section) []:Infrastructure Division Common Name (eg, your name or your server's hostname) []:
Local Company Root CA
Email Address []:
2. Issuing the self-signed certificate for vsftpd

# openssl genrsa /etc/pki/tls/private/repov1.host.local-key.pem 2048

# openssl req -new -nodes -sha256 -out /etc/pki/tls/repov1.host.local.csr \
          -key /etc/pki/tls/private/repov1.host.local-key.pem

You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [XX]:JP State or Province Name (full name) []:Tokyo Locality Name (eg, city) [Default City]:Minato Organization Name (eg, company) [Default Company Ltd]:Local Company Organizational Unit Name (eg, section) []:Infrastructure Division Common Name (eg, your name or your server''s hostname) []:repov1.host.local Email Address []: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []:
# openssl x509 -sha256 -days 3650 -req -in /etc/pki/tls/repov1.host.local.csr \ -CAcreateserial -CA /etc/pki/CA/root-cacert.pem -CAkey /etc/pki/CA/private/root-cakey.pem \ -out /etc/pki/tls/certs/repov1.host.local-cert.pem

3. Deployment of the self-signed certificate to FTPS client servers

I had copied the certificate to /etc/pki/tls/certs/repov1.host.local-cert.pem on the FTPS client servers

Step2: Configuration for vsftpd.conf


The following is a snippet of FTPS configurations, not all configurations. (config options manual)

# vim /etc/vsftpd/vsftpd.conf
#> FTPS configuration #+ enable the SSL/TLS ssl_enable=YES #+ the protocols whether enabled or not ssl_tlsv1=YES #+ allow and force anonymous, local users for using SSL/TLS #- for anonymous users allow_anon_ssl=YES force_anon_data_ssl=YES force_anon_logins_ssl=YES #- for local users force_local_data_ssl=YES force_local_logins_ssl=YES #+ specify the certificate and private key files rsa_cert_file=/etc/pki/tls/certs/repov1.host.local-cert.pem rsa_private_key_file=/etc/pki/tls/private/repov1.host.local-key.pem #+ change the control and data port, 990/TCP for control channel, 989/TCP for data channel listen_port=990 ftp_data_port=989 #+ if you started daemon with the passive mode, you would need to limit the passive ports. pasv_min_port=60000 pasv_max_port=60010

Step3: Test the FTPS service


I used lftp client here to verify the FTPS configurations, but WinSCP can be used here too.
And FTPS requires two connections per session like FTP: a control channel and a data channel,
you need to allow the ports before test if firewalld or iptables is activated.


$ lftp -e 'set ftp:ssl-force true;set ssl:ca-file "/etc/pki/tls/certs/repov1.host.local-cert.pem"' \
       -u anonymous repov1.host.local
Password: lftp anonymous@repov1.host.local:~> ls ---- Connecting to repov1.host.local (192.168.122.84) port 990 <--- 220 (vsFTPd 3.0.2) ---> FEAT <--- 211-Features: <--- AUTH TLS ... snip ... ---> AUTH TLS <--- 234 Proceed with negotiation. ---> OPTS UTF8 ON Certificate: C=JP,ST=Tokyo,L=Minato,O=Local Company,OU=Infrastructure Division,CN=repov1.host.local Issued by: C=JP,ST=Tokyo,L=Minato,O=Local Company,OU=Infrastructure Division,CN=Local Company Root CA Trusted ...snip...

Test with WinSCP as follows.