mariadb-seal

Reset ค่า password root ให้แก่ mysql และ mariadb

ปัญหาที่เกิดขึ้นบ่อย คือต้องการ ที่จะ reset password เนื่องจากไม่ทราบว่าเดิมใข้ค่า password อะไรสามารถทำได้ ง่ายๆ มีขั้นตอนดังนี้

ขั้นตอนที่ 1

ขั้นตอนที่ 2 หยุดการทำงานของ mariadb-server และ start แบบ safe

ขั้นตอนที่ 3 Login แบบไม่ต้องใช้ password

ขั้นตอนที่ 4 ตั้งค่า password ใหม่

ขั้นตอนที่ 5 หยุดการทำงาน แบบ safe และค่อย start แบบปรกติ

มาเริ่มต้นใช้งาน jenkins และ Docker

ทดสอบการใช้งาน jenkins ผ่านทาง Docker

1 ติดตั้ง Docker Binary

2 ดาวโหลด jenkins image

3 เริ่มต้น Docker

4 ดูค่า temporary password

8 เปิด browser localhost:8080 และนำค่า password มาใส่

หลังจากกรอก password ก็ติดตั้ง plugin


สร้าง admin user และ กำหนด password

เริ่มต้น การใช้งาน


หยุด Docker

มาเริ่มต้นสร้าง marven project ด้วย command line

Test file Apptest.java

กด manage Jenkins เพื่อติดตั้ง maven plugin เลือก plugin แล้วก็ Download now and install after restart


สร้าง job ใหม่ ด้วยการกด Create new jobs


ตั้งชื่อ mavendemo เลือก Maven project กด ok

ติดตั้ง jdk , maven

ใน section Global Tool Configuration
jdk

maven

note local install

Dev Environment Fedora 28

กำหนดการของการ release fedora 28
2018-04-03 Beta Release (Target #1)
2018-04-17 Final Freeze (*)
2018-05-01 Fedora 28 Final Release (GA) (Preferred Target)
2018-05-08 Fedora 28 Final Release (GA) (Target #1)

ติดตั้ง Dev Environment สำหรับ Fedora 28 วางแผนการใช้งาน Vagrant บน Linux libvirt ไม่ใช่ผ่านทาง Virtualbox มีขั้นตอนดังนี้
1) ติดตั้ง package ที่จำเป็น และ ต้องมีการ enable vt-x ใน Bios ก่อน

2) install Virt-manager เพื่อใช้เป็น gui

default network libvirt จะใช้ network ชื่อ virbr0 192.168.122.0/24

3 ต่อมาให้ติดตั้ง vagrant plugin

file Vagrantfile ที่ปรับเปลี่ยนตามความต้องการ

เริ่มต้น boot image

หากต้องการใช้งาน image อื่นสามารถไปค้นหาได้ที่ http://www.vagrantbox.es/ และ https://app.vagrantup.com/boxes/search

4 Connect ไปยัง box

5 ติดตั้ง Docker ใน vm ที่สร้างจาก Vagrant

6 ทดสอบ Django
– สร้าง directory ว่างๆ
– สร้าง Dockerfile

สร้าง Dockerfile
สร้าง requirements.txt
สร้าง docker-compose.yml

install docker-compose

ติดตั้ง openstreet map บน ubuntu 16.04

ขั้นตอนการติดตั้ง openstreet map บน ubuntu server มีขั้นตอนดังต่อไปนี้
1). update server

2). ติดตั้ง dependencies

3). ติดตั้ง postgres

จะสร้าง user ชื่อว่า postgres ในระหว่างการติดตั้ง ที่มีสิทธิในการเเข้าใช้ ฐานข้อมูล ถือว่าเป็น user root ของ postgres database การใช้งานฐานข้อมูล ในครั้งแรก ให้ทำการ login เป็น postgres ต่อมาจะสร้าง database ชื่อ osm และ database ชื่อ gis

สร้าง hstore และ postgis extension

ออกจาก postgres user


4) ติดตั้ง osm2pgsql เป็น เครื่องเมื่อที่จะ บันทึก openstreep map สู่ ฐานข้อมูล postgres


5) ติดตั้ง Mapnik เป็นเครื่องมือ ที่ใช้สำหรับการ render ทำงานร่วมกับ mod_tile

6) ติดตั้ง mod_tile

7). สร้าง unix user ชื่อ osm เพื่อเป็น user สำหรับการใช้งาน

8) ติดตั้ง carto ด้วย node เพื่อใช้ compile carto project ให้ mapnik.xml

9) Download openstreetmap-carto version ล่าสุด และ convert project.mml สู่ mapnik.xml

10) Download ข้อมูลแผนที่จาก http://download.geofabrik.de/ เลือก Asia > Thailand

11) บันทึกใน ฐานข้อมูล

อธิบายคำสั่ง
-d gis Database ที่ใช้ชื่อ gis
--create Load data สู่ ฐานข้อมูล ที่ยังว่าง
--slim ใช้ตาราง slim ตอน rendering
-G
--hstore
--tag-transform-script
-C 2500 พื้นที่หน่วยความจำที่ osm2pgsql ใช้ในการ import
--number-processes 1 ใช้ จำนวน CPU
verify


12). Download shapefile

13). Download Fonts

14 ตั้งค่า

15). ตั้งค่า apache

บันทึก file

16) เพิ่ม virtual host

เพิ่มในระหว่างบันทัดของ “ServerAdmin” และ “DocumentRoot”

17) restart server

18 start service renderd

19) กำหนดให้ renderd ทำงาน ใน backgroud mode

20 ทดสอบร่วมกับ openlayer

สร้าง file index.html และแทนค่า your-ip ด้วย ip ของ server

Map Server part 1 : ติดตั้ง QGIS สำหรับ Mac OS X

ติตดั้ง QGIS บน mac os ล่าสุดจะสามารถใช้งาน library ของ python3 ดังนั้น เครื่อง mac จะต้องทำการติดตั้ง python3 ให้เรียบร้อยดังนี้ ก่อนอื่นให้ทำการตรวจ version ที่ใช้งานอยู่ในปัจจุบัน

 
1) ติดตั้ง  python3  ด้วย homebrew

 
2 ไปยัง  https://www.qgis.org/en/site/
และทำการ กด Download จะไปยังหน้า Download เลือก สำหรับ mac กดเลือก KyngChaos QGIS download page

เลือก Current version

หลังจาก Download จะได้ package ดังนี้

ให้ติดตั้ง package ตามลำดับดังนี้
1 install GDAL Complete.pkg

2 install QGIS.pkg
เนื่องจากเราติดตั้ง python ด้วย brew python path จะทำการติดตั้งไว้ที่ /usr/local/Cellar/python3/3.6.4_4/ (version จะเป็น 3.6.x_y) จึงต้องทำการสร้าง symbolic link โดยใช้สิทธิ sudo
หลังจากนั้นจึงทำการติดตั้ง QGIS.pkg

