在SoftLayer的免费裸金属服务器上学习OpenStack(12)- 第11章 “利用Ansible进行配置管理自动化”

上回是在这里-下回是在这里。


这是什么?

OpenStackクラウドインテグレーション オープンソースクラウドによるサービス構築入門

使用ansible实现配置管理的自动化的第11章

在前面的九个章节中,我们学习了如何使用OpenStack的标准功能。在本章中,我们将学习如何利用Ansible来提高OpenStack的运维效率。

这里是章的支援文件。

11.1 故事情节的发展

Ansible章节的引言,旨在改善运维。

11.2. 引入和配置Ansible

11.2.1 安装Ansible

操作系统提供了几种软件包、pip和从源代码构建的安装方法。下面是对这三种方法的说明。然而,本书的描述假设使用pip进行安装,因此请根据此进行操作。

被引导的是“Development Tools”软件包组和“python-virtualenv”软件包的安装。

[root@step-server ~]# yum groupinstall -y "Development Tools"
~~~~~~~~
Complete!
[root@step-server ~]# yum install -y python-virtualenv
~~~~~~~~
Complete!

在此之后,由一般用户执行任务,因此我们需要创建一个名为user01的一般用户并进行切换。

[root@step-server ~]# adduser user01
[root@step-server ~]# su - user01

以一般用户user01身份,在Python虚拟执行环境下安装Ansible。

[user01@step-server ~]$ virtualenv venv
New python executable in venv/bin/python
Installing Setuptools..............................................................................................................................................................................................................................done.
Installing Pip.....................................................................................................................................................................................................................................................................................................................................done.
[user01@step-server ~]$ source venv/bin/activate

(venv)[user01@step-server ~]$ pip install jinja2 passlib pycrypto pyyaml
Downloading/unpacking jinja2
~~~~~~~~
Successfully installed jinja2 passlib pycrypto pyyaml markupsafe
Cleaning up...

(venv)[user01@step-server ~]$ pip install ansible
Downloading/unpacking ansible
  Downloading ansible-1.9.0.1.tar.gz (916kB): 916kB downloaded
~~~~~~~~
Successfully installed ansible paramiko ecdsa
Cleaning up...

(venv)[user01@step-server ~]$ ansible --version
ansible 1.9.0.1
  configured module search path = None

已经推出了1.9.0.1版本。本书中确认使用的是1.8.2。

11.2.2 Ansible的基本设置

将基本配置写入到$HOME/.ansible.cfg文件中。

创建日志目录。

(venv)[user01@step-server ~]$ mkdir $HOME/log

设定 $HOME/.ansible.cfg。

(venv)[user01@step-server ~]$ nano .ansible.cfg
(venv)[user01@step-server ~]$ cat .ansible.cfg
[defaults]
forks                   = 10
log_path                = /home/user01/log/ansible.log
host_key_checking       = False
gathering               = smart
transport               = smart

11.2.3 验证 Ansible 的运行情况

尝试使用Ansible在本地主机上进行ping测试。

(venv)[user01@step-server ~]$ cd
(venv)[user01@step-server ~]$ pwd
/home/user01
(venv)[user01@step-server ~]$ echo "localhost ansible_connection=local" > ansible_hosts
(venv)[user01@step-server ~]$ ansible all -i ansible_hosts -m ping
localhost | success >> {
    "changed": false,
    "ping": "pong"
}

在ansible_hosts中新增192.168.0.11和192.168.0.21。但是192.168.0.11的主机不存在。192.168.0.21是第10章中az2-dbs01留存的地址。

(venv)[user01@step-server ~]$ nano ansible_hosts
(venv)[user01@step-server ~]$ cat ansible_hosts
localhost ansible_connection=local
192.168.0.11
192.168.0.21

Ansible的操作基本上是通过ssh连接进行的。
localhost因为有”ansible_connection=local”的配置,所以可以在不进行ssh连接的情况下成功执行。
192.168.0.21尝试通过ssh进行TCP连接,但由于无法登录而导致出现错误。
192.168.0.11由于该IP上没有启动服务器,所以在尝试通过ssh进行TCP连接时出现错误。

(venv)[user01@step-server ~]$ ansible all -i ansible_hosts -m ping
localhost | success >> {
    "changed": false,
    "ping": "pong"
}

192.168.0.21 | FAILED => SSH Error: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
    while connecting to 192.168.0.21:22
It is sometimes useful to re-run the command using -vvvv, which prints SSH debug output to help diagnose the issue.
192.168.0.11 | FAILED => SSH Error: ssh: connect to host 192.168.0.11 port 22: No route to host
    while connecting to 192.168.0.11:22
It is sometimes useful to re-run the command using -vvvv, which prints SSH debug output to help diagnose the issue.

为了能够通过ssh登录到192.168.0.21,将ssh密钥复制到/home/user01/并将所有权设置为user01。

[root@step-server ~]# cp key-for-internal.pem /home/user01/
[root@step-server ~]# cd /home/user01
[root@step-server user01]# chown user01 key-for-internal.pem
[root@step-server user01]# ls -al key-for-internal.pem
-rw------- 1 user01 root 1680 Mar 29 18:03 key-for-internal.pem

请在.ansible.cfg配置文件中使用完整路径设置private_key_file为私钥的路径。

(venv)[user01@step-server ~]$ cat .ansible.cfg
[defaults]
forks                   = 10
log_path                = /home/user01/log/ansible.log
host_key_checking       = False
gathering               = smart
transport               = smart
private_key_file        = /home/user01/key-for-internal.pem

在执行ansible时,使用”-u root”参数,声明要以root身份登录到目标主机。
使用/home/user01/key-for-internal.pem连接到root@192.168.0.21,并成功进行了ping测试。

当然192.168.0.11会失败。

(venv)[user01@step-server ~]$ ansible all -i ansible_hosts -m ping -u root
localhost | success >> {
    "changed": false,
    "ping": "pong"
}

192.168.0.21 | success >> {
    "changed": false,
    "ping": "pong"
}

192.168.0.11 | FAILED => SSH Error: ssh: connect to host 192.168.0.11 port 22: No route to host
    while connecting to 192.168.0.11:22
It is sometimes useful to re-run the command using -vvvv, which prints SSH debug output to help diagnose the issue.

目标设定为“所有:!192.168.0.11”。使用“!”符号,除去192.168.0.11后,“所有”成为目标。

由於192.168.0.11已被排除在目標之外,可以確認對所有目標的ping応答正常。

