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

使用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 应用程序部署的自动化
在这里进行的是以下四点。
-
- 时区的更改
-
- 从github中拉取应用程序检查
-
- 执行安装脚本
-
- 通过编辑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的目标。
外部程序的条件如下所示,并在本书中有所提及。
-
- 如果以-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章已经结束了。总算是解决了。
上一次是这里-下一次是这里