ก่อนจะเริ่มต้นการใช้งาน ให้ทำการติดตั้ง python module ด้วยคำสั่ง pip3

เพิ่มเติม

NextCloud 13 บน CentOS 7 ตอนที่ 2

ในบทนี้ก็จะเน้นการใช้งาน nextcloud ที่ได้ทำการติดตั้งใน ตอนที่ 1 หากท่านยังไม่ได้อ่าน ในบทดังกล่าว แนะนำให้ทำการติดตั้งให้เรียบร้อยก่อน เนื่องจากการใช้งาน nextcloud ผู้ใช้งานสามารถ download client ที่ได้พัฒนาไว้พร้อมสำหรับการใช้งานได้ทันที และ application จะทำงานได้ทุก platform ไม่ว่าจะใช้งาน บน window, mac, linux

1) ก่อนการใช้งานผ่าน client ให้ login ด้วย user admin และ Click ที่มุมขวาบน และ เลือก “user”

สร้าง user อื่นที่สามารถ ใน องค์กร สามารถ สร้างได้ดังนี้

ในตัวอย่างเช่น username “sawangpong” พร้อมกับ สร้าง group ของ user เพื่อจัดกลุ่ม user ได้ทันที เช่นกลุ่มชื่อ management

สามารถกำหนด โควต้าได้จาก Action menu ที่อยู่ท้ายบรรทัด

ลองทดสอบการ login ด้วย user ใหม่ เพื่อกรอกข้อมูลในส่วนบุคคล เพิ่มเติมโดยการเพิ่ม user จะทำจาก backend ด้วย useradmin เท่านั้น หลังจากที่ user ได้รับ username/password แล้วก็จะต้องมาเพิ่มเติมข้อมูลส่วนบุคคลด้วยตนเอง

การใช้งานผ่านทาง davs://, dav:// โปรโตคอล

โดยให้ทำการใช้ address ตามรูปแบบ dav://IP_NEXTCLOUD/nextcloud/remote.php/webdav/
สำหรับ linux ให้เปิด file browser เลือก “other locations” ให้ใส่ address ที่กล่องข้อความด้านล่าง และกดปุ่ม connect

เมื่อ login สำเร็จจะทำให้เราสามารถเชื่อมต่อการใช้งานไปยัง nextcloud ผ่านทาง โปรโตคอล webdev ได้สำเร็จ


การใช้งานผ่านทาง macos

เปิด finder > Go > Connect to Server และใช้ url ตาม format ดังนี้ http://IP_NEXTCLOUD/nextcloud/remote.php/webdav/

จะมีกล่องข้อความปรากฎดังนี้ เพื่อใส่ค่า server

กล่อง input สำหรับ username / password

เมื่อ login ได้แล้วก็สามารถใช้งานได้ทันที

การใช้งาน บน window10
Download nextcloud client https://nextcloud.com/install/

เลือก Desktop Client

เริ่ม Download และ install

ขั้นตอนต่อไป

ขั้นตอนต่อไป

ขั้นตอนต่อไป

ขั้นตอนต่อไป

ขั้นตอนต่อไป

ขั้นตอนต่อไป

ขั้นตอนต่อไป

ขั้นตอนต่อไป

สำหรับ Desktop Client สามารถที่จะเลือกการทำงานได้ทั้งที่เป็น local Disk หรือ ทำงานผ่าน browser จะพบว่า การใช้งาน nextcloud มีความยืดหยุนในการใช้งานอย่างมาก เหมาะที่จะนำมาใช้งานองค์ หากมีข้อสงสัยประการใด ก็สามารถสอบถามเพิ่มเติมได้

NextCloud 13 บน CentOS 7 ตอนที่ 1

ในปัจจุบันหลายหน่วยงานมองหา Solution ที่ต้องการเก็บข้อมูลที่มีสะดวกปลอดภัยง่ายต่อการใช้งาน หลายคนคงนึกถึง Google Drive , OneDrive, หรือ Dropbox ที่หลายคนคงคุ้นเคยในการใช้อยู่ในปัจจุบัน ที่มีการให้การบริการในรูปแบบของ Cloud Service อย่างแน่นอน แต่หากเราต้องการสร้าง Storage ในรูปแบบเดียวกันแต่สามารถใช้งานได้ภายในองค์กรเอง เป็นลักษณะ (one premise)  คงจะดีเนื่องจากไม่จำเป็นต้องเปลือง bandwidth และสามารถที่จะใช้ทรัพยากรที่มีอยู่ได้อย่างมีประสิทธิ ในวันนี้จะนำเสนอการติดตั้ง Solution  NextCloud ที่นำมาสนับสนุนการทำงานในองค์กรได้อย่างมีประสิทธิภาพ นองจากในตอนนี้จะสอนวิธีการติดตั้งอย่างละเดียดถูกต้องและใช้งานความอย่างปลอดภัยแล้ว จะแนะนำวิธีการใช้งาน ผ่านวิธีการ Connect โดยตรงผ่าน pc (Mapdrive) มายัง nextCloud

สิ่งที่ต้องเตรียม

  1. Server ที่จะติดตั้งการใช้งาน ให้ติดตั้ง Centos7 รอไว้ให้เรียบร้อย (ไม่ต้องปิด  SElinux)
  2. วางแผนพื้นการใช้งาน nextcloud ในกรณีนี้ เตรียมพื้นที่การใช้งานไว้ 100G สำหรับใช้งาน Storage

1). ติดตั้ง software ที่จำเป็น

เลือกฐานข้อมูล ที่สนับสนุนการทำงาน โดยเลือกได้เป็น sqlite, mysql/mariadb, postgreSQL ซึ่งจะเลือกติดตั้งดังนี้ (เลือกอย่างใดอย่างหนึ่ง)
1.1) สำหรับการติดตั้งใช้งาน mariadb

– แทนค่า YOUR_PASSWORD_HERE ด้วย password ที่มีความปลอดภัย

1.2) สำหรับการติดตั้งการใช้งาน postgresl

สำหรับการใช้งาน postgres จะต้องมีการตั้งค่าวิธีการ authentication method โดยเปลี่ยนค่าจาก ident ที่เป็นค่า default ให้กลาย md5 คือต้องมาใช้ การ authentication แบบ username password มีขั้นตอนดังนี้

– แทนค่า PASSWORD_POSTGRES ที่ต้องการ

เปลี่ยนจาก

เปลี่ยนเป็น

รีสตาร์ท

2). ติดตั้ง nextcloud 13 ใน version ล่าสุดได้จากขั้นตอนดังนี้

3). สร้าง config file /etc/httpd/conf.d/nextcloud.conf

4). ตั้งค่า Apache ให้ใช้งาน SELinux

5). Verify

6). รีสตาร์ท http

7).สร้าง กฎของไฟล์วอล

8). เปิด http://ip_address/nextcloud/ เพื่อสร้าง user admin เป็น user admin และกดปุ่ม Finish up

เมื่อเสร็จสิ้น