(venv)[user01@step-server ~]$ ansible 'all:!192.168.0.11' -i ansible_hosts -m ping -u root
localhost | success >> {
    "changed": false,
    "ping": "pong"
}

192.168.0.21 | success >> {
    "changed": false,
    "ping": "pong"
}

11.3 Ansible的机制

正如节标题所示,这是关于Ansible工作原理的解释。

运行更改此主机名的播放书以确认操作。

(venv)[user01@step-server samples]$ ansible-playbook -i ~/ansible_hosts -u root -e target=192.168.0.21 sample-11-1.yml

PLAY [192.168.0.21] ***********************************************************

GATHERING FACTS ***************************************************************
ok: [192.168.0.21]

TASK: [get hostname] **********************************************************
changed: [192.168.0.21]

TASK: [set hostname] **********************************************************
changed: [192.168.0.21]

NOTIFIED: [show hostname] *****************************************************
ok: [192.168.0.21] => {
    "msg": "before=az2-dbs01 after=ansible-host1"
}

PLAY RECAP ********************************************************************
192.168.0.21               : ok=4    changed=2    unreachable=0    failed=0

az2-dbs01的主机名已被更改为ansible-host1。

再执行一次。

(venv)[user01@step-server samples]$ ansible-playbook -i ~/ansible_hosts -u root -e target=192.168.0.21 sample-11-1.yml

PLAY [192.168.0.21] ***********************************************************

GATHERING FACTS ***************************************************************
ok: [192.168.0.21]

TASK: [get hostname] **********************************************************
changed: [192.168.0.21]

TASK: [set hostname] **********************************************************
ok: [192.168.0.21]

PLAY RECAP ********************************************************************
192.168.0.21               : ok=3    changed=1    unreachable=0    failed=0

由于已经更改了主机名,因此handlers不会被调用,”NOTIFIED: [show hostname]”不会被调用。

14.4 使用Ansible自动化基本操作

安装/更新CentOS的软件包

安装/更新软件包。使用的剧本在这里。

(venv)[user01@step-server samples]$ ansible-playbook -i ~/ansible_hosts -u root -e target=192.168.0.21 sample-11-2.yml

PLAY [192.168.0.21] ***********************************************************

GATHERING FACTS ***************************************************************
ok: [192.168.0.21]

TASK: [install or upgrade packages] *******************************************
changed: [192.168.0.21] => (item=bash,tcsh,zsh)

PLAY RECAP ********************************************************************
192.168.0.21               : ok=2    changed=1    unreachable=0    failed=0

11.4.2 创建用户帐户

在目标主机上创建一个名为ansible的用户。以下是要使用的playbook。

(venv)[user01@step-server samples]$ ansible-playbook -i ~/ansible_hosts -u root -e target=192.168.0.21 sample-11-3.yml
Enter a new user's password:
confirm Enter a new user's password:
***** VALUES ENTERED DO NOT MATCH ****
Enter a new user's password:
confirm Enter a new user's password:

PLAY [192.168.0.21] ***********************************************************

GATHERING FACTS ***************************************************************
ok: [192.168.0.21]

TASK: [add a new user on target host] *****************************************
changed: [192.168.0.21]

TASK: [add a publickey on localhost to authorized_keys on target host] ********
fatal: [192.168.0.21] => could not locate file in lookup: /root/.ssh/id_rsa.pub

FATAL: all hosts have already failed -- aborting

PLAY RECAP ********************************************************************
           to retry, use: --limit @/home/user01/sample-11-3.retry

192.168.0.21               : ok=2    changed=1    unreachable=1    failed=0

如果在重新输入密码时犯了错误,就会被要求再次输入。
访问“/root/.ssh/id_rsa.pub”时出现错误。如果仔细阅读本书,会发现在事前使用ssh-keygen创建了公钥,需要指定它。

创建「/home/user01/.ssh/id_rsa.pub」文件。

(venv)[user01@step-server samples]$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user01/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user01/.ssh/id_rsa.
Your public key has been saved in /home/user01/.ssh/id_rsa.pub.
The key fingerprint is:
74:11:82:b0:f5:aa:c2:0f:cf:b8:45:f4:d6:26:44:7a user01@step-server
The key's randomart image is:
+--[ RSA 2048]----+
|    ..o.. o.     |
|     =.. . .     |
|    + E o .      |
|   . + + .       |
|    . = S        |
| . . o o         |
|  + o            |
|   O             |
|  o.+            |
+-----------------+

修改公钥文件的名称。

    authorized_key:
      user: "{{ username }}"
      key: "{{ lookup('file', '/home/user01/.ssh/id_rsa.pub') }}"

这一次取得了成功。

(venv)[user01@step-server samples]$ ansible-playbook -i ~/ansible_hosts -u root -e target=192.168.0.21 sample-11-3.yml
Enter a new user's password:
confirm Enter a new user's password:

PLAY [192.168.0.21] ***********************************************************

GATHERING FACTS ***************************************************************
ok: [192.168.0.21]

TASK: [add a new user on target host] *****************************************
changed: [192.168.0.21]

TASK: [add a publickey on localhost to authorized_keys on target host] ********
changed: [192.168.0.21]

PLAY RECAP ********************************************************************
192.168.0.21               : ok=3    changed=2    unreachable=0    failed=0

可以进行SSH登录。

(venv)[user01@step-server samples]$ ssh ansible@192.168.0.21
[ansible@ansible-host1 ~]$ exit
logout
Connection to 192.168.0.21 closed.

添加sudo配置。

在ansible所属的”wheel”组中添加”/etc/sudoers”的条目。只在”wheel”组不存在时进行添加。可以使用此playbook。

第一次执行时,由于没有记录,”TASK: [grant privileges to do the sudo command to the wheel group]” 标记为 “changed”。

(venv)[user01@step-server samples]$ ansible-playbook -i ~/ansible_hosts -u root -e target=192.168.0.21 sample-11-4.yml

PLAY [192.168.0.21] ***********************************************************

GATHERING FACTS ***************************************************************
ok: [192.168.0.21]

TASK: [grant privileges to do the sudo command to the wheel group] ************
changed: [192.168.0.21]

PLAY RECAP ********************************************************************
192.168.0.21               : ok=2    changed=1    unreachable=0    failed=0

当再次执行时,会显示”OK”并且不会进行任何附加操作。

(venv)[user01@step-server samples]$ ansible-playbook -i ~/ansible_hosts -u root -e target=192.168.0.21 sample-11-4.yml