รูปแบบการเชื่อมต่อการใช้งาน
1). Destop App (https://nextcloud.com/install/#install-clients)
2). Android (https://play.google.com/store/apps/details?id=com.nextcloud.client)
3). AppStore (https://itunes.apple.com/us/app/nextcloud/id1125420102?mt=8)

ติดตามการใช้งาน ในตอนที่ 2 ต่อไป ตอน2

ป้องกันความปลอดภัย ด้วย TLS สำหรับ Apache บน Centos 7

บทนำ
TLS ย่อมากจาก “Transport layer Security” เพื่อรองรับการสื่อสาร ระหว่าง webserver และ client ให้มีความปลอดภัย โดยการใช้ระบบ certificate เพื่อเป็นการยืนยันว่า server เป็น server ที่ client ต้องการติดต่อด้วยจริง การใช้งานสามารถใช้งาน self-signed certificate หรือ certificate ที่ยืืนยันตนเอง ถึงแม้วิธีนี้จะไม่ได้ยืนยันจาก ผู้ให้การรับรอง (Trusted cerfificate authorities) แต่ก็สามารถใช้สำหรับการเข้ารหัสการสื่อสารได้

1 ติดตั้งโปรแกรม

sudo yum install https mod_ssl
sudo systemctl enable httpd.service
sudo systemctl start httpd.service

2 สร้าง Certificate
หลังจากการติดตั้งแล้ว ให้ทำการสร้าง certificate ด้วยการสร้าง directory สำหรับเก็บ certificate ที่สร้างขึ้น โดยตั้งชื่อ certificate ว่า “apache.crt” และ key ชื่อ “apache.key” คำสั่งที่ใช้ในการสร้าง คือ openssl

sudo mkdir /etc/httpd/ssl
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/httpd/ssl/apache.key -out /etc/httpd/ssl/apache.crt

ตอบคำถามระหว่างการสร้าง certificate

Country Name (2 letter code) [XX]:TH
State or Province Name (full name) []:Bangkok
Locality Name (eg, city) [Default City]:Bangkok
Organization Name (eg, company) [Default Company Ltd]:ITBAKERY 
Organizational Unit Name (eg, section) []:WEB
Common Name (eg, your name or your server's hostname) []:web.example.com
Email Address []:info@example.com

# ls -l /etc/httpd/ssl/
total 8
-rw-r--r--. 1 root root 1424 Nov  1 18:02 apache.crt
-rw-r--r--. 1 root root 1704 Nov  1 18:02 apache.key

3 สรุป options ของคำสั่ง openssl

req -x509: ระบุประเภทของ certificate ที่ต้องการคือ x509 รองรับมาตรฐาน public key infrastructure ที่ใช้สำหรับ ssl, tls เป็นการทำงานร่วมกันระหว่าง key และ certificate
-nodes: ยกเลิกการใช้ passphrase ของ key ที่สร้างขึ้น
-days 365: อายุของ certificate ที่สร้างขึ้น
-newkey rsa:2048: ขนาดความยาวของ key ที่สร้างขึ้น ให้มีขนาด 2048bit
-keyout: ระบุชื่อของ private key ที่สร้างขั้น
-out: ระบุชื่อ certificate

4 ตั้งค่า VirtualHost สำหรับการใช้ cert
ไฟล์ /etc/httpd/conf.d/ssl.conf มีอยู่แล้ว

sudo vi /etc/httpd/conf.d/ssl.conf

4.1 uncomment บรรทัด DocumentRoot

grep -n "DocumentRoot" /etc/httpd/conf.d/ssl.conf
59:#DocumentRoot "/var/www/html"

DocumentRoot "/var/www/example.com/public_html"

4.2 uncomment บรรทัด ServerName

grep -n ServerName /etc/httpd/conf.d/ssl.conf 
60:#ServerName www.example.com:443

ServerName www.example.com:443

4.3 แก้ไขตำแหน่ง/ชื่อของ key และ certificate

grep -n SSLCertificateFile  /etc/httpd/conf.d/ssl.conf
100:SSLCertificateFile /etc/pki/tls/certs/localhost.crt

แก้เป็น
SSLCertificateFile /etc/httpd/ssl/apache.crt

rep -n SSLCertificateKeyFile  /etc/httpd/conf.d/ssl.conf
107:SSLCertificateKeyFile /etc/pki/tls/private/localhost.key

แก้เป็น
SSLCertificateKeyFile /etc/httpd/ssl/apache.key

5 เริ่มต้นการใช้ cert ด้วยการ restart apache

sudo apachectl restart

การทดสอบ
ตรวจสอบ ip ของ eth0

ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1

192.168.121.14

เพิ่ม www.example.com ใน /etc/hosts

echo "192.168.121.14 www.example.com"  >> /etc/hosts

selection_023

ให้กดยอมรับ ADVANDCED จะได้ว่า
selection_025

Openstack Mitaka with Packstack (RHEL7,CentOS7)

Packstack คืออะไร
Packstack คือ เครื่องมือที่ใช้สำหรับการติดตั้ง Openstack แบบ Cluster สามารถติดตั้งแบบ all-in-one เพื่อให้เราสามารถเรียนรู้การใช้งาน หรือจะติดตั้งแบบ multinode เพื่อใช้งานได้ด้วยการสร้างและปรับแต่งค่าของ answerfille เบื้องหลังการทำงานจะใช้ config management แบบ Puppet ที่มี puppet module ทำหน้าเป็น template สำหรับการติดตั้ง openstack หลังจากติดตั้งแล้วสามารถดูได้ที่ /usr/share/openstack-puppet/modules/

$ ls /usr/share/openstack-puppet/modules/
aodh        elasticsearch  java             module-data       openstacklib  ssh       uchiwa
apache      firewall       kafka            mongodb           pacemaker     staging   vcsrepo
cassandra   fluentd        keepalived       mysql             packstack     stdlib    vlan
ceilometer  git            keystone         n1k_vsm           qpid          swift     vswitch
ceph        glance         kibana3          nagios            rabbitmq      sysctl    xinetd
certmonger  gnocchi        kmod             neutron           redis         tempest   zaqar
cinder      haproxy        manila           nova              remote        timezone  zookeeper
concat      heat           memcached        nssdb             rsync         tomcat
contrail    horizon        midonet          ntp               sahara        tripleo
corosync    inifile        mistral          opendaylight      sensu         trove
datacat     ironic         module-collectd  openstack_extras  snmp          tuskar

เตรียม infrastructure
สร้าง directory ชื่อ openstack และภายในมี Vagrantfile ดังนี้

Vagrantfile

# -*- mode: ruby -*-
# vi: set ft=ruby :

$script = <<SCRIPT
echo "run provisioning..."
echo 'root:password' | sudo chpasswd
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
setenforce 0
yum install -y epel-release
yum install -y centos-release-openstack-mitaka
yum update -y
yum install -y openstack-packstack
SCRIPT

Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  config.vm.define :controller do |node|
            node.vm.network :private_network, :ip => "10.0.0.10"
            node.vm.network :private_network, :ip => "20.0.0.10"
            node.vm.provider :libvirt do |domain|
              domain.uri = 'qemu+unix:///system'
              domain.driver = 'kvm'
              domain.host = "server1.example.com"
              domain.memory = 8192
              domain.cpus = 4
              domain.nested = true
              domain.volume_cache = 'none'
              domain.storage :file, :size => '20G'
            end
    node.vm.provision "shell", inline: $script
  end
  config.vm.define :compute do |node|
            node.vm.network :private_network, :ip => "10.0.0.11"
            node.vm.network :private_network, :ip => "20.0.0.11"
            node.vm.provider :libvirt do |domain|
              domain.uri = 'qemu+unix:///system'
              domain.driver = 'kvm'
              domain.host = "server2.example.com"
              domain.memory = 4096
              domain.cpus = 2
              domain.nested = true
              domain.volume_cache = 'none'
            end
    node.vm.provision "shell", inline: $script
  end
end
$ vagrant up --provider libvirt
$ vagrant status
Current machine states:

controller                running (libvirt)
compute                   running (libvirt)

$ vagrant halt
$ vagrant up

$ vagrant ssh controller
$ sudo su -
$ getenforce
Disabled

$ sudo systemctl disable firewalld
$ sudo systemctl stop firewalld
$ sudo systemctl disable NetworkManager
$ sudo systemctl stop NetworkManager
$ sudo systemctl enable network
$ sudo systemctl start network

เตรียม cinder list
Cinder Service กำหนดให้ใช้ disk จาก volume group ที่ชื่อ cinder-volumes และใน config Vagrant ได้มีการเพิ่ม disk ให้แก่ vm 1 ลูก mount อยู่ที่ /dev/vdb

$ sudo su -
# fdisk -l | grep vdb
# Disk /dev/vdb: 21.5 GB, 21474836480 bytes, 41943040 sectors

# pvcreate /dev/vdb
# vgcreate cinder-volumes /dev/vdb
# vgs
  VG             #PV #LV #SN Attr   VSize  VFree  
  VolGroup00       1   2   0 wz--n- 39.50g 320.00m
  cinder-volumes   1   0   0 wz--n- 20.00g  20.00g

สร้างไฟล์ answerfile001.txt จากคำสั่ง packstack

# cd /root
# packstack --gen-answer-file  answerfile001.txt

# ip a s eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 52:54:00:b5:b5:fa brd ff:ff:ff:ff:ff:ff
    inet 192.168.121.147/24 brd 192.168.121.255 scope global dynamic eth0
       valid_lft 1808sec preferred_lft 1808sec
    inet6 fe80::5054:ff:feb5:b5fa/64 scope link 
       valid_lft forever preferred_lft forever

# ip a s eth1
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 52:54:00:7b:64:20 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.10/24 brd 10.0.0.255 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::5054:ff:fe7b:6420/64 scope link 
       valid_lft forever preferred_lft forever

แก้ ip ของ management network
packstack จะทำการเอาค่า ip จาก eth0 มาเป็นค่าของ management ip ซึ่งคือ 192.168.121.147 ค่า ip จะเป็นค่าที่อยู่ใน answerfile001.txt

# grep HOST answerfile001.txt
CONFIG_CONTROLLER_HOST=192.168.121.9
CONFIG_COMPUTE_HOSTS=192.168.121.9
CONFIG_NETWORK_HOSTS=192.168.121.9
CONFIG_VCENTER_HOST=
CONFIG_STORAGE_HOST=192.168.121.9
CONFIG_SAHARA_HOST=192.168.121.9
CONFIG_AMQP_HOST=192.168.121.9
CONFIG_MARIADB_HOST=192.168.121.9
...

# eth0_ip=$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)
# echo $eth0_ip
192.168.121.9

# eth1_ip=$(ip addr show eth1 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)
# echo $eth1_ip
10.0.0.10

# sed -i.orig "s/$eth0_ip/$eth1_ip/g" answerfile001.txt 
# grep HOST answerfile001.txt 
CONFIG_CONTROLLER_HOST=10.0.0.10
CONFIG_COMPUTE_HOSTS=10.0.0.10
CONFIG_NETWORK_HOSTS=10.0.0.10
CONFIG_VCENTER_HOST=
CONFIG_STORAGE_HOST=10.0.0.10
CONFIG_SAHARA_HOST=10.0.0.10
CONFIG_AMQP_HOST=10.0.0.10
CONFIG_MARIADB_HOST=10.0.0.10
CONFIG_CINDER_NETAPP_HOSTNAME=

ปรับแต่งค่าใน answerfile001.txt

CONFIG_KEYSTONE_ADMIN_PW=password
CONFIG_LBAAS_INSTALL=y
CONFIG_NEUTRON_METERING_AGENT_INSTALL=y
CONFIG_NEUTRON_FWAAS=y

CONFIG_NEUTRON_ML2_TYPE_DRIVERS=vlan,vxlan,gre,flat,local
CONFIG_NEUTRON_ML2_TENANT_NETWORK_TYPES=local,vlan,gre,vxlan
CONFIG_NEUTRON_ML2_VLAN_RANGES=physnet2:1:1000

CONFIG_NEUTRON_OVS_BRIDGE_MAPPINGS=physnet2:br-eth2
CONFIG_NEUTRON_OVS_BRIDGE_IFACES=br-ex:eth0,br-eth2:eth2
CONFIG_HEAT_INSTALL=y

CONFIG_HEAT_CFN_INSTALL=y
CONFIG_TROVE_INSTALL=y
CONFIG_HORIZON_SSL=y
CONFIG_PROVISION_DEMO=n

แก้ไขด้วย crudini

# yum install crudini rubygems -y
# answerfile=answerfile001.txt

# crudini --set $answerfile general CONFIG_KEYSTONE_ADMIN_PW password
# crudini --set $answerfile general CONFIG_LBAAS_INSTALL y
# crudini --set $answerfile general CONFIG_NEUTRON_METERING_AGENT_INSTALL y
# crudini --set $answerfile general CONFIG_NEUTRON_FWAAS y

# crudini --set $answerfile general CONFIG_NEUTRON_ML2_TYPE_DRIVERS vlan,vxlan,gre,flat,local
# crudini --set $answerfile general CONFIG_NEUTRON_ML2_TENANT_NETWORK_TYPES local,vlan,gre,vxlan

# crudini --set $answerfile general CONFIG_NEUTRON_ML2_VLAN_RANGES physnet2:1:1000

# crudini --set $answerfile general CONFIG_NEUTRON_OVS_BRIDGE_MAPPINGS ext-net:br-ex,physnet2:br-eth2
# crudini --set $answerfile general CONFIG_NEUTRON_OVS_BRIDGE_IFACES br-ex:eth0,br-eth2:eth2

# crudini --set $answerfile general CONFIG_HEAT_INSTALL y
# crudini --set $answerfile general CONFIG_TROVE_INSTALL y

# crudini --set $answerfile general CONFIG_HEAT_CFN_INSTALL y
# crudini --set $answerfile general CONFIG_HORIZON_SSL y
# crudini --set $answerfile general CONFIG_PROVISION_DEMO n
# crudini --set $answerfile general CONFIG_CINDER_VOLUMES_CREATE n

# packstack --answer-file answerfile001.txt

Welcome to the Packstack setup utility

The installation log file is available at: /var/tmp/packstack/20160823-023836-_wAfqR/openstack-setup.log

Installing:
Clean Up                                             [ DONE ]
Discovering ip protocol version                      [ DONE ]
Setting up ssh keys                                  [ DONE ]
Preparing servers                                    [ DONE ]
Pre installing Puppet and discovering hosts' details [ DONE ]
Adding pre install manifest entries                  [ DONE ]
Setting up CACERT                                    [ DONE ]
Adding AMQP manifest entries                         [ DONE ]
Adding MariaDB manifest entries                      [ DONE ]
Adding Apache manifest entries                       [ DONE ]
Fixing Keystone LDAP config parameters to be undef if empty[ DONE ]
Adding Keystone manifest entries                     [ DONE ]
Adding Glance Keystone manifest entries              [ DONE ]
Adding Glance manifest entries                       [ DONE ]
Adding Cinder Keystone manifest entries              [ DONE ]
Checking if the Cinder server has a cinder-volumes vg[ DONE ]
Adding Cinder manifest entries                       [ DONE ]
Adding Nova API manifest entries                     [ DONE ]
Adding Nova Keystone manifest entries                [ DONE ]
Adding Nova Cert manifest entries                    [ DONE ]
Adding Nova Conductor manifest entries               [ DONE ]
Creating ssh keys for Nova migration                 [ DONE ]
Gathering ssh host keys for Nova migration           [ DONE ]
Adding Nova Compute manifest entries                 [ DONE ]
Adding Nova Scheduler manifest entries               [ DONE ]
Adding Nova VNC Proxy manifest entries               [ DONE ]
Adding OpenStack Network-related Nova manifest entries[ DONE ]
Adding Nova Common manifest entries                  [ DONE ]
Adding Neutron VPNaaS Agent manifest entries         [ DONE ]
Adding Neutron FWaaS Agent manifest entries          [ DONE ]
Adding Neutron LBaaS Agent manifest entries          [ DONE ]
Adding Neutron API manifest entries                  [ DONE ]
Adding Neutron Keystone manifest entries             [ DONE ]
Adding Neutron L3 manifest entries                   [ DONE ]
Adding Neutron L2 Agent manifest entries             [ DONE ]
Adding Neutron DHCP Agent manifest entries           [ DONE ]
Adding Neutron Metering Agent manifest entries       [ DONE ]
Adding Neutron Metadata Agent manifest entries       [ DONE ]
Adding Neutron SR-IOV Switch Agent manifest entries  [ DONE ]
Checking if NetworkManager is enabled and running    [ DONE ]
Adding OpenStack Client manifest entries             [ DONE ]
Adding Horizon manifest entries                      [ DONE ]
Adding Swift Keystone manifest entries               [ DONE ]
Adding Swift builder manifest entries                [ DONE ]
Adding Swift proxy manifest entries                  [ DONE ]
Adding Swift storage manifest entries                [ DONE ]
Adding Swift common manifest entries                 [ DONE ]
Adding Heat manifest entries                         [ DONE ]
Adding Heat CloudFormation API manifest entries      [ DONE ]
Adding Gnocchi manifest entries                      [ DONE ]
Adding Gnocchi Keystone manifest entries             [ DONE ]
Adding MongoDB manifest entries                      [ DONE ]
Adding Redis manifest entries                        [ DONE ]
Adding Ceilometer manifest entries                   [ DONE ]
Adding Ceilometer Keystone manifest entries          [ DONE ]
Adding Aodh manifest entries                         [ DONE ]
Adding Aodh Keystone manifest entries                [ DONE ]
Adding Trove Keystone manifest entries               [ DONE ]
Adding Trove manifest entries                        [ DONE ]
Adding Nagios server manifest entries                [ DONE ]
Adding Nagios host manifest entries                  [ DONE ]
Copying Puppet modules and manifests                 [ DONE ]
Applying 10.0.0.10_prescript.pp
....
10.0.0.10_nagios.pp:                                 [ DONE ]       
10.0.0.10_nagios_nrpe.pp:                            [ DONE ]       
Applying Puppet manifests                            [ DONE ]
Finalizing                                           [ DONE ]

 **** Installation completed successfully ******

Additional information:
 * Time synchronization installation was skipped. Please note that unsynchronized time on server instances might be problem for some OpenStack components.
 * File /root/keystonerc_admin has been created on OpenStack client host 10.0.0.10. To use the command line tools you need to source the file.
 * NOTE : A certificate was generated to be used for ssl, You should change the ssl certificate configured in /etc/httpd/conf.d/ssl.conf on 10.0.0.10 to use a CA signed cert.
 * To access the OpenStack Dashboard browse to https://10.0.0.10/dashboard .
Please, find your login credentials stored in the keystonerc_admin in your home directory.
 * To use Nagios, browse to http://10.0.0.10/nagios username: nagiosadmin, password: 292931d483bb4c13
 * The installation log file is available at: /var/tmp/packstack/20160823-024129-glQQuf/openstack-setup.log
 * The generated manifests are available at: /var/tmp/packstack/20160823-024129-glQQuf/manifests

เปิด browser https://10.0.0.10/dashboard
ssl accept
Selection_729

login ด้วย admin/password
login

Selection_731

Openvswitch Network
ทดสอบ ดูว่า Openvswitch สร้าง bridge อะไรให้กับระบบบ้าง

# ovs-vsctl show
c319424e-43f2-4440-ba92-0f57b4ec3bf3
    Bridge "br-eth2"
        Port "br-eth2"
            Interface "br-eth2"
                type: internal
        Port "phy-br-eth2"
            Interface "phy-br-eth2"
                type: patch
                options: {peer="int-br-eth2"}
        Port "eth2"
            Interface "eth2"
    Bridge br-ex
        Port phy-br-ex
            Interface phy-br-ex
                type: patch
                options: {peer=int-br-ex}
        Port "eth0"
            Interface "eth0"
        Port br-ex
            Interface br-ex
                type: internal
    Bridge br-int
        fail_mode: secure
        Port int-br-ex
            Interface int-br-ex
                type: patch
                options: {peer=phy-br-ex}
        Port "int-br-eth2"
            Interface "int-br-eth2"
                type: patch
                options: {peer="phy-br-eth2"}
        Port br-int
            Interface br-int
                type: internal
        Port patch-tun
            Interface patch-tun
                type: patch
                options: {peer=patch-int}
    Bridge br-tun
        fail_mode: secure
        Port patch-int
            Interface patch-int
                type: patch
                options: {peer=patch-tun}
        Port br-tun
            Interface br-tun
                type: internal
    ovs_version: "2.5.0"

ภาพแสดงการเชื่อมต่อภายใน จาก instance vm ออก internet ต้องผ่าน อุปกรณ์ ที่เป็น virtual network device ต่างๆ จำนวน 9 อุปกรณ์ ดังรูป
ovs-network
การเชื่อมต่อ ระหว่าง br-ex และ eth0
การเชื่อมต่อ ระหว่าง eth0 และ br-ex เพื่อให้ openstack สามารถเชื่อม provider network และ network ภายนอก

# cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0 
NAME=eth0
DEVICETYPE=ovs
TYPE=OVSPort
OVS_BRIDGE=br-ex
ONBOOT=yes
BOOTPROTO=none

# cat /etc/sysconfig/network-scripts/ifcfg-eth1
NM_CONTROLLED=no
BOOTPROTO=none
ONBOOT=yes
IPADDR=10.0.0.10
NETMASK=255.255.255.0
DEVICE=eth1
HWADDR=52:54:00:7b:64:20
PEERDNS=no


Ansible Configuration Management

มาเรียนรู้การใช้งาน Ansible
Ansible คือ เครื่องมือที่ใช้สำหรับการจัดการ configuration โดยจะทำงานผ่านทาง ssh พัฒนาด้วย ภาษา python การทำงานจะงานในรูปแบบที่ต้องมี management node ที่ทำหน้าเป็น server หลังที่จะทำหน้าเป็น ผู้ที่จะต้องไปติดตั้ง package บน เครื่องserverในระบบ การทำงานจะประกอบด้วยfile ที่เกี่ยวข้อง 2 file คือ inventory file และ playbook

  1. inventory file ทำหน้าเก่็บรายชื่อของ server หรือ ip ของ server ที่จะใช้สำหรับเป้าหมายสำหรับการติดตั้ง โดยdefault หาไม่มีการกำหนด ใน option -i ก็จะใช้ inventory ตือ /etc/ansible/hosts เราสามารถที่จะแก้ไขค่านี้ได้โดยทำการแก้ไข file /etc/ansible/ansible.cfg
  2. playbook.yml ไฟล์นี้จะเป็นตัวระบุว่า จะให้ ansible ทำอะไรบ้างในแต่ละ server การเขียนไฟล์จะใช้เป็น format ของ yaml format โดยสามารถเขียนแบบที่เป็น static และ dynamic ก็ได้โดยถ้าหาเขียนแบบ dynamic โดยใช้ jinja2 template
    ในการทดสอบการใช้งาน จะทดสอบการใช้งานผ่านทาง Vagrantfile โดยจะเป็นการสร้าง infrastructure ด้วย Vagrantfile ดังนี้ โดยสร้างบน provider virtualbox

Screen Shot 2559-08-22 at 6.25.57 PM

Vagrantfile

# Defines our Vagrant environment
#
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|

  # create mgmt node
  config.vm.define :mgmt do |mgmt_config|
      mgmt_config.vm.box = "centos/7"
      mgmt_config.vm.hostname = "mgmt"
      mgmt_config.vm.network :private_network, ip: "10.0.15.10"
      mgmt_config.vm.provider "virtualbox" do |vb|
        vb.memory = "256"
      end
      mgmt_config.vm.provision :shell, path: "bootstrap-mgmt.sh"
  end

  # create load balancer
  config.vm.define :lb do |lb_config|
      lb_config.vm.box = "centos/7"
      lb_config.vm.hostname = "lb"
      lb_config.vm.network :private_network, ip: "10.0.15.11"
      lb_config.vm.network "forwarded_port", guest: 80, host: 8080
      lb_config.vm.provider "virtualbox" do |vb|
        vb.memory = "256"
      end
  end

  # create some web servers
  # https://docs.vagrantup.com/v2/vagrantfile/tips.html
  (1..2).each do |i|
    config.vm.define "web#{i}" do |node|
        node.vm.box = "centos/7"
        node.vm.hostname = "web#{i}"
        node.vm.network :private_network, ip: "10.0.15.2#{i}"
        node.vm.network "forwarded_port", guest: 80, host: "808#{i}"
        node.vm.provider "virtualbox" do |vb|
          vb.memory = "256"
        end
    end
  end
end

bootstrap-mgmt.sh

#!/bin/bash
yum -y update
yum -y install epel-release
yum -y install ansible
yum -y install git

cat << EOF >> /etc/hosts
10.0.15.10  mgmt
10.0.15.11  lb
10.0.15.21  web1
10.0.15.22  web2
10.0.15.23  web3
10.0.15.24  web4
10.0.15.25  web5
10.0.15.26  web6
10.0.15.27  web7
10.0.15.28  web8
10.0.15.29  web9
EOF

inventory.ini

[lb]
lb

[web]
web1
web2

โดยให้สร้าง bootstrap-mgmt.sh และ inventory.ini ไว้ระดับเดียวกับ Vagrantfile

$ tree .
.
├── Vagrantfile
└── bootstrap-mgmt.sh
└── inventory.ini

ผลที่ได้ จะได้ infrastructure ดังนี้
Screen Shot 2559-08-22 at 11.11.36 PM

$ vagrant up
$ vagrant up
Bringing machine 'mgmt' up with 'virtualbox' provider...
Bringing machine 'lb' up with 'virtualbox' provider...
Bringing machine 'web1' up with 'virtualbox' provider...
Bringing machine 'web2' up with 'virtualbox' provider...
==&gt; mgmt: Checking if box 'centos/7' is up to date...
==&gt; mgmt: Clearing any previously set forwarded ports...
==&gt; mgmt: Clearing any previously set network interfaces...
==&gt; mgmt: Preparing network interfaces based on configuration...
...
==&gt; web2: Setting hostname...
==&gt; web2: Configuring and enabling network interfaces...
==&gt; web2: Rsyncing folder: /Users/newton/Vagrant/c7_ansible/ =&gt; /vagrant
==&gt; web2: Machine already provisioned. Run <code>vagrant provision</code> or use the <code>--provision</code>
==&gt; web2: flag to force provisioning. Provisioners marked to run always will still run.

$ vagrant status
Current machine states:

mgmt                      running (virtualbox)
lb                        running (virtualbox)
web1                      running (virtualbox)
web2                      running (virtualbox)   

## ตรวจสอบ ip
$ vagrant ssh mgmt -c &quot;ip a&quot;
$ vagrant ssh lb -c &quot;ip a&quot;
$ vagrant ssh web1 -c &quot;ip a&quot;
$ vagrant ssh web2 -c &quot;ip a&quot;

หมายเหตุ ถ้าไม่ได้ ip ให้ลองไปปรับ ค่าของ network adapter โดยไปยัง setting > Network ดังนี้
Adapter Type: Tserver(82543GC)
Promiscuous Mode: Allow All

Screen Shot 2559-08-22 at 11.30.07 PM
การเชื่อมต่อไปยัง vagrant

## connect to vagrant on node mgmt
$ vagrant ssh mgmt 

$ cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)

$ hosts="lb web1 web2"
$ for h in $hosts;do ping -c 4 $h; done

$ ansible --version
ansible 2.1.1.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides               

การเชื่อมต่อ ระหว่างโหนดด้วย ssh

เนื่องจาก Ansible จะเชื่อมต่อไปยังเครื่อง remote ด้วย ssh โดยที่การเชื่อมต่อไม่มีprograme ที่ไปทำงานอยู่บน เครื่อง remote หรือที่มีจะเรียกว่า agent
เมื่อทำการเชื่อมต่อไปยัง เครื่องปลายทางครั้งแรกด้วย ssh เครื่องปลายทางจะทำการส่ง key มาให้กับเราเพื่อทำ ssh authentication เพื่อยอมรับการเชื่อมต่อ ยกตัวอย่างเช่นเมื่อ mgmt node ต้องการ ssh ไปยัง web1 ในครั้งแรก

$ ssh web1
The authenticity of host 'web1 (10.0.15.21)' can't be established.
ECDSA key fingerprint is d1:2d:26:9d:9b:92:e9:0c:02:53:59:8b:b9:6a:c7:8f.
Are you sure you want to continue connecting (yes/no)?  no

## go to /vagrant
$ cd /vagrant
$ ls

$ ansible web1 -i inititial.ini -m ping
The authenticity of host 'web1 (10.0.15.21)' can't be established.
ECDSA key fingerprint is d1:2d:26:9d:9b:92:e9:0c:02:53:59:8b:b9:6a:c7:8f.
Are you sure you want to continue connecting (yes/no)? yes
web1 | UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh.",
    "unreachable": true
}
 

เมื่อทำการยืนยันด้วยการตอบ yes ค่า publickey ของ web1 จะมาเก็บไว้ในfile ~/.ssh/known_hosts

$ cat ~/.ssh/known_hosts
web1,10.0.15.21 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLK8riXRk1/Gyzggg6u+R41F+CBR1ZB7j3dOgBPqOn2H6jGfi0CC5W934OM6OQzKboXTZkny2Q2hrRopCQvJGCg=

เราสามารถเรียกดู public key ได้ใช้คำสั่ง ssh-keyscan

$ ssh-keyscan web1
# web1 SSH-2.0-OpenSSH_6.6.1
web1 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDxFTURY5TNjR2YliYth1qf2JL++rhuDu8bAdX3cJ/uMmheUEk2Ay3a5n3Fwc64jOTIoFWfIRlKNjogdtAU0xNEb+ksLGDXoNZATM9i08AT/RsenZ1RMDt/R9AA+Q6cptw9TzM/MQLBzGKqannZnHqF7iYc6BXnmzly3lO9t10mc4CV7K0xm3sZT17cOuxUHIc+/Jh63JJJpd2MEXB933zjJFHLdlD/GDIlmOy+HZEjLs6VETwL1UDryvIXqQFa0al7gylS6phWiHa807rRV+luKQM662RP8X7EcAI0bSHxYkRopqL8EVXgWwYOkHOTk21EhDRDb52goLjdE5OmPDz9
# web1 SSH-2.0-OpenSSH_6.6.1
web1 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLK8riXRk1/Gyzggg6u+R41F+CBR1ZB7j3dOgBPqOn2H6jGfi0CC5W934OM6OQzKboXTZkny2Q2hrRopCQvJGCg=