PLAY [192.168.0.21] ***********************************************************

GATHERING FACTS ***************************************************************
ok: [192.168.0.21]

TASK: [grant privileges to do the sudo command to the wheel group] ************
ok: [192.168.0.21]

PLAY RECAP ********************************************************************
192.168.0.21               : ok=2    changed=0    unreachable=0    failed=0

11.4.4 配置设定文件并重新启动服务。

将预先准备好的my.cnf.j2复制到/etc/my.cnf。仅当发生文件替换时,重新启动MySQL。可使用以下播放列表。

第一次时,[替换了my.cnf]并且调用了[重新启动数据库]。

(venv)[user01@step-server samples]$ ansible-playbook -i ~/ansible_hosts -u root -e target=192.168.0.21 sample-11-5.yml

PLAY [192.168.0.21] ***********************************************************

GATHERING FACTS ***************************************************************
ok: [192.168.0.21]

TASK: [replace my.cnf] ********************************************************
changed: [192.168.0.21]

NOTIFIED: [restart database] **************************************************
changed: [192.168.0.21]

PLAY RECAP ********************************************************************
192.168.0.21               : ok=3    changed=2    unreachable=0    failed=0

第二次的时候,[替换我的.cnf]是可以的,不需要[重启数据库]。

(venv)[user01@step-server samples]$ ansible-playbook -i ~/ansible_hosts -u root -e target=192.168.0.21 sample-11-5.yml

PLAY [192.168.0.21] ***********************************************************

GATHERING FACTS ***************************************************************
ok: [192.168.0.21]

TASK: [replace my.cnf] ********************************************************
ok: [192.168.0.21]

PLAY RECAP ********************************************************************
192.168.0.21               : ok=2    changed=0    unreachable=0    failed=0

11.4.5 重新启动操作系统以确认启动完成。

请重新启动目标主机,等待2分钟后以10秒的间隔尝试SSH连接确认是否成功。使用的剧本位于这里。

如果在暂停模块中,可以通过“Ctrl+C”来中止并显示消息“Action? (a)bort/(c)ontinue:”,以便用户知道可以通过“^C-a”来中止或者通过“^C-c”来继续。

(venv)[user01@step-server samples]$ ansible-playbook -i ~/ansible_hosts -u root -e target=192.168.0.21 sample-11-6.yml

PLAY [192.168.0.21] ***********************************************************

GATHERING FACTS ***************************************************************
ok: [192.168.0.21]

TASK: [reboot server] *********************************************************
changed: [192.168.0.21]

TASK: [wait for shutdown process] *********************************************
(^C-c = continue early, ^C-a = abort)
[192.168.0.21]
Pausing for 120 seconds
^C
Action? (a)bort/(c)ontinue:
ok: [192.168.0.21 -> 127.0.0.1]

TASK: [check the server to start up] ******************************************
ok: [192.168.0.21 -> 127.0.0.1]

PLAY RECAP ********************************************************************
192.168.0.21               : ok=4    changed=1    unreachable=0    failed=0

如果在暂停模块中没有等待停止,而按下“Ctrl+C”键,则会立即结束。

TASK: [reboot server] *********************************************************
^CERROR: interrupted
(venv)[user01@step-server samples]$

11.5 自动化OpenStack管理操作

11.5.1 事前准备工作

在跳板服务器上创建并切换用户ansible。

[root@step-server ~]# useradd ansible
[root@step-server ~]# cp /root/openrc /home/ansible/
[root@step-server ~]# chown ansible:ansible /home/ansible/openrc
[root@step-server ~]# su - ansible
[ansible@step-server ~]$

用户使用 Ansible,使用 pip 安装 Ansible。

[ansible@step-server ~]$ virtualenv venv
New python executable in venv/bin/python
Installing Setuptools.............................................................................................done.
Installing Pip....................................................................................................................................done.

[ansible@step-server ~]$ source venv/bin/activate

(venv)[ansible@step-server ~]$ pip install jinja2 passlib pycrypto pyyaml
Downloading/unpacking jinja2
~~~~~~~~
Successfully installed jinja2 passlib pycrypto pyyaml markupsafe
Cleaning up...

(venv)[ansible@step-server ~]$ pip install ansible
Downloading/unpacking ansible
  Downloading ansible-1.9.0.1.tar.gz (916kB): 916kB downloaded
~~~~~~~~
Successfully installed ansible paramiko ecdsa
Cleaning up...

安装本书的支援文件以及python-novaclient。

(venv)[ansible@step-server ~]$ cd $HOME

(venv)[ansible@step-server ~]$ git clone https://github.com/josug-book1-materials/chapter11.git
Initialized empty Git repository in /home/ansible/chapter11/.git/
remote: Counting objects: 218, done.
remote: Total 218 (delta 0), reused 0 (delta 0), pack-reused 218
Receiving objects: 100% (218/218), 32.98 KiB, done.
Resolving deltas: 100% (116/116), done.

(venv)[ansible@step-server ~]$ pip install python-novaclient==2.16.0
Downloading/unpacking python-novaclient==2.16.0
  Downloading python-novaclient-2.16.0.tar.gz (227kB): 227kB downloaded
~~~~~~~~
Successfully installed python-novaclient pbr argparse iso8601 PrettyTable requests simplejson six Babel pytz
Cleaning up..

(venv)[ansible@step-server ~]$ pip install python-neutronclient==2.3.4
Downloading/unpacking python-neutronclient==2.3.4
  Downloading python-neutronclient-2.3.4.tar.gz (105kB): 105kB downloaded
~~~~~~~~
Successfully installed python-neutronclient cliff httplib2 cmd2 pyparsing stevedore
Cleaning up...

将以下内容添加到代码中以获取网络的UUID,并执行。

(venv)[ansible@step-server ~]$ cat openrc
export OS_AUTH_URL=http://192.168.100.10:5000/v2.0/
export OS_REGION_NAME=RegionOne
export OS_TENANT_NAME=SNSApp
export OS_USERNAME=snsapp-infra-user
export OS_PASSWORD=passw0rd

function get_uuid () { cat - | grep " id " | awk '{print $4}'; }
export OS_DMZ_NET=`neutron net-show dmz-net | get_uuid`
export OS_APP_NET=`neutron net-show app-net | get_uuid`
export OS_DBS_NET=`neutron net-show dbs-net | get_uuid`

(venv)[ansible@step-server ~]$ source openrc