อ่านค่า key มาเก็บไว้ใน ~/.ssh/known_hosts

$ ssh-keyscan lb web1 web2 >> ~/.ssh/known_hosts
# web1 SSH-2.0-OpenSSH_6.6.1
# lb SSH-2.0-OpenSSH_6.6.1
# lb SSH-2.0-OpenSSH_6.6.1
# web1 SSH-2.0-OpenSSH_6.6.1
# web2 SSH-2.0-OpenSSH_6.6.1
# web2 SSH-2.0-OpenSSH_6.6.1

เมื่อใช้คำสั่ง ansible ก็จะไม่ถามให้ยอมรับ keyอีก

$ ansible lb  -i inititial.ini -m ping
lb | UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh.",
    "unreachable": true 

$ ansible web1 -i inititial.ini -m ping
web1 | UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh.",
    "unreachable": true
}

$ ansible web2 -i inititial.ini -m ping
web2 | UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh.",
    "unreachable": true
}

Ansible Ad-hoc
การใช้คำสั่ง ansible ที่ผ่านมา เรียกว่าเป็นการสั่งแบบ ad-hoc เหมือนกับเราสั่งด้วยทีละคำสั่งเหมือนกับการสั่งใน commandline แต่เป็นการสั่งผ่าน ansible เท่านั้น ที่ผ่านมาจะเห็นว่า ansible บอกว่ายังไม่สามารถเชื่อมต่อผ่าน ssh ได้
-m เป็นการบอกว่า จะให้ module ใดทำงาน เช่น -m ping คือ ต้องการที่ใช้ module ping โดยที่ module ที่พูดถึงคือ python module นั้นเอง ความสามารถของ ansible สามารถขยายความสามารถได้ด้วย module และ module จะแบ่งออกเป็น 2 ส่วนได้แก่ core และ extra ซึ่งมีมากกว่า 250 module
Screen Shot 2559-08-23 at 12.20.33 AM

## work on current user = vagrant
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/vagrant/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/vagrant/.ssh/id_rsa.
Your public key has been saved in /home/vagrant/.ssh/id_rsa.pub.
The key fingerprint is:
bd:e8:d3:1b:06:53:7b:b2:16:2d:5f:55:30:58:56:65 vagrant@mgmt
The key's randomart image is:
+--[ RSA 2048]----+
|             o=oE|
|            .. o.|
|          .     .|
|         o o   . |
|        S * o .  |
|         + O .   |
|        ..* .    |
|       ..o..     |
|        ....     |
+-----------------+
## run ad-hoc ansible
$ cd /vagrant
$ ansible all -i inititial.ini -m ping --ask-pass
SSH password:
lb | UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh.",
    "unreachable": true
}
web2 | UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh.",
    "unreachable": true
}
web1 | UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh.",
    "unreachable": true
}

หากเกิด error
Fix error ssh fails with error as permission denied

## try ssh to localhost on mgmt
$ ssh localhost
Permission denied (publickey,gssapi-keyex,gssapi-with-mic)
$ ssh lb
Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
$ ssh web1
Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
$ ssh web2
Permission denied (publickey,gssapi-keyex,gssapi-with-mic).

สำหรับการติดตั้ง Centos 7 ด้วย vagrant default ไม่อนุญาติให้ใช้ password สำหรับการ login ด้วย password

 
## check /etc/ssh/sshd_config , 
PasswordAuthentication  no