创建密钥对并将其注册到OpenStack中。


(venv)[ansible@step-server ~]$ ssh-keygen -t rsa -b 2048 -N ""
Generating public/private rsa key pair.
Enter file in which to save the key (/home/ansible/.ssh/id_rsa):
Created directory '/home/ansible/.ssh'.
Your identification has been saved in /home/ansible/.ssh/id_rsa.
Your public key has been saved in /home/ansible/.ssh/id_rsa.pub.
The key fingerprint is:
a1:49:c1:a2:6d:db:3b:bb:d9:91:50:88:0a:0d:53:1f ansible@step-server
The key's randomart image is:
+--[ RSA 2048]----+
|o.. E..          |
| + ..o.o         |
|. .oo.o o        |
| ...o. + .       |
|  .. o+ S        |
|    . .. .       |
|       .o        |
|      oo .       |
|      ++.        |
+-----------------+

(venv)[ansible@step-server ~]$ nova keypair-add --pub-key .ssh/id_rsa.pub key-for-ansible

(venv)[ansible@step-server ~]$ nova keypair-list
+---------------------+-------------------------------------------------+
| Name                | Fingerprint                                     |
+---------------------+-------------------------------------------------+
| key-for-step-server | c6:a2:cd:b5:ee:0b:29:ae:19:61:27:f8:5d:28:5f:8b |
| key-for-internal    | 9d:89:c8:a7:c6:4b:f1:23:8c:41:9f:3f:a8:bf:91:77 |
| key-for-ansible     | a1:49:c1:a2:6d:db:3b:bb:d9:91:50:88:0a:0d:53:1f |
+---------------------+-------------------------------------------------+

11.5.2 虚拟机实例构建的自动化方法

当通过指定web、app和dbs的角色时,会构建相应的虚拟机实例。下面是执行计划。

复制Playbook到本地,声明不使用本地连接进行ssh。

(venv)[ansible@step-server ~]$ cd

(venv)[ansible@step-server ~]$ cp chapter11/playbooks/book1/create_sample_vm.yml .

(venv)[ansible@step-server ~]$ echo "localhost ansible_connection=local" > ansible_hosts

以”target=web”作为条件执行播放列表。

(venv)[ansible@step-server ~]$ ansible-playbook -i ansible_hosts -e target=web create_sample_vm.yml

PLAY [localhost] **************************************************************

GATHERING FACTS ***************************************************************
ok: [localhost]

TASK: [ansible_python_interpreter setup] **************************************
ok: [localhost]

TASK: [get uuid for generate hostname] ****************************************
changed: [localhost]

TASK: [create {{ target }}-server on nova-compute with floating_ip] ***********
changed: [localhost]

TASK: [create {{ target }}-server on nova-compute without floating_ip] ********
skipping: [localhost]

PLAY RECAP ********************************************************************
localhost                  : ok=4    changed=2    unreachable=0    failed=0

服务器已创建并分配了浮动IP。


(venv)[ansible@step-server ~]$ nova list --name ^web- --field name,networks
+--------------------------------------+------------------------------------------+-------------------------------------------------------------+
| ID                                   | Name                                     | Networks                                                    |
+--------------------------------------+------------------------------------------+-------------------------------------------------------------+
| 0055b5ed-5180-4b06-8805-c8b6205040dd | web-520710f9-08d3-41cd-9d28-aa6cc4bfca66 | dmz-net=192.168.0.22, 192.168.100.135; app-net=172.16.10.15 |
+--------------------------------------+------------------------------------------+-------------------------------------------------------------+

(venv)[ansible@step-server ~]$ nova floating-ip-list
+-----------------+-----------+--------------+---------+
| Ip              | Server Id | Fixed Ip     | Pool    |
+-----------------+-----------+--------------+---------+
| 192.168.100.135 |           | 192.168.0.22 | Ext-Net |
| 192.168.100.131 |           | 10.0.0.1     | Ext-Net |
| 192.168.100.134 |           | 192.168.0.19 | Ext-Net |
| 192.168.100.133 |           | 192.168.0.5  | Ext-Net |
+-----------------+-----------+--------------+---------+

用「target=app」进行创建。

(venv)[ansible@step-server ~]$ ansible-playbook -i ansible_hosts -e target=app create_sample_vm.yml

PLAY [localhost] **************************************************************

GATHERING FACTS ***************************************************************
ok: [localhost]

TASK: [ansible_python_interpreter setup] **************************************
ok: [localhost]

TASK: [get uuid for generate hostname] ****************************************
changed: [localhost]

TASK: [create {{ target }}-server on nova-compute with floating_ip] ***********
skipping: [localhost]

TASK: [create {{ target }}-server on nova-compute without floating_ip] ********
changed: [localhost]

PLAY RECAP ********************************************************************
localhost                  : ok=4    changed=2    unreachable=0    failed=0

已经创建。


(venv)[ansible@step-server ~]$ nova list --name ^app- --field name,networks
+--------------------------------------+------------------------------------------+-----------------------------------------------------------------+
| ID                                   | Name                                     | Networks                                                        |
+--------------------------------------+------------------------------------------+-----------------------------------------------------------------+
| ab7c19c6-6f4f-438e-8cdf-012dbb7a4cc1 | app-18e1b380-a213-4518-a3ae-30ccad545014 | dmz-net=192.168.0.23; app-net=172.16.10.16; dbs-net=172.16.20.8 |
+--------------------------------------+------------------------------------------+-----------------------------------------------------------------+

在「target=dbs」上创建。


(venv)[ansible@step-server ~]$ ansible-playbook -i ansible_hosts -e target=dbs create_sample_vm.yml

PLAY [localhost] **************************************************************

GATHERING FACTS ***************************************************************
ok: [localhost]

TASK: [ansible_python_interpreter setup] **************************************
ok: [localhost]

TASK: [get uuid for generate hostname] ****************************************
changed: [localhost]

TASK: [create {{ target }}-server on nova-compute with floating_ip] ***********
skipping: [localhost]

TASK: [create {{ target }}-server on nova-compute without floating_ip] ********
changed: [localhost]

PLAY RECAP ********************************************************************
localhost                  : ok=4    changed=2    unreachable=0    failed=0

(venv)[ansible@step-server ~]$ nova list --name ^dbs- --field name,networks
+--------------------------------------+------------------------------------------+-------------------------------------------+
| ID                                   | Name                                     | Networks                                  |
+--------------------------------------+------------------------------------------+-------------------------------------------+
| 359d02ea-098e-4e03-966e-81bbc40da2c0 | dbs-968a948e-7e58-4089-a6c6-6b2a38bb71e6 | dmz-net=192.168.0.24; dbs-net=172.16.20.9 |
+--------------------------------------+------------------------------------------+-------------------------------------------+