ให้เปลี่ยนค่า config ใน ทุก node mgmt, lb, web1, web2

$ sudo su -
# vi /etc/ssh/sshd_config
PasswordAuthentication  yes

# systemctl restart sshd

ทดสอบ vagrant ad-hoc อีกครั้ง

$ ansible all -i inititial.ini -m ping --ask-pass
SSH password:
web2 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
lb | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
web1 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

หมายความว่า mgmt node สามารถติดต่อไปยัง เครื่อง อื่นได้ผ่านทาง ssh คราวนี้ให้ลองสั่งอีกครั้งโดยไม่มี –ask-pass จะเห็นว่าก็ยังคงทำงานได้อยู่ แต่คราวนี้ จะเร็วกว่าเดิม โดย ansible จะทำการ cache ไว้ใช้ชั่วคราวเท่านั้น

$ ps -x
11939 ?        Ss     0:00 ssh: /home/vagrant/.ansible/cp/ansible-ssh-web1-22-vagrant [mux]
11942 ?        Ss     0:00 ssh: /home/vagrant/.ansible/cp/ansible-ssh-lb-22-vagrant [mux]
11945 ?        Ss     0:00 ssh: /home/vagrant/.ansible/cp/ansible-ssh-web2-22-vagrant [mux]

## try again win no password 
$ ansible all -i inititial.ini -m ping
web1 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
web2 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
lb | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

ตัวอย่างของ การสั่ง adhoc ด้วย module shell
อ่านเพิ่มเติม http://docs.ansible.com/ansible/intro_adhoc.html

$ ansible all -m shell -a "uname -a" -i inititial.ini
web1 | SUCCESS | rc=0 >>
Linux web1 3.10.0-327.22.2.el7.x86_64 #1 SMP Thu Jun 23 17:05:11 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

web2 | SUCCESS | rc=0 >>
Linux web2 3.10.0-327.22.2.el7.x86_64 #1 SMP Thu Jun 23 17:05:11 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

lb | SUCCESS | rc=0 >>
Linux lb 3.10.0-327.22.2.el7.x86_64 #1 SMP Thu Jun 23 17:05:11 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

โดยคำสั่ง ที่ต้องการสั่งจะอยู่ใน option -a
Ansible playbook  link

นอกจากการสั่ง ให้ ansible ทำงานแบบ ad-hoc แล้ว ยังสามารถให้ทำงานผ่านทาง playbook โดยมีการเขียนในแบบ ภาษา yaml โดย ansible จะใช้ playbook เป็น configuration management ให้แก่ระบบ การประกาศค่าต่างๆ ใน playbook นั้นไม่ยากอ่านง่าย ดังตัวอย่าง
ssh-addkey.yml จะทำหน้าที่ copy key จาก mgmt ไปยังเครื่องอื่นๆ

---
- hosts: all
  sudo: yes
  gather_facts: no
  remote_user: vagrant

  tasks:
  - name: install ssh key
    authorized_key: user=vagrant
                    key="{{ lookup('file', '/home/vagrant/.ssh/id_rsa.pub') }}"
                    state=present

การใช้งาน playbook จะใช้คำสั่ง ansible-playbook ดังนี้

cd /vagrant
$ ansible-playbook ssh-addkey.yml -i inititial.ini --ask-pass
SSH password:
[DEPRECATION WARNING]: Instead of sudo/sudo_user, use become/become_user and make sure become_method is 'sudo'
(default).
This feature will be removed in a future release. Deprecation warnings can be disabled by setting
deprecation_warnings=False in ansible.cfg.

PLAY [all] *********************************************************************

TASK [install ssh key] *********************************************************
changed: [web2]
changed: [lb]
changed: [web1]

PLAY RECAP *********************************************************************
lb                         : ok=1    changed=1    unreachable=0    failed=0
web1                       : ok=1    changed=1    unreachable=0    failed=0
web2                       : ok=1    changed=1    unreachable=0    failed=0

ถึงขั้นตอนนี้ เราได้สร้าง ssh trust ระหว่าง node เรียบร้อย เราสามารถที่สั่ง run playbook ซ้ำๆ ได้ ansible มีความฉลาดพอ เพื่อดูว่ามีการเปลี่ยนแปลงของ config หรือไม่ หาไม่มีการเปลี่ยนแปลง ansible ก็จะไม่ดำเนินการใด เรียกได้ว่า ansible มีคุณสมบัติของ “idempotence”

$ ansible-playbook ssh-addkey.yml -i inititial.ini --ask-pass
SSH password:
[DEPRECATION WARNING]: Instead of sudo/sudo_user, use become/become_user and make sure become_method is 'sudo'
(default).
This feature will be removed in a future release. Deprecation warnings can be disabled by setting
deprecation_warnings=False in ansible.cfg.

PLAY [all] *********************************************************************

TASK [install ssh key] *********************************************************
ok: [web1]
ok: [web2]
ok: [lb]

PLAY RECAP *********************************************************************
lb                         : ok=1    changed=0    unreachable=0    failed=0
web1                       : ok=1    changed=0    unreachable=0    failed=0
web2                       : ok=1    changed=0    unreachable=0    failed=0

จะเห็นว่า change=0

---
- hosts: all
  sudo: yes
  gather_facts: no

  tasks:

  - name: install chrony
    yum: name=chrony state=installed update_cache=yes

  - name: write our chrony.conf
    copy: src=/vagrant/files/chrony.conf dest=/etc/chrony.conf mode=644 owner=root group=root
    notify: restart chrony

  - name: start chrony
    service: name=chronyd state=started

  handlers:

  - name: restart chrony
    service: name=chronyd state=restarted
$ ansible-playbook -i inititial.ini chrony-install.yml
[DEPRECATION WARNING]: Instead of sudo/sudo_user, use become/become_user and make sure become_method is 'sudo' (default).
This feature
will be removed in a future release. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.

PLAY [all] *********************************************************************

TASK [install chrony] **********************************************************
ok: [web2]
ok: [web1]
ok: [lb]

TASK [write our chrony.conf] ***************************************************
ok: [web1]
ok: [lb]
ok: [web2]

TASK [start chrony] ************************************************************
ok: [web1]
ok: [web2]
ok: [lb]

PLAY RECAP *********************************************************************
lb                         : ok=3    changed=0    unreachable=0    failed=0
web1                       : ok=3    changed=0    unreachable=0    failed=0
web2                       : ok=3    changed=0    unreachable=0    failed=0

chrony-remove.yml

---
- hosts: all
  sudo: yes
  gather_facts: no

  tasks:

  - name: remove chrony
    yum: name=chrony state=absent 

run playbook: chrony-remove.yml

$ ansible-playbook -i inititial.ini chrony-remove.yml
[DEPRECATION WARNING]: Instead of sudo/sudo_user, use become/become_user and make sure become_method is 'sudo' (default).
This feature
will be removed in a future release. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.

PLAY [all] *********************************************************************

TASK [remove chrony] ***********************************************************
changed: [web1]
changed: [lb]
changed: [web2]

PLAY RECAP *********************************************************************
lb                         : ok=1    changed=1    unreachable=0    failed=0
web1                       : ok=1    changed=1    unreachable=0    failed=0
web2                       : ok=1    changed=1    unreachable=0    failed=0