11.5.3 应用程序部署的自动化

在这里进行的是以下四点。

    1. 时区的更改

 

    1. 从github中拉取应用程序检查

 

    1. 执行安装脚本

 

    1. 通过编辑endpoint.conf来更改并传输服务器之间的协作

 

    启动服务

这是游戏策略。

首先,在ansible_hosts文件中记录目标主机的dmz-net IP地址。这是用于操作的。另外,为了修改endpoint.conf文件,需要记录web上要设置的应用程序的app-net IP地址,以及要设置为app的数据库的dbs-net IP地址。

(venv)[ansible@step-server ~]$ cat ansible_hosts
[localhost]
localhost ansible_connection=local

[web]
192.168.0.22

[app]
192.168.0.23

[dbs]
192.168.0.24

[web:vars]
app = 172.16.10.16

[app:vars]
dbs = 172.16.20.9

把Playbook和endpoint.conf的模板复制到主页上。

(venv)[ansible@step-server ~]$ cd

(venv)[ansible@step-server ~]$ cp chapter11/playbooks/book1/install_sample_app.yml .

(venv)[ansible@step-server ~]$ cp chapter11/playbooks/book1/endpoint.conf.j2 .

由于存在依赖关系,需要按照以下顺序进行安装:首先安装dbs,然后是app,最后是web。

执行「target=dbs」。我指定了登录,并且还指定了“-u root”。当从GitHub获取应用程序时出现了“403 Forbidden”的错误。

(venv)[ansible@step-server ~]$ ansible-playbook -i ansible_hosts -e target=dbs -u root install_sample_app.yml

PLAY [dbs] ********************************************************************

GATHERING FACTS ***************************************************************
The authenticity of host '192.168.0.24 (192.168.0.24)' can't be established.
RSA key fingerprint is 9d:7e:70:8f:da:c2:b0:1f:9c:57:39:c1:a1:01:9a:a3.
Are you sure you want to continue connecting (yes/no)? yes
ok: [192.168.0.24]

TASK: [change the timezone] ***************************************************
changed: [192.168.0.24]

TASK: [checkout app from github] **********************************************
failed: [192.168.0.24] => {"cmd": "/usr/bin/git clone --origin origin --branch v1.0 https://github.com/josug-book1-materials/sample-app.git /root/sample-app", "failed": true, "rc": 128}
stderr: error: The requested URL returned error: 403 Forbidden while accessing https://github.com/josug-book1-materials/sample-app.git/info/refs

fatal: HTTP request failed

stdout: Initialized empty Git repository in /root/sample-app/.git/

msg: error: The requested URL returned error: 403 Forbidden while accessing https://github.com/josug-book1-materials/sample-app.git/info/refs

fatal: HTTP request failed

FATAL: all hosts have already failed -- aborting

PLAY RECAP ********************************************************************
           to retry, use: --limit @/home/ansible/install_sample_app.retry

192.168.0.24               : ok=2    changed=1    unreachable=0    failed=1

我先重新执行一次。这一次成功了。

(venv)[ansible@step-server ~]$ ansible-playbook -i ansible_hosts -e target=dbs -u root install_sample_app.yml

PLAY [dbs] ********************************************************************

GATHERING FACTS ***************************************************************
ok: [192.168.0.24]

TASK: [change the timezone] ***************************************************
changed: [192.168.0.24]

TASK: [checkout app from github] **********************************************
changed: [192.168.0.24]

TASK: [execute install script] ************************************************
ok: [192.168.0.24]

TASK: [copy endpoint.conf to web and app server] ******************************
skipping: [192.168.0.24]

PLAY RECAP ********************************************************************
192.168.0.24               : ok=4    changed=2    unreachable=0    failed=0

在”target=app”上运行。

(venv)[ansible@step-server ~]$ ansible-playbook -i ansible_hosts -e target=app -u root install_sample_app.yml

PLAY [app] ********************************************************************

GATHERING FACTS ***************************************************************
The authenticity of host '192.168.0.23 (192.168.0.23)' can't be established.
RSA key fingerprint is 4d:8e:f4:7d:06:ca:85:c4:b7:23:27:30:67:3a:8b:13.
Are you sure you want to continue connecting (yes/no)? yes
ok: [192.168.0.23]

TASK: [change the timezone] ***************************************************
changed: [192.168.0.23]

TASK: [checkout app from github] **********************************************
changed: [192.168.0.23]

TASK: [execute install script] ************************************************
ok: [192.168.0.23]

TASK: [copy endpoint.conf to web and app server] ******************************
changed: [192.168.0.23]

NOTIFIED: [startup service] ***************************************************
changed: [192.168.0.23]

PLAY RECAP ********************************************************************
192.168.0.23               : ok=6    changed=4    unreachable=0    failed=0

以「target=app」作为参数运行。

(venv)[ansible@step-server ~]$ ansible-playbook -i ansible_hosts -e target=web -u root install_sample_app.yml

PLAY [web] ********************************************************************

GATHERING FACTS ***************************************************************
The authenticity of host '192.168.0.22 (192.168.0.22)' can't be established.
RSA key fingerprint is 28:30:e0:72:bc:7e:d8:61:da:1d:cb:67:02:19:8b:5e.
Are you sure you want to continue connecting (yes/no)? yes
ok: [192.168.0.22]

TASK: [change the timezone] ***************************************************
changed: [192.168.0.22]

TASK: [checkout app from github] **********************************************
changed: [192.168.0.22]

TASK: [execute install script] ************************************************
ok: [192.168.0.22]

TASK: [copy endpoint.conf to web and app server] ******************************
changed: [192.168.0.22]

NOTIFIED: [startup service] ***************************************************
changed: [192.168.0.22]

PLAY RECAP ********************************************************************
192.168.0.22               : ok=6    changed=4    unreachable=0    failed=0

11.5.4 在动态库存中应对主机的增减情况

在”11.5.3应用部署自动化”中,我们将目标IP地址记录在ansible_hosts中。然而,在OpenStack中,直到部署之前,地址基本上是未知的。
我们可以调用返回清单信息的外部程序,并将其作为ansible的目标。

外部程序的条件如下所示,并在本书中有所提及。

    1. 如果以-list作为参数,则返回JSON格式的主机列表。

 

    如果用-host作为参数,则返回JSON格式的主机参数。

验证是否可以通过一个简单的shell脚本返回主机列表。

(venv)[ansible@step-server ~]$ cat inventry.sh
#!/bin/sh

usage() {
        echo "Usage: invenrty.sh --list|--host hostname"
        exit 1
}

case $1 in
        "--list")
                echo '{"sns":{"hosts":["192.168.0.22","192.168.0.23","192.168.0.24"]}}'
                ;;
        "--host")
                if [ "x"$2 == "x" ] || [ $# -ne 2 ]; then
                        usage
                fi
                echo "{}"
                ;;
        *)
                usage
                ;;
esac

当使用ping模块进行确认时,即使是这样的shell也能正常工作。

(venv)[ansible@step-server ~]$ ansible sns -i inventry.sh -m ping -u root
192.168.0.22 | success >> {
    "changed": false,
    "ping": "pong"
}

192.168.0.24 | success >> {
    "changed": false,
    "ping": "pong"
}

192.168.0.23 | success >> {
    "changed": false,
    "ping": "pong"
}

将提供的sample_app_inventory.py和sample_app_inventory.ini文件复制到主目录中。给sample_app_inventory.py文件添加执行权限。

(venv)[ansible@step-server ~]$ cd

(venv)[ansible@step-server ~]$ cp chapter11/playbooks/sample_app_inventory.py .

(venv)[ansible@step-server ~]$ cp chapter11/playbooks/sample_app_inventory.ini .

(venv)[ansible@step-server ~]$ chmod u+x sample_app_inventory.py

这个ini文件是这样的。

(venv)[ansible@step-server ~]$ cat sample_app_inventory.ini
[DEFAULT]


[stack]
api_version    = 1.1
os_username    = %OS_USERNAME%
os_password    = %OS_PASSWORD%
os_auth_url    = %AUTH_URL%
os_region_name = %REGION_NAME%
os_tenant_name = %TENANT_NAME%

[sample_app]
web_hostname_prefix = web-
app_hostname_prefix = app-
dbs_hostname_prefix = dbs-


##
## [EOF]
##

根据这次的环境做相应的修改。

(venv)[ansible@step-server ~]$ cat sample_app_inventory.ini
[DEFAULT]


[stack]
api_version    = 1.1
os_username    = snsapp-infra-user
os_password    = passw0rd
os_auth_url    = http://192.168.100.10:5000/v2.0/
os_region_name = RegionOne
os_tenant_name = SNSApp

[sample_app]
web_hostname_prefix = web-
app_hostname_prefix = app-
dbs_hostname_prefix = dbs-


##
## [EOF]
##

执行

(venv)[ansible@step-server ~]$ ./sample_app_inventory.py --list
{
  "_meta": {
    "hostvars": {
      "192.168.0.22": {
        "app": "172.16.10.16"
      },
      "192.168.0.23": {
        "dbs": "172.16.20.9"
      },
      "192.168.0.24": {}
    }
  },
  "app": {
    "hosts": [
      "192.168.0.23"
    ],
    "vars": {
      "dbs": "172.16.20.9"
    }
  },
  "dbs": {
    "hosts": [
      "192.168.0.24"
    ],
    "vars": {}
  },
  "localhost": {
    "hosts": [
      "localhost"
    ],
    "vars": {
      "ansible_connection": "local"
    }
  },
  "web": {
    "hosts": [
      "192.168.0.22"
    ],
    "vars": {
      "app": "172.16.10.16"
    }
  }
}

暂时删除此章创建的服务器。

(venv)[ansible@step-server ~]$ nova delete app-18e1b380-a213-4518-a3ae-30ccad545014
(venv)[ansible@step-server ~]$ nova delete dbs-968a948e-7e58-4089-a6c6-6b2a38bb71e6
(venv)[ansible@step-server ~]$ nova delete web-520710f9-08d3-41cd-9d28-aa6cc4bfca66

启动新服务器。

(venv)[ansible@step-server ~]$ echo "localhost ansible_connection=local" > ansible_hosts
(venv)[ansible@step-server ~]$ ansible-playbook -i ansible_hosts -e target=web create_sample_vm.yml
(venv)[ansible@step-server ~]$ ansible-playbook -i ansible_hosts -e target=app create_sample_vm.yml
(venv)[ansible@step-server ~]$ ansible-playbook -i ansible_hosts -e target=dbs create_sample_vm.yml

将其引入到DBS。目标IP为[192.168.0.27]。

(venv)[ansible@step-server ~]$ ansible-playbook -i sample_app_inventory.py -e target=dbs install_sample_app.yml

PLAY [dbs] ********************************************************************

GATHERING FACTS ***************************************************************
The authenticity of host '192.168.0.27 (192.168.0.27)' can't be established.
RSA key fingerprint is a8:6a:42:e4:e2:19:2f:19:67:99:44:2e:8e:72:8b:40.
Are you sure you want to continue connecting (yes/no)? yes
ok: [192.168.0.27]

TASK: [change the timezone] ***************************************************
changed: [192.168.0.27]

TASK: [checkout app from github] **********************************************
changed: [192.168.0.27]

TASK: [execute install script] ************************************************
ok: [192.168.0.27]

TASK: [copy endpoint.conf to web and app server] ******************************
skipping: [192.168.0.27]

PLAY RECAP ********************************************************************
192.168.0.27               : ok=4    changed=2    unreachable=0    failed=0

将该应用程序安装到指定的IP地址[192.168.0.26]上。

(venv)[ansible@step-server ~]$ ansible-playbook -i sample_app_inventory.py -e target=app install_sample_app.yml

PLAY [app] ********************************************************************

GATHERING FACTS ***************************************************************
The authenticity of host '192.168.0.26 (192.168.0.26)' can't be established.
RSA key fingerprint is 82:84:ad:c8:3e:fe:fd:a9:b0:43:cd:fc:9d:d0:43:b6.
Are you sure you want to continue connecting (yes/no)? yes
ok: [192.168.0.26]

TASK: [change the timezone] ***************************************************
changed: [192.168.0.26]

TASK: [checkout app from github] **********************************************
changed: [192.168.0.26]

TASK: [execute install script] ************************************************
ok: [192.168.0.26]

TASK: [copy endpoint.conf to web and app server] ******************************
changed: [192.168.0.26]

NOTIFIED: [startup service] ***************************************************
changed: [192.168.0.26]

PLAY RECAP ********************************************************************
192.168.0.26               : ok=6    changed=4    unreachable=0    failed=0

安装到网络。目标IP地址为[192.168.0.25]。

(venv)[ansible@step-server ~]$ ansible-playbook -i sample_app_inventory.py -e target=web install_sample_app.yml

PLAY [web] ********************************************************************

GATHERING FACTS ***************************************************************
The authenticity of host '192.168.0.25 (192.168.0.25)' can't be established.
RSA key fingerprint is b4:3c:b3:1c:bd:58:5f:4e:8c:72:6d:05:82:2e:a3:01.
Are you sure you want to continue connecting (yes/no)? yes
ok: [192.168.0.25]

TASK: [change the timezone] ***************************************************
changed: [192.168.0.25]

TASK: [checkout app from github] **********************************************
changed: [192.168.0.25]

TASK: [execute install script] ************************************************
ok: [192.168.0.25]

TASK: [copy endpoint.conf to web and app server] ******************************
changed: [192.168.0.25]

NOTIFIED: [startup service] ***************************************************
changed: [192.168.0.25]

PLAY RECAP ********************************************************************
192.168.0.25               : ok=6    changed=4    unreachable=0    failed=0

11.5.5 自动化数据库备份/恢复

在dbs上获取快照,通过app重新启动服务,并自动化备份快照。

以下是三个步骤的游戏手册。

创建快照.yml、重启Rest服务.yml、备份快照.yml

这是一份一口气完成的播放书。

数据库备份.yml

将这些剧本复制到家里。

(venv)[ansible@step-server ~]$ cp chapter11/playbooks/book2/create_snapshot.yml .
(venv)[ansible@step-server ~]$ cp chapter11/playbooks/book2/restart_rest_service.yml .
(venv)[ansible@step-server ~]$ cp chapter11/playbooks/book2/backup_snapshot.yml .
(venv)[ansible@step-server ~]$ cp chapter11/playbooks/book2/db_backup.yml .

执行db_backup.yml的过程中发生了错误。

(venv)[ansible@step-server ~]$ ansible-playbook -i sample_app_inventory.py -t snapshot,backup -u root db_backup.yml

PLAY [dbs] ********************************************************************

GATHERING FACTS ***************************************************************
ok: [192.168.0.27]

TASK: [stop mysqld] ***********************************************************
ok: [192.168.0.27]

TASK: [umount mysql_dir] ******************************************************
ok: [192.168.0.27]

TASK: [create snapshot on lvm] ************************************************
failed: [192.168.0.27] => {"changed": true, "cmd": ["lvcreate", "-s", "/dev/mysql_vg/mysql_vol01", "-L", "100m", "-n", "mysql_bk_snap01"], "delta": "0:00:00.009340", "end": "2015-03-30 17:32:52.913837", "rc": 5, "start": "2015-03-30 17:32:52.904497", "warnings": []}
stderr:   Volume group "mysql_vg" not found

FATAL: all hosts have already failed -- aborting

PLAY RECAP ********************************************************************
           to retry, use: --limit @/home/ansible/db_backup.retry

192.168.0.27               : ok=3    changed=0    unreachable=0    failed=1

我正在尝试创建LVM快照。

~~~~~~
mysql_dir: /var/lib/mysql
mysql_vol: /dev/mysql_vg/mysql_vol01
mysql_snap: mysql_bk_snap01
mysql_snap_size: 100m
~~~~~~
command: lvcreate -s "{{ mysql_vol }}" -L "{{ mysql_snap_size }}" -n "{{ mysql_snap }}"

在DBS中没有LV…

[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf /]# lvdisplay
  No volume groups found

接下来的硬盘连接了vda和vdb。

[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf /]# lsblk
NAME                            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sr0                              11:0    1  410K  0 rom
vda                             252:0    0   10G  0 disk
└─vda1                          252:1    0   10G  0 part /
vdb                             252:16   0   10G  0 disk /mnt

由于在backup_snapshot.yml中连接了/dev/vdd1,所以可以推测vdc和vdd已连接。
根据在SoftLayer免费裸金属上学习OpenStack(10)-第9章“利用块卷进行数据保护”(使用Cinder)的步骤,我们需要添加两个卷。
我们将在vdc上创建LVM并将其作为mysql的数据区域。
我们将vdd作为常规的ext4分区用作备份区域。

用Cinder创建两个卷。


(venv)[ansible@step-server ~]$ cinder create --display-name dbs_vdc --availability-zone az1 10
+---------------------+--------------------------------------+
|       Property      |                Value                 |
+---------------------+--------------------------------------+
|     attachments     |                  []                  |
|  availability_zone  |                 az1                  |
|       bootable      |                false                 |
|      created_at     |      2015-03-30T11:43:00.654349      |
| display_description |                 None                 |
|     display_name    |               dbs_vdc                |
|      encrypted      |                False                 |
|          id         | 5293f5c7-d386-4b36-9092-252f724eeafd |
|       metadata      |                  {}                  |
|         size        |                  10                  |
|     snapshot_id     |                 None                 |
|     source_volid    |                 None                 |
|        status       |               creating               |
|     volume_type     |                 None                 |
+---------------------+--------------------------------------+

(venv)[ansible@step-server ~]$ cinder create --display-name dbs_vdd --availability-zone az1 10
+---------------------+--------------------------------------+
|       Property      |                Value                 |
+---------------------+--------------------------------------+
|     attachments     |                  []                  |
|  availability_zone  |                 az1                  |
|       bootable      |                false                 |
|      created_at     |      2015-03-30T11:43:13.524431      |
| display_description |                 None                 |
|     display_name    |               dbs_vdd                |
|      encrypted      |                False                 |
|          id         | e7f73a03-e9a3-4f27-9a33-a40c869d13cb |
|       metadata      |                  {}                  |
|         size        |                  10                  |
|     snapshot_id     |                 None                 |
|     source_volid    |                 None                 |
|        status       |               creating               |
|     volume_type     |                 None                 |
+---------------------+--------------------------------------+

连接到DBS。


(venv)[ansible@step-server ~]$ function get_uuid () { cat - | grep " id " | awk '{print $4}'; }

(venv)[ansible@step-server ~]$ export MY_DBS_VDC=`cinder show dbs_vdc |get_uuid`

(venv)[ansible@step-server ~]$ export MY_DBS_VDD=`cinder show dbs_vdd |get_uuid`

(venv)[ansible@step-server ~]$ nova volume-attach dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf $MY_DBS_VDC
+----------+--------------------------------------+
| Property | Value                                |
+----------+--------------------------------------+
| device   | /dev/vdc                             |
| id       | 5293f5c7-d386-4b36-9092-252f724eeafd |
| serverId | e4908bd6-c862-4993-964c-44c7bf6c4ddf |
| volumeId | 5293f5c7-d386-4b36-9092-252f724eeafd |
+----------+--------------------------------------+

(venv)[ansible@step-server ~]$ nova volume-attach dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf $MY_DBS_VDD
+----------+--------------------------------------+
| Property | Value                                |
+----------+--------------------------------------+
| device   | /dev/vdd                             |
| id       | e7f73a03-e9a3-4f27-9a33-a40c869d13cb |
| serverId | e4908bd6-c862-4993-964c-44c7bf6c4ddf |
| volumeId | e7f73a03-e9a3-4f27-9a33-a40c869d13cb |
+----------+--------------------------------------+

连接成功。

[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf /]# lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sr0     11:0    1  410K  0 rom
vda    252:0    0   10G  0 disk
└─vda1 252:1    0   10G  0 part /
vdb    252:16   0   10G  0 disk /mnt
vdc    252:32   0   10G  0 disk
vdd    252:48   0   10G  0 disk

计划创建名为「/dev/mysql_vg/mysql_vol01」的LVM快照。

将/dev/vdc的类型更改为8e(Linux LVM)。

[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf /]# fdisk /dev/vdc
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel with disk identifier 0xed33b73b.
Changes will remain in memory only, until you decide to write them.
After that, of course, the previous content won't be recoverable.

Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)

WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
         switch off the mode (command 'c') and change display units to
         sectors (command 'u').

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-20805, default 1):
Using default value 1
Last cylinder, +cylinders or +size{K,M,G} (1-20805, default 20805):
Using default value 20805

Command (m for help): t
Selected partition 1
Hex code (type L to list codes): 8e
Changed system type of partition 1 to 8e (Linux LVM)

Command (m for help): p

Disk /dev/vdc: 10.7 GB, 10737418240 bytes
16 heads, 63 sectors/track, 20805 cylinders
Units = cylinders of 1008 * 512 = 516096 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xed33b73b

   Device Boot      Start         End      Blocks   Id  System
/dev/vdc1               1       20805    10485688+  8e  Linux LVM

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

在/dev/vdc1上创建一个物理卷(pv),并创建vg命名为”mysql_vg”,lv命名为”mysql_vol01″。

[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf /]# pvcreate /dev/vdc1
  Physical volume "/dev/vdc1" successfully created

[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf /]# vgcreate mysql_vg /dev/vdc1
  Volume group "mysql_vg" successfully created

[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf /]# lvcreate -L 5G -n mysql_vol01 mysql_vg
  Logical volume "mysql_vol01" created

创建了/dev/mysql_vg/mysql_vol01。

[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf /]# lsblk
NAME                            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sr0                              11:0    1  410K  0 rom
vda                             252:0    0   10G  0 disk
└─vda1                          252:1    0   10G  0 part /
vdb                             252:16   0   10G  0 disk /mnt
vdc                             252:32   0   10G  0 disk
└─vdc1                          252:33   0   10G  0 part
  └─mysql_vg-mysql_vol01 (dm-0) 253:0    0    5G  0 lvm
vdd                             252:48   0   10G  0 disk

[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf /]# ls /dev/mysql_vg/mysql_vol01
/dev/mysql_vg/mysql_vol01

创建一个ext4文件系统,并将MySQL数据迁移到/var/lib/mysql目录中进行挂载。

[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf /]# mkfs.ext4 -L mysql_data /dev/mysql_vg/mysql_vol01

[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf /]# tune2fs -c 0 -i 0 -r 0 /dev/mysql_vg/mysql_vol01

[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf /]# mkdir /tmp/data

[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf /]# mount LABEL=mysql_data /tmp/data

[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf /]# chown -R mysql:mysql /tmp/data

[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf /]# service mysqld stop

[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf /]# mv /var/lib/mysql/* /tmp/data/


[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf /]# umount /tmp/data/

[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf /]# mount LABEL=mysql_data /var/lib/mysql

[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf /]# service mysqld start

在Linux操作系统的83版本上创建一个ext4文件系统。

[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf /]# fdisk /dev/vdd

[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf /]# mkfs.ext4 -L mysql_backup /dev/vdd1

[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf /]# tune2fs -c 0 -i 0 -r 0 /dev/vdd1

我已经成功地使用Ansible实现自动备份。

(venv)[ansible@step-server ~]$ ansible-playbook -i sample_app_inventory.py -t snapshot,backup -u root db_backup.yml

PLAY [dbs] ********************************************************************

GATHERING FACTS ***************************************************************
ok: [192.168.0.27]

TASK: [stop mysqld] ***********************************************************
changed: [192.168.0.27]

TASK: [umount mysql_dir] ******************************************************
changed: [192.168.0.27]

TASK: [create snapshot on lvm] ************************************************
changed: [192.168.0.27]

TASK: [mount mysql_dir] *******************************************************
changed: [192.168.0.27]

TASK: [start mysqld] **********************************************************
changed: [192.168.0.27]

PLAY [app] ********************************************************************

GATHERING FACTS ***************************************************************
ok: [192.168.0.26]

TASK: [restart rest app] ******************************************************
changed: [192.168.0.26]

PLAY [dbs] ********************************************************************

GATHERING FACTS ***************************************************************
ok: [192.168.0.27]

TASK: [make directory] ********************************************************
changed: [192.168.0.27]

TASK: [mount backup] **********************************************************
changed: [192.168.0.27]

TASK: [mount snapshot] ********************************************************
changed: [192.168.0.27]

TASK: [archive database files to "{{ backup_mountpoint }}"] *******************
changed: [192.168.0.27]

TASK: [umount snapshot] *******************************************************
changed: [192.168.0.27]

TASK: [umount backup] *********************************************************
changed: [192.168.0.27]

TASK: [remove snapshot] *******************************************************
changed: [192.168.0.27]

PLAY RECAP ********************************************************************
192.168.0.26               : ok=2    changed=1    unreachable=0    failed=0
192.168.0.27               : ok=14   changed=12   unreachable=0    failed=0

第11章已经结束了。总算是解决了。


上一次是这里-下一次是这里

广告
将在 10 秒后关闭
bannerAds