{"id":42770,"date":"2022-11-22T16:18:50","date_gmt":"2022-11-02T10:12:19","guid":{"rendered":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8softlayer%e7%9a%84%e5%85%8d%e8%b4%b9%e8%a3%b8%e9%87%91%e5%b1%9e%e6%9c%8d%e5%8a%a1%e5%99%a8%e4%b8%8a%e5%ad%a6%e4%b9%a0openstack%ef%bc%8812%ef%bc%89-%e7%ac%ac11%e7%ab%a0-%e5%88%a9%e7%94%a8an\/"},"modified":"2024-04-29T01:58:36","modified_gmt":"2024-04-28T17:58:36","slug":"%e5%9c%a8softlayer%e7%9a%84%e5%85%8d%e8%b4%b9%e8%a3%b8%e9%87%91%e5%b1%9e%e6%9c%8d%e5%8a%a1%e5%99%a8%e4%b8%8a%e5%ad%a6%e4%b9%a0openstack%ef%bc%8812%ef%bc%89-%e7%ac%ac11%e7%ab%a0-%e5%88%a9%e7%94%a8an","status":"publish","type":"post","link":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8softlayer%e7%9a%84%e5%85%8d%e8%b4%b9%e8%a3%b8%e9%87%91%e5%b1%9e%e6%9c%8d%e5%8a%a1%e5%99%a8%e4%b8%8a%e5%ad%a6%e4%b9%a0openstack%ef%bc%8812%ef%bc%89-%e7%ac%ac11%e7%ab%a0-%e5%88%a9%e7%94%a8an\/","title":{"rendered":"\u5728SoftLayer\u7684\u514d\u8d39\u88f8\u91d1\u5c5e\u670d\u52a1\u5668\u4e0a\u5b66\u4e60OpenStack\uff0812\uff09- \u7b2c11\u7ae0 &#8220;\u5229\u7528Ansible\u8fdb\u884c\u914d\u7f6e\u7ba1\u7406\u81ea\u52a8\u5316&#8221;"},"content":{"rendered":"<p>\u4e0a\u56de\u662f\u5728\u8fd9\u91cc-\u4e0b\u56de\u662f\u5728\u8fd9\u91cc\u3002<\/p>\n<hr \/>\n<h1>\u8fd9\u662f\u4ec0\u4e48\uff1f<\/h1>\n<div><img decoding=\"async\" class=\"post-images\" title=\"\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d4ec437434c4406cc199d\/3-0.png\" alt=\"OpenStack\u30af\u30e9\u30a6\u30c9\u30a4\u30f3\u30c6\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3 \u30aa\u30fc\u30d7\u30f3\u30bd\u30fc\u30b9\u30af\u30e9\u30a6\u30c9\u306b\u3088\u308b\u30b5\u30fc\u30d3\u30b9\u69cb\u7bc9\u5165\u9580\" \/><\/div>\n<h1>\u4f7f\u7528ansible\u5b9e\u73b0\u914d\u7f6e\u7ba1\u7406\u7684\u81ea\u52a8\u5316\u7684\u7b2c11\u7ae0<\/h1>\n<p>\u5728\u524d\u9762\u7684\u4e5d\u4e2a\u7ae0\u8282\u4e2d\uff0c\u6211\u4eec\u5b66\u4e60\u4e86\u5982\u4f55\u4f7f\u7528OpenStack\u7684\u6807\u51c6\u529f\u80fd\u3002\u5728\u672c\u7ae0\u4e2d\uff0c\u6211\u4eec\u5c06\u5b66\u4e60\u5982\u4f55\u5229\u7528Ansible\u6765\u63d0\u9ad8OpenStack\u7684\u8fd0\u7ef4\u6548\u7387\u3002<\/p>\n<p>\u8fd9\u91cc\u662f\u7ae0\u7684\u652f\u63f4\u6587\u4ef6\u3002<\/p>\n<h2>11.1 \u6545\u4e8b\u60c5\u8282\u7684\u53d1\u5c55<\/h2>\n<p>Ansible\u7ae0\u8282\u7684\u5f15\u8a00\uff0c\u65e8\u5728\u6539\u5584\u8fd0\u7ef4\u3002<\/p>\n<h2>11.2. \u5f15\u5165\u548c\u914d\u7f6eAnsible<\/h2>\n<h3>11.2.1 \u5b89\u88c5Ansible<\/h3>\n<p>\u64cd\u4f5c\u7cfb\u7edf\u63d0\u4f9b\u4e86\u51e0\u79cd\u8f6f\u4ef6\u5305\u3001pip\u548c\u4ece\u6e90\u4ee3\u7801\u6784\u5efa\u7684\u5b89\u88c5\u65b9\u6cd5\u3002\u4e0b\u9762\u662f\u5bf9\u8fd9\u4e09\u79cd\u65b9\u6cd5\u7684\u8bf4\u660e\u3002\u7136\u800c\uff0c\u672c\u4e66\u7684\u63cf\u8ff0\u5047\u8bbe\u4f7f\u7528pip\u8fdb\u884c\u5b89\u88c5\uff0c\u56e0\u6b64\u8bf7\u6839\u636e\u6b64\u8fdb\u884c\u64cd\u4f5c\u3002<\/p>\n<p>\u88ab\u5f15\u5bfc\u7684\u662f\u201cDevelopment Tools\u201d\u8f6f\u4ef6\u5305\u7ec4\u548c\u201cpython-virtualenv\u201d\u8f6f\u4ef6\u5305\u7684\u5b89\u88c5\u3002<\/p>\n<pre class=\"post-pre\"><code>[root@step-server ~]# yum groupinstall -y \"Development Tools\"\r\n\uff5e\uff5e\uff5e\uff5e\uff5e\uff5e\uff5e\uff5e\r\nComplete!\r\n[root@step-server ~]# yum install -y python-virtualenv\r\n\uff5e\uff5e\uff5e\uff5e\uff5e\uff5e\uff5e\uff5e\r\nComplete!\r\n<\/code><\/pre>\n<p>\u5728\u6b64\u4e4b\u540e\uff0c\u7531\u4e00\u822c\u7528\u6237\u6267\u884c\u4efb\u52a1\uff0c\u56e0\u6b64\u6211\u4eec\u9700\u8981\u521b\u5efa\u4e00\u4e2a\u540d\u4e3auser01\u7684\u4e00\u822c\u7528\u6237\u5e76\u8fdb\u884c\u5207\u6362\u3002<\/p>\n<pre class=\"post-pre\"><code>[root@step-server ~]# adduser user01\r\n[root@step-server ~]# su - user01\r\n<\/code><\/pre>\n<p>\u4ee5\u4e00\u822c\u7528\u6237user01\u8eab\u4efd\uff0c\u5728Python\u865a\u62df\u6267\u884c\u73af\u5883\u4e0b\u5b89\u88c5Ansible\u3002<\/p>\n<pre class=\"post-pre\"><code>[user01@step-server ~]$ virtualenv venv\r\nNew python executable in venv\/bin\/python\r\nInstalling Setuptools..............................................................................................................................................................................................................................done.\r\nInstalling Pip.....................................................................................................................................................................................................................................................................................................................................done.\r\n[user01@step-server ~]$ source venv\/bin\/activate\r\n\r\n(venv)[user01@step-server ~]$ pip install jinja2 passlib pycrypto pyyaml\r\nDownloading\/unpacking jinja2\r\n\uff5e\uff5e\uff5e\uff5e\uff5e\uff5e\uff5e\uff5e\r\nSuccessfully installed jinja2 passlib pycrypto pyyaml markupsafe\r\nCleaning up...\r\n\r\n(venv)[user01@step-server ~]$ pip install ansible\r\nDownloading\/unpacking ansible\r\n  Downloading ansible-1.9.0.1.tar.gz (916kB): 916kB downloaded\r\n\uff5e\uff5e\uff5e\uff5e\uff5e\uff5e\uff5e\uff5e\r\nSuccessfully installed ansible paramiko ecdsa\r\nCleaning up...\r\n\r\n(venv)[user01@step-server ~]$ ansible --version\r\nansible 1.9.0.1\r\n  configured module search path = None\r\n<\/code><\/pre>\n<p>\u5df2\u7ecf\u63a8\u51fa\u4e861.9.0.1\u7248\u672c\u3002\u672c\u4e66\u4e2d\u786e\u8ba4\u4f7f\u7528\u7684\u662f1.8.2\u3002<\/p>\n<h3>11.2.2 Ansible\u7684\u57fa\u672c\u8bbe\u7f6e<\/h3>\n<p>\u5c06\u57fa\u672c\u914d\u7f6e\u5199\u5165\u5230$HOME\/.ansible.cfg\u6587\u4ef6\u4e2d\u3002<\/p>\n<p>\u521b\u5efa\u65e5\u5fd7\u76ee\u5f55\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[user01@step-server ~]$ mkdir $HOME\/log\r\n<\/code><\/pre>\n<p>\u8bbe\u5b9a $HOME\/.ansible.cfg\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[user01@step-server ~]$ nano .ansible.cfg\r\n(venv)[user01@step-server ~]$ cat .ansible.cfg\r\n[defaults]\r\nforks                   = 10\r\nlog_path                = \/home\/user01\/log\/ansible.log\r\nhost_key_checking       = False\r\ngathering               = smart\r\ntransport               = smart\r\n<\/code><\/pre>\n<h3>11.2.3 \u9a8c\u8bc1 Ansible \u7684\u8fd0\u884c\u60c5\u51b5<\/h3>\n<p>\u5c1d\u8bd5\u4f7f\u7528Ansible\u5728\u672c\u5730\u4e3b\u673a\u4e0a\u8fdb\u884cping\u6d4b\u8bd5\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[user01@step-server ~]$ cd\r\n(venv)[user01@step-server ~]$ pwd\r\n\/home\/user01\r\n(venv)[user01@step-server ~]$ echo \"localhost ansible_connection=local\" &gt; ansible_hosts\r\n(venv)[user01@step-server ~]$ ansible all -i ansible_hosts -m ping\r\nlocalhost | success &gt;&gt; {\r\n    \"changed\": false,\r\n    \"ping\": \"pong\"\r\n}\r\n<\/code><\/pre>\n<p>\u5728ansible_hosts\u4e2d\u65b0\u589e192.168.0.11\u548c192.168.0.21\u3002\u4f46\u662f192.168.0.11\u7684\u4e3b\u673a\u4e0d\u5b58\u5728\u3002192.168.0.21\u662f\u7b2c10\u7ae0\u4e2daz2-dbs01\u7559\u5b58\u7684\u5730\u5740\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[user01@step-server ~]$ nano ansible_hosts\r\n(venv)[user01@step-server ~]$ cat ansible_hosts\r\nlocalhost ansible_connection=local\r\n192.168.0.11\r\n192.168.0.21\r\n<\/code><\/pre>\n<p>Ansible\u7684\u64cd\u4f5c\u57fa\u672c\u4e0a\u662f\u901a\u8fc7ssh\u8fde\u63a5\u8fdb\u884c\u7684\u3002<br \/>\nlocalhost\u56e0\u4e3a\u6709&#8221;ansible_connection=local&#8221;\u7684\u914d\u7f6e\uff0c\u6240\u4ee5\u53ef\u4ee5\u5728\u4e0d\u8fdb\u884cssh\u8fde\u63a5\u7684\u60c5\u51b5\u4e0b\u6210\u529f\u6267\u884c\u3002<br \/>\n192.168.0.21\u5c1d\u8bd5\u901a\u8fc7ssh\u8fdb\u884cTCP\u8fde\u63a5\uff0c\u4f46\u7531\u4e8e\u65e0\u6cd5\u767b\u5f55\u800c\u5bfc\u81f4\u51fa\u73b0\u9519\u8bef\u3002<br \/>\n192.168.0.11\u7531\u4e8e\u8be5IP\u4e0a\u6ca1\u6709\u542f\u52a8\u670d\u52a1\u5668\uff0c\u6240\u4ee5\u5728\u5c1d\u8bd5\u901a\u8fc7ssh\u8fdb\u884cTCP\u8fde\u63a5\u65f6\u51fa\u73b0\u9519\u8bef\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[user01@step-server ~]$ ansible all -i ansible_hosts -m ping\r\nlocalhost | success &gt;&gt; {\r\n    \"changed\": false,\r\n    \"ping\": \"pong\"\r\n}\r\n\r\n192.168.0.21 | FAILED =&gt; SSH Error: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).\r\n    while connecting to 192.168.0.21:22\r\nIt is sometimes useful to re-run the command using -vvvv, which prints SSH debug output to help diagnose the issue.\r\n192.168.0.11 | FAILED =&gt; SSH Error: ssh: connect to host 192.168.0.11 port 22: No route to host\r\n    while connecting to 192.168.0.11:22\r\nIt is sometimes useful to re-run the command using -vvvv, which prints SSH debug output to help diagnose the issue.\r\n<\/code><\/pre>\n<p>\u4e3a\u4e86\u80fd\u591f\u901a\u8fc7ssh\u767b\u5f55\u5230192.168.0.21\uff0c\u5c06ssh\u5bc6\u94a5\u590d\u5236\u5230\/home\/user01\/\u5e76\u5c06\u6240\u6709\u6743\u8bbe\u7f6e\u4e3auser01\u3002<\/p>\n<pre class=\"post-pre\"><code>[root@step-server ~]# cp key-for-internal.pem \/home\/user01\/\r\n[root@step-server ~]# cd \/home\/user01\r\n[root@step-server user01]# chown user01 key-for-internal.pem\r\n[root@step-server user01]# ls -al key-for-internal.pem\r\n-rw------- 1 user01 root 1680 Mar 29 18:03 key-for-internal.pem\r\n<\/code><\/pre>\n<p>\u8bf7\u5728.ansible.cfg\u914d\u7f6e\u6587\u4ef6\u4e2d\u4f7f\u7528\u5b8c\u6574\u8def\u5f84\u8bbe\u7f6eprivate_key_file\u4e3a\u79c1\u94a5\u7684\u8def\u5f84\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[user01@step-server ~]$ cat .ansible.cfg\r\n[defaults]\r\nforks                   = 10\r\nlog_path                = \/home\/user01\/log\/ansible.log\r\nhost_key_checking       = False\r\ngathering               = smart\r\ntransport               = smart\r\nprivate_key_file        = \/home\/user01\/key-for-internal.pem\r\n<\/code><\/pre>\n<p>\u5728\u6267\u884cansible\u65f6\uff0c\u4f7f\u7528&#8221;-u root&#8221;\u53c2\u6570\uff0c\u58f0\u660e\u8981\u4ee5root\u8eab\u4efd\u767b\u5f55\u5230\u76ee\u6807\u4e3b\u673a\u3002<br \/>\n\u4f7f\u7528\/home\/user01\/key-for-internal.pem\u8fde\u63a5\u5230root@192.168.0.21\uff0c\u5e76\u6210\u529f\u8fdb\u884c\u4e86ping\u6d4b\u8bd5\u3002<\/p>\n<p>\u5f53\u7136192.168.0.11\u4f1a\u5931\u8d25\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[user01@step-server ~]$ ansible all -i ansible_hosts -m ping -u root\r\nlocalhost | success &gt;&gt; {\r\n    \"changed\": false,\r\n    \"ping\": \"pong\"\r\n}\r\n\r\n192.168.0.21 | success &gt;&gt; {\r\n    \"changed\": false,\r\n    \"ping\": \"pong\"\r\n}\r\n\r\n192.168.0.11 | FAILED =&gt; SSH Error: ssh: connect to host 192.168.0.11 port 22: No route to host\r\n    while connecting to 192.168.0.11:22\r\nIt is sometimes useful to re-run the command using -vvvv, which prints SSH debug output to help diagnose the issue.\r\n<\/code><\/pre>\n<p>\u76ee\u6807\u8bbe\u5b9a\u4e3a\u201c\u6240\u6709\uff1a\uff01192.168.0.11\u201d\u3002\u4f7f\u7528\u201c\uff01\u201d\u7b26\u53f7\uff0c\u9664\u53bb192.168.0.11\u540e\uff0c\u201c\u6240\u6709\u201d\u6210\u4e3a\u76ee\u6807\u3002<\/p>\n<p>\u7531\u65bc192.168.0.11\u5df2\u88ab\u6392\u9664\u5728\u76ee\u6a19\u4e4b\u5916\uff0c\u53ef\u4ee5\u78ba\u8a8d\u5c0d\u6240\u6709\u76ee\u6a19\u7684ping\u5fdc\u7b54\u6b63\u5e38\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[user01@step-server ~]$ ansible 'all:!192.168.0.11' -i ansible_hosts -m ping -u root\r\nlocalhost | success &gt;&gt; {\r\n    \"changed\": false,\r\n    \"ping\": \"pong\"\r\n}\r\n\r\n192.168.0.21 | success &gt;&gt; {\r\n    \"changed\": false,\r\n    \"ping\": \"pong\"\r\n}\r\n<\/code><\/pre>\n<h2>11.3 Ansible\u7684\u673a\u5236<\/h2>\n<p>\u6b63\u5982\u8282\u6807\u9898\u6240\u793a\uff0c\u8fd9\u662f\u5173\u4e8eAnsible\u5de5\u4f5c\u539f\u7406\u7684\u89e3\u91ca\u3002<\/p>\n<p>\u8fd0\u884c\u66f4\u6539\u6b64\u4e3b\u673a\u540d\u7684\u64ad\u653e\u4e66\u4ee5\u786e\u8ba4\u64cd\u4f5c\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[user01@step-server samples]$ ansible-playbook -i ~\/ansible_hosts -u root -e target=192.168.0.21 sample-11-1.yml\r\n\r\nPLAY [192.168.0.21] ***********************************************************\r\n\r\nGATHERING FACTS ***************************************************************\r\nok: [192.168.0.21]\r\n\r\nTASK: [get hostname] **********************************************************\r\nchanged: [192.168.0.21]\r\n\r\nTASK: [set hostname] **********************************************************\r\nchanged: [192.168.0.21]\r\n\r\nNOTIFIED: [show hostname] *****************************************************\r\nok: [192.168.0.21] =&gt; {\r\n    \"msg\": \"before=az2-dbs01 after=ansible-host1\"\r\n}\r\n\r\nPLAY RECAP ********************************************************************\r\n192.168.0.21               : ok=4    changed=2    unreachable=0    failed=0\r\n\r\n<\/code><\/pre>\n<p>az2-dbs01\u7684\u4e3b\u673a\u540d\u5df2\u88ab\u66f4\u6539\u4e3aansible-host1\u3002<\/p>\n<p>\u518d\u6267\u884c\u4e00\u6b21\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[user01@step-server samples]$ ansible-playbook -i ~\/ansible_hosts -u root -e target=192.168.0.21 sample-11-1.yml\r\n\r\nPLAY [192.168.0.21] ***********************************************************\r\n\r\nGATHERING FACTS ***************************************************************\r\nok: [192.168.0.21]\r\n\r\nTASK: [get hostname] **********************************************************\r\nchanged: [192.168.0.21]\r\n\r\nTASK: [set hostname] **********************************************************\r\nok: [192.168.0.21]\r\n\r\nPLAY RECAP ********************************************************************\r\n192.168.0.21               : ok=3    changed=1    unreachable=0    failed=0\r\n\r\n<\/code><\/pre>\n<p>\u7531\u4e8e\u5df2\u7ecf\u66f4\u6539\u4e86\u4e3b\u673a\u540d\uff0c\u56e0\u6b64handlers\u4e0d\u4f1a\u88ab\u8c03\u7528\uff0c&#8221;NOTIFIED: [show hostname]&#8221;\u4e0d\u4f1a\u88ab\u8c03\u7528\u3002<\/p>\n<h2>14.4 \u4f7f\u7528Ansible\u81ea\u52a8\u5316\u57fa\u672c\u64cd\u4f5c<\/h2>\n<h3>\u5b89\u88c5\/\u66f4\u65b0CentOS\u7684\u8f6f\u4ef6\u5305<\/h3>\n<p>\u5b89\u88c5\/\u66f4\u65b0\u8f6f\u4ef6\u5305\u3002\u4f7f\u7528\u7684\u5267\u672c\u5728\u8fd9\u91cc\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[user01@step-server samples]$ ansible-playbook -i ~\/ansible_hosts -u root -e target=192.168.0.21 sample-11-2.yml\r\n\r\nPLAY [192.168.0.21] ***********************************************************\r\n\r\nGATHERING FACTS ***************************************************************\r\nok: [192.168.0.21]\r\n\r\nTASK: [install or upgrade packages] *******************************************\r\nchanged: [192.168.0.21] =&gt; (item=bash,tcsh,zsh)\r\n\r\nPLAY RECAP ********************************************************************\r\n192.168.0.21               : ok=2    changed=1    unreachable=0    failed=0\r\n\r\n<\/code><\/pre>\n<h3>11.4.2 \u521b\u5efa\u7528\u6237\u5e10\u6237<\/h3>\n<p>\u5728\u76ee\u6807\u4e3b\u673a\u4e0a\u521b\u5efa\u4e00\u4e2a\u540d\u4e3aansible\u7684\u7528\u6237\u3002\u4ee5\u4e0b\u662f\u8981\u4f7f\u7528\u7684playbook\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[user01@step-server samples]$ ansible-playbook -i ~\/ansible_hosts -u root -e target=192.168.0.21 sample-11-3.yml\r\nEnter a new user's password:\r\nconfirm Enter a new user's password:\r\n***** VALUES ENTERED DO NOT MATCH ****\r\nEnter a new user's password:\r\nconfirm Enter a new user's password:\r\n\r\nPLAY [192.168.0.21] ***********************************************************\r\n\r\nGATHERING FACTS ***************************************************************\r\nok: [192.168.0.21]\r\n\r\nTASK: [add a new user on target host] *****************************************\r\nchanged: [192.168.0.21]\r\n\r\nTASK: [add a publickey on localhost to authorized_keys on target host] ********\r\nfatal: [192.168.0.21] =&gt; could not locate file in lookup: \/root\/.ssh\/id_rsa.pub\r\n\r\nFATAL: all hosts have already failed -- aborting\r\n\r\nPLAY RECAP ********************************************************************\r\n           to retry, use: --limit @\/home\/user01\/sample-11-3.retry\r\n\r\n192.168.0.21               : ok=2    changed=1    unreachable=1    failed=0\r\n\r\n<\/code><\/pre>\n<p>\u5982\u679c\u5728\u91cd\u65b0\u8f93\u5165\u5bc6\u7801\u65f6\u72af\u4e86\u9519\u8bef\uff0c\u5c31\u4f1a\u88ab\u8981\u6c42\u518d\u6b21\u8f93\u5165\u3002<br \/>\n\u8bbf\u95ee\u201c\/root\/.ssh\/id_rsa.pub\u201d\u65f6\u51fa\u73b0\u9519\u8bef\u3002\u5982\u679c\u4ed4\u7ec6\u9605\u8bfb\u672c\u4e66\uff0c\u4f1a\u53d1\u73b0\u5728\u4e8b\u524d\u4f7f\u7528ssh-keygen\u521b\u5efa\u4e86\u516c\u94a5\uff0c\u9700\u8981\u6307\u5b9a\u5b83\u3002<\/p>\n<p>\u521b\u5efa\u300c\/home\/user01\/.ssh\/id_rsa.pub\u300d\u6587\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[user01@step-server samples]$ ssh-keygen -t rsa\r\nGenerating public\/private rsa key pair.\r\nEnter file in which to save the key (\/home\/user01\/.ssh\/id_rsa):\r\nEnter passphrase (empty for no passphrase):\r\nEnter same passphrase again:\r\nYour identification has been saved in \/home\/user01\/.ssh\/id_rsa.\r\nYour public key has been saved in \/home\/user01\/.ssh\/id_rsa.pub.\r\nThe key fingerprint is:\r\n74:11:82:b0:f5:aa:c2:0f:cf:b8:45:f4:d6:26:44:7a user01@step-server\r\nThe key's randomart image is:\r\n+--[ RSA 2048]----+\r\n|    ..o.. o.     |\r\n|     =.. . .     |\r\n|    + E o .      |\r\n|   . + + .       |\r\n|    . = S        |\r\n| . . o o         |\r\n|  + o            |\r\n|   O             |\r\n|  o.+            |\r\n+-----------------+\r\n<\/code><\/pre>\n<p>\u4fee\u6539\u516c\u94a5\u6587\u4ef6\u7684\u540d\u79f0\u3002<\/p>\n<pre class=\"post-pre\"><code>    authorized_key:\r\n      user: \"{{ username }}\"\r\n      key: \"{{ lookup('file', '\/home\/user01\/.ssh\/id_rsa.pub') }}\"\r\n<\/code><\/pre>\n<p>\u8fd9\u4e00\u6b21\u53d6\u5f97\u4e86\u6210\u529f\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[user01@step-server samples]$ ansible-playbook -i ~\/ansible_hosts -u root -e target=192.168.0.21 sample-11-3.yml\r\nEnter a new user's password:\r\nconfirm Enter a new user's password:\r\n\r\nPLAY [192.168.0.21] ***********************************************************\r\n\r\nGATHERING FACTS ***************************************************************\r\nok: [192.168.0.21]\r\n\r\nTASK: [add a new user on target host] *****************************************\r\nchanged: [192.168.0.21]\r\n\r\nTASK: [add a publickey on localhost to authorized_keys on target host] ********\r\nchanged: [192.168.0.21]\r\n\r\nPLAY RECAP ********************************************************************\r\n192.168.0.21               : ok=3    changed=2    unreachable=0    failed=0\r\n<\/code><\/pre>\n<p>\u53ef\u4ee5\u8fdb\u884cSSH\u767b\u5f55\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[user01@step-server samples]$ ssh ansible@192.168.0.21\r\n[ansible@ansible-host1 ~]$ exit\r\nlogout\r\nConnection to 192.168.0.21 closed.\r\n<\/code><\/pre>\n<h3>\u6dfb\u52a0sudo\u914d\u7f6e\u3002<\/h3>\n<p>\u5728ansible\u6240\u5c5e\u7684&#8221;wheel&#8221;\u7ec4\u4e2d\u6dfb\u52a0&#8221;\/etc\/sudoers&#8221;\u7684\u6761\u76ee\u3002\u53ea\u5728&#8221;wheel&#8221;\u7ec4\u4e0d\u5b58\u5728\u65f6\u8fdb\u884c\u6dfb\u52a0\u3002\u53ef\u4ee5\u4f7f\u7528\u6b64playbook\u3002<\/p>\n<p>\u7b2c\u4e00\u6b21\u6267\u884c\u65f6\uff0c\u7531\u4e8e\u6ca1\u6709\u8bb0\u5f55\uff0c&#8221;TASK: [grant privileges to do the sudo command to the wheel group]&#8221; \u6807\u8bb0\u4e3a &#8220;changed&#8221;\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[user01@step-server samples]$ ansible-playbook -i ~\/ansible_hosts -u root -e target=192.168.0.21 sample-11-4.yml\r\n\r\nPLAY [192.168.0.21] ***********************************************************\r\n\r\nGATHERING FACTS ***************************************************************\r\nok: [192.168.0.21]\r\n\r\nTASK: [grant privileges to do the sudo command to the wheel group] ************\r\nchanged: [192.168.0.21]\r\n\r\nPLAY RECAP ********************************************************************\r\n192.168.0.21               : ok=2    changed=1    unreachable=0    failed=0\r\n<\/code><\/pre>\n<p>\u5f53\u518d\u6b21\u6267\u884c\u65f6\uff0c\u4f1a\u663e\u793a&#8221;OK&#8221;\u5e76\u4e14\u4e0d\u4f1a\u8fdb\u884c\u4efb\u4f55\u9644\u52a0\u64cd\u4f5c\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[user01@step-server samples]$ ansible-playbook -i ~\/ansible_hosts -u root -e target=192.168.0.21 sample-11-4.yml\r\n\r\nPLAY [192.168.0.21] ***********************************************************\r\n\r\nGATHERING FACTS ***************************************************************\r\nok: [192.168.0.21]\r\n\r\nTASK: [grant privileges to do the sudo command to the wheel group] ************\r\nok: [192.168.0.21]\r\n\r\nPLAY RECAP ********************************************************************\r\n192.168.0.21               : ok=2    changed=0    unreachable=0    failed=0\r\n<\/code><\/pre>\n<h3>11.4.4 \u914d\u7f6e\u8bbe\u5b9a\u6587\u4ef6\u5e76\u91cd\u65b0\u542f\u52a8\u670d\u52a1\u3002<\/h3>\n<p>\u5c06\u9884\u5148\u51c6\u5907\u597d\u7684my.cnf.j2\u590d\u5236\u5230\/etc\/my.cnf\u3002\u4ec5\u5f53\u53d1\u751f\u6587\u4ef6\u66ff\u6362\u65f6\uff0c\u91cd\u65b0\u542f\u52a8MySQL\u3002\u53ef\u4f7f\u7528\u4ee5\u4e0b\u64ad\u653e\u5217\u8868\u3002<\/p>\n<p>\u7b2c\u4e00\u6b21\u65f6\uff0c[\u66ff\u6362\u4e86my.cnf]\u5e76\u4e14\u8c03\u7528\u4e86[\u91cd\u65b0\u542f\u52a8\u6570\u636e\u5e93]\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[user01@step-server samples]$ ansible-playbook -i ~\/ansible_hosts -u root -e target=192.168.0.21 sample-11-5.yml\r\n\r\nPLAY [192.168.0.21] ***********************************************************\r\n\r\nGATHERING FACTS ***************************************************************\r\nok: [192.168.0.21]\r\n\r\nTASK: [replace my.cnf] ********************************************************\r\nchanged: [192.168.0.21]\r\n\r\nNOTIFIED: [restart database] **************************************************\r\nchanged: [192.168.0.21]\r\n\r\nPLAY RECAP ********************************************************************\r\n192.168.0.21               : ok=3    changed=2    unreachable=0    failed=0\r\n<\/code><\/pre>\n<p>\u7b2c\u4e8c\u6b21\u7684\u65f6\u5019\uff0c[\u66ff\u6362\u6211\u7684.cnf]\u662f\u53ef\u4ee5\u7684\uff0c\u4e0d\u9700\u8981[\u91cd\u542f\u6570\u636e\u5e93]\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[user01@step-server samples]$ ansible-playbook -i ~\/ansible_hosts -u root -e target=192.168.0.21 sample-11-5.yml\r\n\r\nPLAY [192.168.0.21] ***********************************************************\r\n\r\nGATHERING FACTS ***************************************************************\r\nok: [192.168.0.21]\r\n\r\nTASK: [replace my.cnf] ********************************************************\r\nok: [192.168.0.21]\r\n\r\nPLAY RECAP ********************************************************************\r\n192.168.0.21               : ok=2    changed=0    unreachable=0    failed=0\r\n<\/code><\/pre>\n<h3>11.4.5 \u91cd\u65b0\u542f\u52a8\u64cd\u4f5c\u7cfb\u7edf\u4ee5\u786e\u8ba4\u542f\u52a8\u5b8c\u6210\u3002<\/h3>\n<p>\u8bf7\u91cd\u65b0\u542f\u52a8\u76ee\u6807\u4e3b\u673a\uff0c\u7b49\u5f852\u5206\u949f\u540e\u4ee510\u79d2\u7684\u95f4\u9694\u5c1d\u8bd5SSH\u8fde\u63a5\u786e\u8ba4\u662f\u5426\u6210\u529f\u3002\u4f7f\u7528\u7684\u5267\u672c\u4f4d\u4e8e\u8fd9\u91cc\u3002<\/p>\n<p>\u5982\u679c\u5728\u6682\u505c\u6a21\u5757\u4e2d\uff0c\u53ef\u4ee5\u901a\u8fc7\u201cCtrl+C\u201d\u6765\u4e2d\u6b62\u5e76\u663e\u793a\u6d88\u606f\u201cAction? (a)bort\/(c)ontinue:\u201d\uff0c\u4ee5\u4fbf\u7528\u6237\u77e5\u9053\u53ef\u4ee5\u901a\u8fc7\u201c^C-a\u201d\u6765\u4e2d\u6b62\u6216\u8005\u901a\u8fc7\u201c^C-c\u201d\u6765\u7ee7\u7eed\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[user01@step-server samples]$ ansible-playbook -i ~\/ansible_hosts -u root -e target=192.168.0.21 sample-11-6.yml\r\n\r\nPLAY [192.168.0.21] ***********************************************************\r\n\r\nGATHERING FACTS ***************************************************************\r\nok: [192.168.0.21]\r\n\r\nTASK: [reboot server] *********************************************************\r\nchanged: [192.168.0.21]\r\n\r\nTASK: [wait for shutdown process] *********************************************\r\n(^C-c = continue early, ^C-a = abort)\r\n[192.168.0.21]\r\nPausing for 120 seconds\r\n^C\r\nAction? (a)bort\/(c)ontinue:\r\nok: [192.168.0.21 -&gt; 127.0.0.1]\r\n\r\nTASK: [check the server to start up] ******************************************\r\nok: [192.168.0.21 -&gt; 127.0.0.1]\r\n\r\nPLAY RECAP ********************************************************************\r\n192.168.0.21               : ok=4    changed=1    unreachable=0    failed=0\r\n<\/code><\/pre>\n<p>\u5982\u679c\u5728\u6682\u505c\u6a21\u5757\u4e2d\u6ca1\u6709\u7b49\u5f85\u505c\u6b62\uff0c\u800c\u6309\u4e0b\u201cCtrl+C\u201d\u952e\uff0c\u5219\u4f1a\u7acb\u5373\u7ed3\u675f\u3002<\/p>\n<pre class=\"post-pre\"><code>TASK: [reboot server] *********************************************************\r\n^CERROR: interrupted\r\n(venv)[user01@step-server samples]$\r\n<\/code><\/pre>\n<h2>11.5 \u81ea\u52a8\u5316OpenStack\u7ba1\u7406\u64cd\u4f5c<\/h2>\n<h3>11.5.1 \u4e8b\u524d\u51c6\u5907\u5de5\u4f5c<\/h3>\n<p>\u5728\u8df3\u677f\u670d\u52a1\u5668\u4e0a\u521b\u5efa\u5e76\u5207\u6362\u7528\u6237ansible\u3002<\/p>\n<pre class=\"post-pre\"><code>[root@step-server ~]# useradd ansible\r\n[root@step-server ~]# cp \/root\/openrc \/home\/ansible\/\r\n[root@step-server ~]# chown ansible:ansible \/home\/ansible\/openrc\r\n[root@step-server ~]# su - ansible\r\n[ansible@step-server ~]$\r\n<\/code><\/pre>\n<p>\u7528\u6237\u4f7f\u7528 Ansible\uff0c\u4f7f\u7528 pip \u5b89\u88c5 Ansible\u3002<\/p>\n<pre class=\"post-pre\"><code>[ansible@step-server ~]$ virtualenv venv\r\nNew python executable in venv\/bin\/python\r\nInstalling Setuptools.............................................................................................done.\r\nInstalling Pip....................................................................................................................................done.\r\n\r\n[ansible@step-server ~]$ source venv\/bin\/activate\r\n\r\n(venv)[ansible@step-server ~]$ pip install jinja2 passlib pycrypto pyyaml\r\nDownloading\/unpacking jinja2\r\n\uff5e\uff5e\uff5e\uff5e\uff5e\uff5e\uff5e\uff5e\r\nSuccessfully installed jinja2 passlib pycrypto pyyaml markupsafe\r\nCleaning up...\r\n\r\n(venv)[ansible@step-server ~]$ pip install ansible\r\nDownloading\/unpacking ansible\r\n  Downloading ansible-1.9.0.1.tar.gz (916kB): 916kB downloaded\r\n\uff5e\uff5e\uff5e\uff5e\uff5e\uff5e\uff5e\uff5e\r\nSuccessfully installed ansible paramiko ecdsa\r\nCleaning up...\r\n<\/code><\/pre>\n<p>\u5b89\u88c5\u672c\u4e66\u7684\u652f\u63f4\u6587\u4ef6\u4ee5\u53capython-novaclient\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[ansible@step-server ~]$ cd $HOME\r\n\r\n(venv)[ansible@step-server ~]$ git clone https:\/\/github.com\/josug-book1-materials\/chapter11.git\r\nInitialized empty Git repository in \/home\/ansible\/chapter11\/.git\/\r\nremote: Counting objects: 218, done.\r\nremote: Total 218 (delta 0), reused 0 (delta 0), pack-reused 218\r\nReceiving objects: 100% (218\/218), 32.98 KiB, done.\r\nResolving deltas: 100% (116\/116), done.\r\n\r\n(venv)[ansible@step-server ~]$ pip install python-novaclient==2.16.0\r\nDownloading\/unpacking python-novaclient==2.16.0\r\n  Downloading python-novaclient-2.16.0.tar.gz (227kB): 227kB downloaded\r\n\uff5e\uff5e\uff5e\uff5e\uff5e\uff5e\uff5e\uff5e\r\nSuccessfully installed python-novaclient pbr argparse iso8601 PrettyTable requests simplejson six Babel pytz\r\nCleaning up..\r\n\r\n(venv)[ansible@step-server ~]$ pip install python-neutronclient==2.3.4\r\nDownloading\/unpacking python-neutronclient==2.3.4\r\n  Downloading python-neutronclient-2.3.4.tar.gz (105kB): 105kB downloaded\r\n\uff5e\uff5e\uff5e\uff5e\uff5e\uff5e\uff5e\uff5e\r\nSuccessfully installed python-neutronclient cliff httplib2 cmd2 pyparsing stevedore\r\nCleaning up...\r\n<\/code><\/pre>\n<p>\u5c06\u4ee5\u4e0b\u5185\u5bb9\u6dfb\u52a0\u5230\u4ee3\u7801\u4e2d\u4ee5\u83b7\u53d6\u7f51\u7edc\u7684UUID\uff0c\u5e76\u6267\u884c\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[ansible@step-server ~]$ cat openrc\r\nexport OS_AUTH_URL=http:\/\/192.168.100.10:5000\/v2.0\/\r\nexport OS_REGION_NAME=RegionOne\r\nexport OS_TENANT_NAME=SNSApp\r\nexport OS_USERNAME=snsapp-infra-user\r\nexport OS_PASSWORD=passw0rd\r\n\r\nfunction get_uuid () { cat - | grep \" id \" | awk '{print $4}'; }\r\nexport OS_DMZ_NET=`neutron net-show dmz-net | get_uuid`\r\nexport OS_APP_NET=`neutron net-show app-net | get_uuid`\r\nexport OS_DBS_NET=`neutron net-show dbs-net | get_uuid`\r\n\r\n(venv)[ansible@step-server ~]$ source openrc\r\n<\/code><\/pre>\n<p>\u521b\u5efa\u5bc6\u94a5\u5bf9\u5e76\u5c06\u5176\u6ce8\u518c\u5230OpenStack\u4e2d\u3002<\/p>\n<pre class=\"post-pre\"><code>\r\n(venv)[ansible@step-server ~]$ ssh-keygen -t rsa -b 2048 -N \"\"\r\nGenerating public\/private rsa key pair.\r\nEnter file in which to save the key (\/home\/ansible\/.ssh\/id_rsa):\r\nCreated directory '\/home\/ansible\/.ssh'.\r\nYour identification has been saved in \/home\/ansible\/.ssh\/id_rsa.\r\nYour public key has been saved in \/home\/ansible\/.ssh\/id_rsa.pub.\r\nThe key fingerprint is:\r\na1:49:c1:a2:6d:db:3b:bb:d9:91:50:88:0a:0d:53:1f ansible@step-server\r\nThe key's randomart image is:\r\n+--[ RSA 2048]----+\r\n|o.. E..          |\r\n| + ..o.o         |\r\n|. .oo.o o        |\r\n| ...o. + .       |\r\n|  .. o+ S        |\r\n|    . .. .       |\r\n|       .o        |\r\n|      oo .       |\r\n|      ++.        |\r\n+-----------------+\r\n\r\n(venv)[ansible@step-server ~]$ nova keypair-add --pub-key .ssh\/id_rsa.pub key-for-ansible\r\n\r\n(venv)[ansible@step-server ~]$ nova keypair-list\r\n+---------------------+-------------------------------------------------+\r\n| Name                | Fingerprint                                     |\r\n+---------------------+-------------------------------------------------+\r\n| key-for-step-server | c6:a2:cd:b5:ee:0b:29:ae:19:61:27:f8:5d:28:5f:8b |\r\n| key-for-internal    | 9d:89:c8:a7:c6:4b:f1:23:8c:41:9f:3f:a8:bf:91:77 |\r\n| key-for-ansible     | a1:49:c1:a2:6d:db:3b:bb:d9:91:50:88:0a:0d:53:1f |\r\n+---------------------+-------------------------------------------------+\r\n<\/code><\/pre>\n<h3>11.5.2 \u865a\u62df\u673a\u5b9e\u4f8b\u6784\u5efa\u7684\u81ea\u52a8\u5316\u65b9\u6cd5<\/h3>\n<p>\u5f53\u901a\u8fc7\u6307\u5b9aweb\u3001app\u548cdbs\u7684\u89d2\u8272\u65f6\uff0c\u4f1a\u6784\u5efa\u76f8\u5e94\u7684\u865a\u62df\u673a\u5b9e\u4f8b\u3002\u4e0b\u9762\u662f\u6267\u884c\u8ba1\u5212\u3002<\/p>\n<p>\u590d\u5236Playbook\u5230\u672c\u5730\uff0c\u58f0\u660e\u4e0d\u4f7f\u7528\u672c\u5730\u8fde\u63a5\u8fdb\u884cssh\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[ansible@step-server ~]$ cd\r\n\r\n(venv)[ansible@step-server ~]$ cp chapter11\/playbooks\/book1\/create_sample_vm.yml .\r\n\r\n(venv)[ansible@step-server ~]$ echo \"localhost ansible_connection=local\" &gt; ansible_hosts\r\n<\/code><\/pre>\n<p>\u4ee5&#8221;target=web&#8221;\u4f5c\u4e3a\u6761\u4ef6\u6267\u884c\u64ad\u653e\u5217\u8868\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[ansible@step-server ~]$ ansible-playbook -i ansible_hosts -e target=web create_sample_vm.yml\r\n\r\nPLAY [localhost] **************************************************************\r\n\r\nGATHERING FACTS ***************************************************************\r\nok: [localhost]\r\n\r\nTASK: [ansible_python_interpreter setup] **************************************\r\nok: [localhost]\r\n\r\nTASK: [get uuid for generate hostname] ****************************************\r\nchanged: [localhost]\r\n\r\nTASK: [create {{ target }}-server on nova-compute with floating_ip] ***********\r\nchanged: [localhost]\r\n\r\nTASK: [create {{ target }}-server on nova-compute without floating_ip] ********\r\nskipping: [localhost]\r\n\r\nPLAY RECAP ********************************************************************\r\nlocalhost                  : ok=4    changed=2    unreachable=0    failed=0\r\n\r\n<\/code><\/pre>\n<p>\u670d\u52a1\u5668\u5df2\u521b\u5efa\u5e76\u5206\u914d\u4e86\u6d6e\u52a8IP\u3002<\/p>\n<pre class=\"post-pre\"><code>\r\n(venv)[ansible@step-server ~]$ nova list --name ^web- --field name,networks\r\n+--------------------------------------+------------------------------------------+-------------------------------------------------------------+\r\n| ID                                   | Name                                     | Networks                                                    |\r\n+--------------------------------------+------------------------------------------+-------------------------------------------------------------+\r\n| 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 |\r\n+--------------------------------------+------------------------------------------+-------------------------------------------------------------+\r\n\r\n(venv)[ansible@step-server ~]$ nova floating-ip-list\r\n+-----------------+-----------+--------------+---------+\r\n| Ip              | Server Id | Fixed Ip     | Pool    |\r\n+-----------------+-----------+--------------+---------+\r\n| 192.168.100.135 |           | 192.168.0.22 | Ext-Net |\r\n| 192.168.100.131 |           | 10.0.0.1     | Ext-Net |\r\n| 192.168.100.134 |           | 192.168.0.19 | Ext-Net |\r\n| 192.168.100.133 |           | 192.168.0.5  | Ext-Net |\r\n+-----------------+-----------+--------------+---------+\r\n<\/code><\/pre>\n<p>\u7528\u300ctarget=app\u300d\u8fdb\u884c\u521b\u5efa\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[ansible@step-server ~]$ ansible-playbook -i ansible_hosts -e target=app create_sample_vm.yml\r\n\r\nPLAY [localhost] **************************************************************\r\n\r\nGATHERING FACTS ***************************************************************\r\nok: [localhost]\r\n\r\nTASK: [ansible_python_interpreter setup] **************************************\r\nok: [localhost]\r\n\r\nTASK: [get uuid for generate hostname] ****************************************\r\nchanged: [localhost]\r\n\r\nTASK: [create {{ target }}-server on nova-compute with floating_ip] ***********\r\nskipping: [localhost]\r\n\r\nTASK: [create {{ target }}-server on nova-compute without floating_ip] ********\r\nchanged: [localhost]\r\n\r\nPLAY RECAP ********************************************************************\r\nlocalhost                  : ok=4    changed=2    unreachable=0    failed=0\r\n<\/code><\/pre>\n<p>\u5df2\u7ecf\u521b\u5efa\u3002<\/p>\n<pre class=\"post-pre\"><code>\r\n(venv)[ansible@step-server ~]$ nova list --name ^app- --field name,networks\r\n+--------------------------------------+------------------------------------------+-----------------------------------------------------------------+\r\n| ID                                   | Name                                     | Networks                                                        |\r\n+--------------------------------------+------------------------------------------+-----------------------------------------------------------------+\r\n| 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 |\r\n+--------------------------------------+------------------------------------------+-----------------------------------------------------------------+\r\n<\/code><\/pre>\n<p>\u5728\u300ctarget=dbs\u300d\u4e0a\u521b\u5efa\u3002<\/p>\n<pre class=\"post-pre\"><code>\r\n(venv)[ansible@step-server ~]$ ansible-playbook -i ansible_hosts -e target=dbs create_sample_vm.yml\r\n\r\nPLAY [localhost] **************************************************************\r\n\r\nGATHERING FACTS ***************************************************************\r\nok: [localhost]\r\n\r\nTASK: [ansible_python_interpreter setup] **************************************\r\nok: [localhost]\r\n\r\nTASK: [get uuid for generate hostname] ****************************************\r\nchanged: [localhost]\r\n\r\nTASK: [create {{ target }}-server on nova-compute with floating_ip] ***********\r\nskipping: [localhost]\r\n\r\nTASK: [create {{ target }}-server on nova-compute without floating_ip] ********\r\nchanged: [localhost]\r\n\r\nPLAY RECAP ********************************************************************\r\nlocalhost                  : ok=4    changed=2    unreachable=0    failed=0\r\n\r\n(venv)[ansible@step-server ~]$ nova list --name ^dbs- --field name,networks\r\n+--------------------------------------+------------------------------------------+-------------------------------------------+\r\n| ID                                   | Name                                     | Networks                                  |\r\n+--------------------------------------+------------------------------------------+-------------------------------------------+\r\n| 359d02ea-098e-4e03-966e-81bbc40da2c0 | dbs-968a948e-7e58-4089-a6c6-6b2a38bb71e6 | dmz-net=192.168.0.24; dbs-net=172.16.20.9 |\r\n+--------------------------------------+------------------------------------------+-------------------------------------------+\r\n<\/code><\/pre>\n<h3>11.5.3 \u5e94\u7528\u7a0b\u5e8f\u90e8\u7f72\u7684\u81ea\u52a8\u5316<\/h3>\n<p>\u5728\u8fd9\u91cc\u8fdb\u884c\u7684\u662f\u4ee5\u4e0b\u56db\u70b9\u3002<\/p>\n<ol>\n<li style=\"list-style-type: none;\">\n<ol>\u65f6\u533a\u7684\u66f4\u6539<\/ol>\n<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<ol>\n<li style=\"list-style-type: none;\">\n<ol>\u4ecegithub\u4e2d\u62c9\u53d6\u5e94\u7528\u7a0b\u5e8f\u68c0\u67e5<\/ol>\n<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<ol>\n<li style=\"list-style-type: none;\">\n<ol>\u6267\u884c\u5b89\u88c5\u811a\u672c<\/ol>\n<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<ol>\n<li style=\"list-style-type: none;\">\n<ol>\u901a\u8fc7\u7f16\u8f91endpoint.conf\u6765\u66f4\u6539\u5e76\u4f20\u8f93\u670d\u52a1\u5668\u4e4b\u95f4\u7684\u534f\u4f5c<\/ol>\n<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<ol>\u542f\u52a8\u670d\u52a1<\/ol>\n<p>\u8fd9\u662f\u6e38\u620f\u7b56\u7565\u3002<\/p>\n<p>\u9996\u5148\uff0c\u5728ansible_hosts\u6587\u4ef6\u4e2d\u8bb0\u5f55\u76ee\u6807\u4e3b\u673a\u7684dmz-net IP\u5730\u5740\u3002\u8fd9\u662f\u7528\u4e8e\u64cd\u4f5c\u7684\u3002\u53e6\u5916\uff0c\u4e3a\u4e86\u4fee\u6539endpoint.conf\u6587\u4ef6\uff0c\u9700\u8981\u8bb0\u5f55web\u4e0a\u8981\u8bbe\u7f6e\u7684\u5e94\u7528\u7a0b\u5e8f\u7684app-net IP\u5730\u5740\uff0c\u4ee5\u53ca\u8981\u8bbe\u7f6e\u4e3aapp\u7684\u6570\u636e\u5e93\u7684dbs-net IP\u5730\u5740\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[ansible@step-server ~]$ cat ansible_hosts\r\n[localhost]\r\nlocalhost ansible_connection=local\r\n\r\n[web]\r\n192.168.0.22\r\n\r\n[app]\r\n192.168.0.23\r\n\r\n[dbs]\r\n192.168.0.24\r\n\r\n[web:vars]\r\napp = 172.16.10.16\r\n\r\n[app:vars]\r\ndbs = 172.16.20.9\r\n<\/code><\/pre>\n<p>\u628aPlaybook\u548cendpoint.conf\u7684\u6a21\u677f\u590d\u5236\u5230\u4e3b\u9875\u4e0a\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[ansible@step-server ~]$ cd\r\n\r\n(venv)[ansible@step-server ~]$ cp chapter11\/playbooks\/book1\/install_sample_app.yml .\r\n\r\n(venv)[ansible@step-server ~]$ cp chapter11\/playbooks\/book1\/endpoint.conf.j2 .\r\n<\/code><\/pre>\n<p>\u7531\u4e8e\u5b58\u5728\u4f9d\u8d56\u5173\u7cfb\uff0c\u9700\u8981\u6309\u7167\u4ee5\u4e0b\u987a\u5e8f\u8fdb\u884c\u5b89\u88c5\uff1a\u9996\u5148\u5b89\u88c5dbs\uff0c\u7136\u540e\u662fapp\uff0c\u6700\u540e\u662fweb\u3002<\/p>\n<p>\u6267\u884c\u300ctarget=dbs\u300d\u3002\u6211\u6307\u5b9a\u4e86\u767b\u5f55\uff0c\u5e76\u4e14\u8fd8\u6307\u5b9a\u4e86\u201c-u root\u201d\u3002\u5f53\u4eceGitHub\u83b7\u53d6\u5e94\u7528\u7a0b\u5e8f\u65f6\u51fa\u73b0\u4e86\u201c403 Forbidden\u201d\u7684\u9519\u8bef\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[ansible@step-server ~]$ ansible-playbook -i ansible_hosts -e target=dbs -u root install_sample_app.yml\r\n\r\nPLAY [dbs] ********************************************************************\r\n\r\nGATHERING FACTS ***************************************************************\r\nThe authenticity of host '192.168.0.24 (192.168.0.24)' can't be established.\r\nRSA key fingerprint is 9d:7e:70:8f:da:c2:b0:1f:9c:57:39:c1:a1:01:9a:a3.\r\nAre you sure you want to continue connecting (yes\/no)? yes\r\nok: [192.168.0.24]\r\n\r\nTASK: [change the timezone] ***************************************************\r\nchanged: [192.168.0.24]\r\n\r\nTASK: [checkout app from github] **********************************************\r\nfailed: [192.168.0.24] =&gt; {\"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}\r\nstderr: error: The requested URL returned error: 403 Forbidden while accessing https:\/\/github.com\/josug-book1-materials\/sample-app.git\/info\/refs\r\n\r\nfatal: HTTP request failed\r\n\r\nstdout: Initialized empty Git repository in \/root\/sample-app\/.git\/\r\n\r\nmsg: error: The requested URL returned error: 403 Forbidden while accessing https:\/\/github.com\/josug-book1-materials\/sample-app.git\/info\/refs\r\n\r\nfatal: HTTP request failed\r\n\r\nFATAL: all hosts have already failed -- aborting\r\n\r\nPLAY RECAP ********************************************************************\r\n           to retry, use: --limit @\/home\/ansible\/install_sample_app.retry\r\n\r\n192.168.0.24               : ok=2    changed=1    unreachable=0    failed=1\r\n<\/code><\/pre>\n<p>\u6211\u5148\u91cd\u65b0\u6267\u884c\u4e00\u6b21\u3002\u8fd9\u4e00\u6b21\u6210\u529f\u4e86\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[ansible@step-server ~]$ ansible-playbook -i ansible_hosts -e target=dbs -u root install_sample_app.yml\r\n\r\nPLAY [dbs] ********************************************************************\r\n\r\nGATHERING FACTS ***************************************************************\r\nok: [192.168.0.24]\r\n\r\nTASK: [change the timezone] ***************************************************\r\nchanged: [192.168.0.24]\r\n\r\nTASK: [checkout app from github] **********************************************\r\nchanged: [192.168.0.24]\r\n\r\nTASK: [execute install script] ************************************************\r\nok: [192.168.0.24]\r\n\r\nTASK: [copy endpoint.conf to web and app server] ******************************\r\nskipping: [192.168.0.24]\r\n\r\nPLAY RECAP ********************************************************************\r\n192.168.0.24               : ok=4    changed=2    unreachable=0    failed=0\r\n<\/code><\/pre>\n<p>\u5728&#8221;target=app&#8221;\u4e0a\u8fd0\u884c\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[ansible@step-server ~]$ ansible-playbook -i ansible_hosts -e target=app -u root install_sample_app.yml\r\n\r\nPLAY [app] ********************************************************************\r\n\r\nGATHERING FACTS ***************************************************************\r\nThe authenticity of host '192.168.0.23 (192.168.0.23)' can't be established.\r\nRSA key fingerprint is 4d:8e:f4:7d:06:ca:85:c4:b7:23:27:30:67:3a:8b:13.\r\nAre you sure you want to continue connecting (yes\/no)? yes\r\nok: [192.168.0.23]\r\n\r\nTASK: [change the timezone] ***************************************************\r\nchanged: [192.168.0.23]\r\n\r\nTASK: [checkout app from github] **********************************************\r\nchanged: [192.168.0.23]\r\n\r\nTASK: [execute install script] ************************************************\r\nok: [192.168.0.23]\r\n\r\nTASK: [copy endpoint.conf to web and app server] ******************************\r\nchanged: [192.168.0.23]\r\n\r\nNOTIFIED: [startup service] ***************************************************\r\nchanged: [192.168.0.23]\r\n\r\nPLAY RECAP ********************************************************************\r\n192.168.0.23               : ok=6    changed=4    unreachable=0    failed=0\r\n<\/code><\/pre>\n<p>\u4ee5\u300ctarget=app\u300d\u4f5c\u4e3a\u53c2\u6570\u8fd0\u884c\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[ansible@step-server ~]$ ansible-playbook -i ansible_hosts -e target=web -u root install_sample_app.yml\r\n\r\nPLAY [web] ********************************************************************\r\n\r\nGATHERING FACTS ***************************************************************\r\nThe authenticity of host '192.168.0.22 (192.168.0.22)' can't be established.\r\nRSA key fingerprint is 28:30:e0:72:bc:7e:d8:61:da:1d:cb:67:02:19:8b:5e.\r\nAre you sure you want to continue connecting (yes\/no)? yes\r\nok: [192.168.0.22]\r\n\r\nTASK: [change the timezone] ***************************************************\r\nchanged: [192.168.0.22]\r\n\r\nTASK: [checkout app from github] **********************************************\r\nchanged: [192.168.0.22]\r\n\r\nTASK: [execute install script] ************************************************\r\nok: [192.168.0.22]\r\n\r\nTASK: [copy endpoint.conf to web and app server] ******************************\r\nchanged: [192.168.0.22]\r\n\r\nNOTIFIED: [startup service] ***************************************************\r\nchanged: [192.168.0.22]\r\n\r\nPLAY RECAP ********************************************************************\r\n192.168.0.22               : ok=6    changed=4    unreachable=0    failed=0\r\n<\/code><\/pre>\n<h3>11.5.4 \u5728\u52a8\u6001\u5e93\u5b58\u4e2d\u5e94\u5bf9\u4e3b\u673a\u7684\u589e\u51cf\u60c5\u51b5<\/h3>\n<p>\u5728&#8221;11.5.3\u5e94\u7528\u90e8\u7f72\u81ea\u52a8\u5316&#8221;\u4e2d\uff0c\u6211\u4eec\u5c06\u76ee\u6807IP\u5730\u5740\u8bb0\u5f55\u5728ansible_hosts\u4e2d\u3002\u7136\u800c\uff0c\u5728OpenStack\u4e2d\uff0c\u76f4\u5230\u90e8\u7f72\u4e4b\u524d\uff0c\u5730\u5740\u57fa\u672c\u4e0a\u662f\u672a\u77e5\u7684\u3002<br \/>\n\u6211\u4eec\u53ef\u4ee5\u8c03\u7528\u8fd4\u56de\u6e05\u5355\u4fe1\u606f\u7684\u5916\u90e8\u7a0b\u5e8f\uff0c\u5e76\u5c06\u5176\u4f5c\u4e3aansible\u7684\u76ee\u6807\u3002<\/p>\n<p>\u5916\u90e8\u7a0b\u5e8f\u7684\u6761\u4ef6\u5982\u4e0b\u6240\u793a\uff0c\u5e76\u5728\u672c\u4e66\u4e2d\u6709\u6240\u63d0\u53ca\u3002<\/p>\n<ol>\n<li style=\"list-style-type: none;\">\n<ol>\u5982\u679c\u4ee5-list\u4f5c\u4e3a\u53c2\u6570\uff0c\u5219\u8fd4\u56deJSON\u683c\u5f0f\u7684\u4e3b\u673a\u5217\u8868\u3002<\/ol>\n<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<ol>\u5982\u679c\u7528-host\u4f5c\u4e3a\u53c2\u6570\uff0c\u5219\u8fd4\u56deJSON\u683c\u5f0f\u7684\u4e3b\u673a\u53c2\u6570\u3002<\/ol>\n<p>\u9a8c\u8bc1\u662f\u5426\u53ef\u4ee5\u901a\u8fc7\u4e00\u4e2a\u7b80\u5355\u7684shell\u811a\u672c\u8fd4\u56de\u4e3b\u673a\u5217\u8868\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[ansible@step-server ~]$ cat inventry.sh\r\n#!\/bin\/sh\r\n\r\nusage() {\r\n        echo \"Usage: invenrty.sh --list|--host hostname\"\r\n        exit 1\r\n}\r\n\r\ncase $1 in\r\n        \"--list\")\r\n                echo '{\"sns\":{\"hosts\":[\"192.168.0.22\",\"192.168.0.23\",\"192.168.0.24\"]}}'\r\n                ;;\r\n        \"--host\")\r\n                if [ \"x\"$2 == \"x\" ] || [ $# -ne 2 ]; then\r\n                        usage\r\n                fi\r\n                echo \"{}\"\r\n                ;;\r\n        *)\r\n                usage\r\n                ;;\r\nesac\r\n<\/code><\/pre>\n<p>\u5f53\u4f7f\u7528ping\u6a21\u5757\u8fdb\u884c\u786e\u8ba4\u65f6\uff0c\u5373\u4f7f\u662f\u8fd9\u6837\u7684shell\u4e5f\u80fd\u6b63\u5e38\u5de5\u4f5c\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[ansible@step-server ~]$ ansible sns -i inventry.sh -m ping -u root\r\n192.168.0.22 | success &gt;&gt; {\r\n    \"changed\": false,\r\n    \"ping\": \"pong\"\r\n}\r\n\r\n192.168.0.24 | success &gt;&gt; {\r\n    \"changed\": false,\r\n    \"ping\": \"pong\"\r\n}\r\n\r\n192.168.0.23 | success &gt;&gt; {\r\n    \"changed\": false,\r\n    \"ping\": \"pong\"\r\n}\r\n<\/code><\/pre>\n<p>\u5c06\u63d0\u4f9b\u7684sample_app_inventory.py\u548csample_app_inventory.ini\u6587\u4ef6\u590d\u5236\u5230\u4e3b\u76ee\u5f55\u4e2d\u3002\u7ed9sample_app_inventory.py\u6587\u4ef6\u6dfb\u52a0\u6267\u884c\u6743\u9650\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[ansible@step-server ~]$ cd\r\n\r\n(venv)[ansible@step-server ~]$ cp chapter11\/playbooks\/sample_app_inventory.py .\r\n\r\n(venv)[ansible@step-server ~]$ cp chapter11\/playbooks\/sample_app_inventory.ini .\r\n\r\n(venv)[ansible@step-server ~]$ chmod u+x sample_app_inventory.py\r\n\r\n<\/code><\/pre>\n<p>\u8fd9\u4e2aini\u6587\u4ef6\u662f\u8fd9\u6837\u7684\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[ansible@step-server ~]$ cat sample_app_inventory.ini\r\n[DEFAULT]\r\n\r\n\r\n[stack]\r\napi_version    = 1.1\r\nos_username    = %OS_USERNAME%\r\nos_password    = %OS_PASSWORD%\r\nos_auth_url    = %AUTH_URL%\r\nos_region_name = %REGION_NAME%\r\nos_tenant_name = %TENANT_NAME%\r\n\r\n[sample_app]\r\nweb_hostname_prefix = web-\r\napp_hostname_prefix = app-\r\ndbs_hostname_prefix = dbs-\r\n\r\n\r\n##\r\n## [EOF]\r\n##\r\n<\/code><\/pre>\n<p>\u6839\u636e\u8fd9\u6b21\u7684\u73af\u5883\u505a\u76f8\u5e94\u7684\u4fee\u6539\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[ansible@step-server ~]$ cat sample_app_inventory.ini\r\n[DEFAULT]\r\n\r\n\r\n[stack]\r\napi_version    = 1.1\r\nos_username    = snsapp-infra-user\r\nos_password    = passw0rd\r\nos_auth_url    = http:\/\/192.168.100.10:5000\/v2.0\/\r\nos_region_name = RegionOne\r\nos_tenant_name = SNSApp\r\n\r\n[sample_app]\r\nweb_hostname_prefix = web-\r\napp_hostname_prefix = app-\r\ndbs_hostname_prefix = dbs-\r\n\r\n\r\n##\r\n## [EOF]\r\n##\r\n<\/code><\/pre>\n<p>\u6267\u884c<\/p>\n<pre class=\"post-pre\"><code>(venv)[ansible@step-server ~]$ .\/sample_app_inventory.py --list\r\n{\r\n  \"_meta\": {\r\n    \"hostvars\": {\r\n      \"192.168.0.22\": {\r\n        \"app\": \"172.16.10.16\"\r\n      },\r\n      \"192.168.0.23\": {\r\n        \"dbs\": \"172.16.20.9\"\r\n      },\r\n      \"192.168.0.24\": {}\r\n    }\r\n  },\r\n  \"app\": {\r\n    \"hosts\": [\r\n      \"192.168.0.23\"\r\n    ],\r\n    \"vars\": {\r\n      \"dbs\": \"172.16.20.9\"\r\n    }\r\n  },\r\n  \"dbs\": {\r\n    \"hosts\": [\r\n      \"192.168.0.24\"\r\n    ],\r\n    \"vars\": {}\r\n  },\r\n  \"localhost\": {\r\n    \"hosts\": [\r\n      \"localhost\"\r\n    ],\r\n    \"vars\": {\r\n      \"ansible_connection\": \"local\"\r\n    }\r\n  },\r\n  \"web\": {\r\n    \"hosts\": [\r\n      \"192.168.0.22\"\r\n    ],\r\n    \"vars\": {\r\n      \"app\": \"172.16.10.16\"\r\n    }\r\n  }\r\n}\r\n<\/code><\/pre>\n<p>\u6682\u65f6\u5220\u9664\u6b64\u7ae0\u521b\u5efa\u7684\u670d\u52a1\u5668\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[ansible@step-server ~]$ nova delete app-18e1b380-a213-4518-a3ae-30ccad545014\r\n(venv)[ansible@step-server ~]$ nova delete dbs-968a948e-7e58-4089-a6c6-6b2a38bb71e6\r\n(venv)[ansible@step-server ~]$ nova delete web-520710f9-08d3-41cd-9d28-aa6cc4bfca66\r\n<\/code><\/pre>\n<p>\u542f\u52a8\u65b0\u670d\u52a1\u5668\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[ansible@step-server ~]$ echo \"localhost ansible_connection=local\" &gt; ansible_hosts\r\n(venv)[ansible@step-server ~]$ ansible-playbook -i ansible_hosts -e target=web create_sample_vm.yml\r\n(venv)[ansible@step-server ~]$ ansible-playbook -i ansible_hosts -e target=app create_sample_vm.yml\r\n(venv)[ansible@step-server ~]$ ansible-playbook -i ansible_hosts -e target=dbs create_sample_vm.yml\r\n<\/code><\/pre>\n<p>\u5c06\u5176\u5f15\u5165\u5230DBS\u3002\u76ee\u6807IP\u4e3a[192.168.0.27]\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[ansible@step-server ~]$ ansible-playbook -i sample_app_inventory.py -e target=dbs install_sample_app.yml\r\n\r\nPLAY [dbs] ********************************************************************\r\n\r\nGATHERING FACTS ***************************************************************\r\nThe authenticity of host '192.168.0.27 (192.168.0.27)' can't be established.\r\nRSA key fingerprint is a8:6a:42:e4:e2:19:2f:19:67:99:44:2e:8e:72:8b:40.\r\nAre you sure you want to continue connecting (yes\/no)? yes\r\nok: [192.168.0.27]\r\n\r\nTASK: [change the timezone] ***************************************************\r\nchanged: [192.168.0.27]\r\n\r\nTASK: [checkout app from github] **********************************************\r\nchanged: [192.168.0.27]\r\n\r\nTASK: [execute install script] ************************************************\r\nok: [192.168.0.27]\r\n\r\nTASK: [copy endpoint.conf to web and app server] ******************************\r\nskipping: [192.168.0.27]\r\n\r\nPLAY RECAP ********************************************************************\r\n192.168.0.27               : ok=4    changed=2    unreachable=0    failed=0\r\n<\/code><\/pre>\n<p>\u5c06\u8be5\u5e94\u7528\u7a0b\u5e8f\u5b89\u88c5\u5230\u6307\u5b9a\u7684IP\u5730\u5740[192.168.0.26]\u4e0a\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[ansible@step-server ~]$ ansible-playbook -i sample_app_inventory.py -e target=app install_sample_app.yml\r\n\r\nPLAY [app] ********************************************************************\r\n\r\nGATHERING FACTS ***************************************************************\r\nThe authenticity of host '192.168.0.26 (192.168.0.26)' can't be established.\r\nRSA key fingerprint is 82:84:ad:c8:3e:fe:fd:a9:b0:43:cd:fc:9d:d0:43:b6.\r\nAre you sure you want to continue connecting (yes\/no)? yes\r\nok: [192.168.0.26]\r\n\r\nTASK: [change the timezone] ***************************************************\r\nchanged: [192.168.0.26]\r\n\r\nTASK: [checkout app from github] **********************************************\r\nchanged: [192.168.0.26]\r\n\r\nTASK: [execute install script] ************************************************\r\nok: [192.168.0.26]\r\n\r\nTASK: [copy endpoint.conf to web and app server] ******************************\r\nchanged: [192.168.0.26]\r\n\r\nNOTIFIED: [startup service] ***************************************************\r\nchanged: [192.168.0.26]\r\n\r\nPLAY RECAP ********************************************************************\r\n192.168.0.26               : ok=6    changed=4    unreachable=0    failed=0\r\n<\/code><\/pre>\n<p>\u5b89\u88c5\u5230\u7f51\u7edc\u3002\u76ee\u6807IP\u5730\u5740\u4e3a[192.168.0.25]\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[ansible@step-server ~]$ ansible-playbook -i sample_app_inventory.py -e target=web install_sample_app.yml\r\n\r\nPLAY [web] ********************************************************************\r\n\r\nGATHERING FACTS ***************************************************************\r\nThe authenticity of host '192.168.0.25 (192.168.0.25)' can't be established.\r\nRSA key fingerprint is b4:3c:b3:1c:bd:58:5f:4e:8c:72:6d:05:82:2e:a3:01.\r\nAre you sure you want to continue connecting (yes\/no)? yes\r\nok: [192.168.0.25]\r\n\r\nTASK: [change the timezone] ***************************************************\r\nchanged: [192.168.0.25]\r\n\r\nTASK: [checkout app from github] **********************************************\r\nchanged: [192.168.0.25]\r\n\r\nTASK: [execute install script] ************************************************\r\nok: [192.168.0.25]\r\n\r\nTASK: [copy endpoint.conf to web and app server] ******************************\r\nchanged: [192.168.0.25]\r\n\r\nNOTIFIED: [startup service] ***************************************************\r\nchanged: [192.168.0.25]\r\n\r\nPLAY RECAP ********************************************************************\r\n192.168.0.25               : ok=6    changed=4    unreachable=0    failed=0\r\n<\/code><\/pre>\n<h3>11.5.5 \u81ea\u52a8\u5316\u6570\u636e\u5e93\u5907\u4efd\/\u6062\u590d<\/h3>\n<p>\u5728dbs\u4e0a\u83b7\u53d6\u5feb\u7167\uff0c\u901a\u8fc7app\u91cd\u65b0\u542f\u52a8\u670d\u52a1\uff0c\u5e76\u81ea\u52a8\u5316\u5907\u4efd\u5feb\u7167\u3002<\/p>\n<p>\u4ee5\u4e0b\u662f\u4e09\u4e2a\u6b65\u9aa4\u7684\u6e38\u620f\u624b\u518c\u3002<\/p>\n<p>\u521b\u5efa\u5feb\u7167.yml\u3001\u91cd\u542fRest\u670d\u52a1.yml\u3001\u5907\u4efd\u5feb\u7167.yml<\/p>\n<p>\u8fd9\u662f\u4e00\u4efd\u4e00\u53e3\u6c14\u5b8c\u6210\u7684\u64ad\u653e\u4e66\u3002<\/p>\n<p>\u6570\u636e\u5e93\u5907\u4efd.yml<\/p>\n<p>\u5c06\u8fd9\u4e9b\u5267\u672c\u590d\u5236\u5230\u5bb6\u91cc\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[ansible@step-server ~]$ cp chapter11\/playbooks\/book2\/create_snapshot.yml .\r\n(venv)[ansible@step-server ~]$ cp chapter11\/playbooks\/book2\/restart_rest_service.yml .\r\n(venv)[ansible@step-server ~]$ cp chapter11\/playbooks\/book2\/backup_snapshot.yml .\r\n(venv)[ansible@step-server ~]$ cp chapter11\/playbooks\/book2\/db_backup.yml .\r\n<\/code><\/pre>\n<p>\u6267\u884cdb_backup.yml\u7684\u8fc7\u7a0b\u4e2d\u53d1\u751f\u4e86\u9519\u8bef\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[ansible@step-server ~]$ ansible-playbook -i sample_app_inventory.py -t snapshot,backup -u root db_backup.yml\r\n\r\nPLAY [dbs] ********************************************************************\r\n\r\nGATHERING FACTS ***************************************************************\r\nok: [192.168.0.27]\r\n\r\nTASK: [stop mysqld] ***********************************************************\r\nok: [192.168.0.27]\r\n\r\nTASK: [umount mysql_dir] ******************************************************\r\nok: [192.168.0.27]\r\n\r\nTASK: [create snapshot on lvm] ************************************************\r\nfailed: [192.168.0.27] =&gt; {\"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\": []}\r\nstderr:   Volume group \"mysql_vg\" not found\r\n\r\nFATAL: all hosts have already failed -- aborting\r\n\r\nPLAY RECAP ********************************************************************\r\n           to retry, use: --limit @\/home\/ansible\/db_backup.retry\r\n\r\n192.168.0.27               : ok=3    changed=0    unreachable=0    failed=1\r\n\r\n<\/code><\/pre>\n<p>\u6211\u6b63\u5728\u5c1d\u8bd5\u521b\u5efaLVM\u5feb\u7167\u3002<\/p>\n<pre class=\"post-pre\"><code>\uff5e\uff5e\uff5e\uff5e\uff5e\uff5e\r\nmysql_dir: \/var\/lib\/mysql\r\nmysql_vol: \/dev\/mysql_vg\/mysql_vol01\r\nmysql_snap: mysql_bk_snap01\r\nmysql_snap_size: 100m\r\n\uff5e\uff5e\uff5e\uff5e\uff5e\uff5e\r\ncommand: lvcreate -s \"{{ mysql_vol }}\" -L \"{{ mysql_snap_size }}\" -n \"{{ mysql_snap }}\"\r\n<\/code><\/pre>\n<p>\u5728DBS\u4e2d\u6ca1\u6709LV&#8230;<\/p>\n<pre class=\"post-pre\"><code>[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf \/]# lvdisplay\r\n  No volume groups found\r\n<\/code><\/pre>\n<p>\u63a5\u4e0b\u6765\u7684\u786c\u76d8\u8fde\u63a5\u4e86vda\u548cvdb\u3002<\/p>\n<pre class=\"post-pre\"><code>[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf \/]# lsblk\r\nNAME                            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT\r\nsr0                              11:0    1  410K  0 rom\r\nvda                             252:0    0   10G  0 disk\r\n\u2514\u2500vda1                          252:1    0   10G  0 part \/\r\nvdb                             252:16   0   10G  0 disk \/mnt\r\n<\/code><\/pre>\n<p>\u7531\u4e8e\u5728backup_snapshot.yml\u4e2d\u8fde\u63a5\u4e86\/dev\/vdd1\uff0c\u6240\u4ee5\u53ef\u4ee5\u63a8\u6d4bvdc\u548cvdd\u5df2\u8fde\u63a5\u3002<br \/>\n\u6839\u636e\u5728SoftLayer\u514d\u8d39\u88f8\u91d1\u5c5e\u4e0a\u5b66\u4e60OpenStack\uff0810\uff09-\u7b2c9\u7ae0\u201c\u5229\u7528\u5757\u5377\u8fdb\u884c\u6570\u636e\u4fdd\u62a4\u201d\uff08\u4f7f\u7528Cinder\uff09\u7684\u6b65\u9aa4\uff0c\u6211\u4eec\u9700\u8981\u6dfb\u52a0\u4e24\u4e2a\u5377\u3002<br \/>\n\u6211\u4eec\u5c06\u5728vdc\u4e0a\u521b\u5efaLVM\u5e76\u5c06\u5176\u4f5c\u4e3amysql\u7684\u6570\u636e\u533a\u57df\u3002<br \/>\n\u6211\u4eec\u5c06vdd\u4f5c\u4e3a\u5e38\u89c4\u7684ext4\u5206\u533a\u7528\u4f5c\u5907\u4efd\u533a\u57df\u3002<\/p>\n<p>\u7528Cinder\u521b\u5efa\u4e24\u4e2a\u5377\u3002<\/p>\n<pre class=\"post-pre\"><code>\r\n(venv)[ansible@step-server ~]$ cinder create --display-name dbs_vdc --availability-zone az1 10\r\n+---------------------+--------------------------------------+\r\n|       Property      |                Value                 |\r\n+---------------------+--------------------------------------+\r\n|     attachments     |                  []                  |\r\n|  availability_zone  |                 az1                  |\r\n|       bootable      |                false                 |\r\n|      created_at     |      2015-03-30T11:43:00.654349      |\r\n| display_description |                 None                 |\r\n|     display_name    |               dbs_vdc                |\r\n|      encrypted      |                False                 |\r\n|          id         | 5293f5c7-d386-4b36-9092-252f724eeafd |\r\n|       metadata      |                  {}                  |\r\n|         size        |                  10                  |\r\n|     snapshot_id     |                 None                 |\r\n|     source_volid    |                 None                 |\r\n|        status       |               creating               |\r\n|     volume_type     |                 None                 |\r\n+---------------------+--------------------------------------+\r\n\r\n(venv)[ansible@step-server ~]$ cinder create --display-name dbs_vdd --availability-zone az1 10\r\n+---------------------+--------------------------------------+\r\n|       Property      |                Value                 |\r\n+---------------------+--------------------------------------+\r\n|     attachments     |                  []                  |\r\n|  availability_zone  |                 az1                  |\r\n|       bootable      |                false                 |\r\n|      created_at     |      2015-03-30T11:43:13.524431      |\r\n| display_description |                 None                 |\r\n|     display_name    |               dbs_vdd                |\r\n|      encrypted      |                False                 |\r\n|          id         | e7f73a03-e9a3-4f27-9a33-a40c869d13cb |\r\n|       metadata      |                  {}                  |\r\n|         size        |                  10                  |\r\n|     snapshot_id     |                 None                 |\r\n|     source_volid    |                 None                 |\r\n|        status       |               creating               |\r\n|     volume_type     |                 None                 |\r\n+---------------------+--------------------------------------+\r\n<\/code><\/pre>\n<p>\u8fde\u63a5\u5230DBS\u3002<\/p>\n<pre class=\"post-pre\"><code>\r\n(venv)[ansible@step-server ~]$ function get_uuid () { cat - | grep \" id \" | awk '{print $4}'; }\r\n\r\n(venv)[ansible@step-server ~]$ export MY_DBS_VDC=`cinder show dbs_vdc |get_uuid`\r\n\r\n(venv)[ansible@step-server ~]$ export MY_DBS_VDD=`cinder show dbs_vdd |get_uuid`\r\n\r\n(venv)[ansible@step-server ~]$ nova volume-attach dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf $MY_DBS_VDC\r\n+----------+--------------------------------------+\r\n| Property | Value                                |\r\n+----------+--------------------------------------+\r\n| device   | \/dev\/vdc                             |\r\n| id       | 5293f5c7-d386-4b36-9092-252f724eeafd |\r\n| serverId | e4908bd6-c862-4993-964c-44c7bf6c4ddf |\r\n| volumeId | 5293f5c7-d386-4b36-9092-252f724eeafd |\r\n+----------+--------------------------------------+\r\n\r\n(venv)[ansible@step-server ~]$ nova volume-attach dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf $MY_DBS_VDD\r\n+----------+--------------------------------------+\r\n| Property | Value                                |\r\n+----------+--------------------------------------+\r\n| device   | \/dev\/vdd                             |\r\n| id       | e7f73a03-e9a3-4f27-9a33-a40c869d13cb |\r\n| serverId | e4908bd6-c862-4993-964c-44c7bf6c4ddf |\r\n| volumeId | e7f73a03-e9a3-4f27-9a33-a40c869d13cb |\r\n+----------+--------------------------------------+\r\n<\/code><\/pre>\n<p>\u8fde\u63a5\u6210\u529f\u3002<\/p>\n<pre class=\"post-pre\"><code>[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf \/]# lsblk\r\nNAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT\r\nsr0     11:0    1  410K  0 rom\r\nvda    252:0    0   10G  0 disk\r\n\u2514\u2500vda1 252:1    0   10G  0 part \/\r\nvdb    252:16   0   10G  0 disk \/mnt\r\nvdc    252:32   0   10G  0 disk\r\nvdd    252:48   0   10G  0 disk\r\n<\/code><\/pre>\n<p>\u8ba1\u5212\u521b\u5efa\u540d\u4e3a\u300c\/dev\/mysql_vg\/mysql_vol01\u300d\u7684LVM\u5feb\u7167\u3002<\/p>\n<p>\u5c06\/dev\/vdc\u7684\u7c7b\u578b\u66f4\u6539\u4e3a8e\uff08Linux LVM\uff09\u3002<\/p>\n<pre class=\"post-pre\"><code>[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf \/]# fdisk \/dev\/vdc\r\nDevice contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel\r\nBuilding a new DOS disklabel with disk identifier 0xed33b73b.\r\nChanges will remain in memory only, until you decide to write them.\r\nAfter that, of course, the previous content won't be recoverable.\r\n\r\nWarning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)\r\n\r\nWARNING: DOS-compatible mode is deprecated. It's strongly recommended to\r\n         switch off the mode (command 'c') and change display units to\r\n         sectors (command 'u').\r\n\r\nCommand (m for help): n\r\nCommand action\r\n   e   extended\r\n   p   primary partition (1-4)\r\np\r\nPartition number (1-4): 1\r\nFirst cylinder (1-20805, default 1):\r\nUsing default value 1\r\nLast cylinder, +cylinders or +size{K,M,G} (1-20805, default 20805):\r\nUsing default value 20805\r\n\r\nCommand (m for help): t\r\nSelected partition 1\r\nHex code (type L to list codes): 8e\r\nChanged system type of partition 1 to 8e (Linux LVM)\r\n\r\nCommand (m for help): p\r\n\r\nDisk \/dev\/vdc: 10.7 GB, 10737418240 bytes\r\n16 heads, 63 sectors\/track, 20805 cylinders\r\nUnits = cylinders of 1008 * 512 = 516096 bytes\r\nSector size (logical\/physical): 512 bytes \/ 512 bytes\r\nI\/O size (minimum\/optimal): 512 bytes \/ 512 bytes\r\nDisk identifier: 0xed33b73b\r\n\r\n   Device Boot      Start         End      Blocks   Id  System\r\n\/dev\/vdc1               1       20805    10485688+  8e  Linux LVM\r\n\r\nCommand (m for help): w\r\nThe partition table has been altered!\r\n\r\nCalling ioctl() to re-read partition table.\r\nSyncing disks.\r\n<\/code><\/pre>\n<p>\u5728\/dev\/vdc1\u4e0a\u521b\u5efa\u4e00\u4e2a\u7269\u7406\u5377(pv)\uff0c\u5e76\u521b\u5efavg\u547d\u540d\u4e3a&#8221;mysql_vg&#8221;\uff0clv\u547d\u540d\u4e3a&#8221;mysql_vol01&#8243;\u3002<\/p>\n<pre class=\"post-pre\"><code>[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf \/]# pvcreate \/dev\/vdc1\r\n  Physical volume \"\/dev\/vdc1\" successfully created\r\n\r\n[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf \/]# vgcreate mysql_vg \/dev\/vdc1\r\n  Volume group \"mysql_vg\" successfully created\r\n\r\n[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf \/]# lvcreate -L 5G -n mysql_vol01 mysql_vg\r\n  Logical volume \"mysql_vol01\" created\r\n<\/code><\/pre>\n<p>\u521b\u5efa\u4e86\/dev\/mysql_vg\/mysql_vol01\u3002<\/p>\n<pre class=\"post-pre\"><code>[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf \/]# lsblk\r\nNAME                            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT\r\nsr0                              11:0    1  410K  0 rom\r\nvda                             252:0    0   10G  0 disk\r\n\u2514\u2500vda1                          252:1    0   10G  0 part \/\r\nvdb                             252:16   0   10G  0 disk \/mnt\r\nvdc                             252:32   0   10G  0 disk\r\n\u2514\u2500vdc1                          252:33   0   10G  0 part\r\n  \u2514\u2500mysql_vg-mysql_vol01 (dm-0) 253:0    0    5G  0 lvm\r\nvdd                             252:48   0   10G  0 disk\r\n\r\n[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf \/]# ls \/dev\/mysql_vg\/mysql_vol01\r\n\/dev\/mysql_vg\/mysql_vol01\r\n<\/code><\/pre>\n<p>\u521b\u5efa\u4e00\u4e2aext4\u6587\u4ef6\u7cfb\u7edf\uff0c\u5e76\u5c06MySQL\u6570\u636e\u8fc1\u79fb\u5230\/var\/lib\/mysql\u76ee\u5f55\u4e2d\u8fdb\u884c\u6302\u8f7d\u3002<\/p>\n<pre class=\"post-pre\"><code>[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf \/]# mkfs.ext4 -L mysql_data \/dev\/mysql_vg\/mysql_vol01\r\n\r\n[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf \/]# tune2fs -c 0 -i 0 -r 0 \/dev\/mysql_vg\/mysql_vol01\r\n\r\n[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf \/]# mkdir \/tmp\/data\r\n\r\n[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf \/]# mount LABEL=mysql_data \/tmp\/data\r\n\r\n[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf \/]# chown -R mysql:mysql \/tmp\/data\r\n\r\n[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf \/]# service mysqld stop\r\n\r\n[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf \/]# mv \/var\/lib\/mysql\/* \/tmp\/data\/\r\n\r\n\r\n[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf \/]# umount \/tmp\/data\/\r\n\r\n[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf \/]# mount LABEL=mysql_data \/var\/lib\/mysql\r\n\r\n[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf \/]# service mysqld start\r\n<\/code><\/pre>\n<p>\u5728Linux\u64cd\u4f5c\u7cfb\u7edf\u768483\u7248\u672c\u4e0a\u521b\u5efa\u4e00\u4e2aext4\u6587\u4ef6\u7cfb\u7edf\u3002<\/p>\n<pre class=\"post-pre\"><code>[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf \/]# fdisk \/dev\/vdd\r\n\r\n[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf \/]# mkfs.ext4 -L mysql_backup \/dev\/vdd1\r\n\r\n[root@dbs-e945fd19-f2ba-40a2-8470-ad1c6092eacf \/]# tune2fs -c 0 -i 0 -r 0 \/dev\/vdd1\r\n<\/code><\/pre>\n<p>\u6211\u5df2\u7ecf\u6210\u529f\u5730\u4f7f\u7528Ansible\u5b9e\u73b0\u81ea\u52a8\u5907\u4efd\u3002<\/p>\n<pre class=\"post-pre\"><code>(venv)[ansible@step-server ~]$ ansible-playbook -i sample_app_inventory.py -t snapshot,backup -u root db_backup.yml\r\n\r\nPLAY [dbs] ********************************************************************\r\n\r\nGATHERING FACTS ***************************************************************\r\nok: [192.168.0.27]\r\n\r\nTASK: [stop mysqld] ***********************************************************\r\nchanged: [192.168.0.27]\r\n\r\nTASK: [umount mysql_dir] ******************************************************\r\nchanged: [192.168.0.27]\r\n\r\nTASK: [create snapshot on lvm] ************************************************\r\nchanged: [192.168.0.27]\r\n\r\nTASK: [mount mysql_dir] *******************************************************\r\nchanged: [192.168.0.27]\r\n\r\nTASK: [start mysqld] **********************************************************\r\nchanged: [192.168.0.27]\r\n\r\nPLAY [app] ********************************************************************\r\n\r\nGATHERING FACTS ***************************************************************\r\nok: [192.168.0.26]\r\n\r\nTASK: [restart rest app] ******************************************************\r\nchanged: [192.168.0.26]\r\n\r\nPLAY [dbs] ********************************************************************\r\n\r\nGATHERING FACTS ***************************************************************\r\nok: [192.168.0.27]\r\n\r\nTASK: [make directory] ********************************************************\r\nchanged: [192.168.0.27]\r\n\r\nTASK: [mount backup] **********************************************************\r\nchanged: [192.168.0.27]\r\n\r\nTASK: [mount snapshot] ********************************************************\r\nchanged: [192.168.0.27]\r\n\r\nTASK: [archive database files to \"{{ backup_mountpoint }}\"] *******************\r\nchanged: [192.168.0.27]\r\n\r\nTASK: [umount snapshot] *******************************************************\r\nchanged: [192.168.0.27]\r\n\r\nTASK: [umount backup] *********************************************************\r\nchanged: [192.168.0.27]\r\n\r\nTASK: [remove snapshot] *******************************************************\r\nchanged: [192.168.0.27]\r\n\r\nPLAY RECAP ********************************************************************\r\n192.168.0.26               : ok=2    changed=1    unreachable=0    failed=0\r\n192.168.0.27               : ok=14   changed=12   unreachable=0    failed=0\r\n<\/code><\/pre>\n<hr \/>\n<p>\u7b2c11\u7ae0\u5df2\u7ecf\u7ed3\u675f\u4e86\u3002\u603b\u7b97\u662f\u89e3\u51b3\u4e86\u3002<\/p>\n<hr \/>\n<p>\u4e0a\u4e00\u6b21\u662f\u8fd9\u91cc-\u4e0b\u4e00\u6b21\u662f\u8fd9\u91cc<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u4e0a\u56de\u662f\u5728\u8fd9\u91cc-\u4e0b\u56de\u662f\u5728\u8fd9\u91cc\u3002 \u8fd9\u662f\u4ec0\u4e48\uff1f \u4f7f\u7528ansible\u5b9e\u73b0\u914d\u7f6e\u7ba1\u7406\u7684\u81ea\u52a8\u5316\u7684\u7b2c11\u7ae0 \u5728\u524d\u9762\u7684\u4e5d\u4e2a\u7ae0\u8282\u4e2d [&hellip;]<\/p>\n","protected":false},"author":7,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-42770","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v21.5 (Yoast SEO v21.5) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>\u5728SoftLayer\u7684\u514d\u8d39\u88f8\u91d1\u5c5e\u670d\u52a1\u5668\u4e0a\u5b66\u4e60OpenStack\uff0812\uff09- \u7b2c11\u7ae0 &quot;\u5229\u7528Ansible\u8fdb\u884c\u914d\u7f6e\u7ba1\u7406\u81ea\u52a8\u5316&quot; - Blog - Silicon Cloud<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.silicloud.com\/zh\/blog\/\u5728softlayer\u7684\u514d\u8d39\u88f8\u91d1\u5c5e\u670d\u52a1\u5668\u4e0a\u5b66\u4e60openstack\uff0812\uff09-\u7b2c11\u7ae0-\u5229\u7528an\/\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\u5728SoftLayer\u7684\u514d\u8d39\u88f8\u91d1\u5c5e\u670d\u52a1\u5668\u4e0a\u5b66\u4e60OpenStack\uff0812\uff09- \u7b2c11\u7ae0 &quot;\u5229\u7528Ansible\u8fdb\u884c\u914d\u7f6e\u7ba1\u7406\u81ea\u52a8\u5316&quot;\" \/>\n<meta property=\"og:description\" content=\"\u4e0a\u56de\u662f\u5728\u8fd9\u91cc-\u4e0b\u56de\u662f\u5728\u8fd9\u91cc\u3002 \u8fd9\u662f\u4ec0\u4e48\uff1f \u4f7f\u7528ansible\u5b9e\u73b0\u914d\u7f6e\u7ba1\u7406\u7684\u81ea\u52a8\u5316\u7684\u7b2c11\u7ae0 \u5728\u524d\u9762\u7684\u4e5d\u4e2a\u7ae0\u8282\u4e2d [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.silicloud.com\/zh\/blog\/\u5728softlayer\u7684\u514d\u8d39\u88f8\u91d1\u5c5e\u670d\u52a1\u5668\u4e0a\u5b66\u4e60openstack\uff0812\uff09-\u7b2c11\u7ae0-\u5229\u7528an\/\" \/>\n<meta property=\"og:site_name\" content=\"Blog - Silicon Cloud\" \/>\n<meta property=\"article:published_time\" content=\"2022-11-02T10:12:19+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-04-28T17:58:36+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d4ec437434c4406cc199d\/3-0.png\" \/>\n<meta name=\"author\" content=\"\u79d1, \u9896\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"\u79d1, \u9896\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"22 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8softlayer%e7%9a%84%e5%85%8d%e8%b4%b9%e8%a3%b8%e9%87%91%e5%b1%9e%e6%9c%8d%e5%8a%a1%e5%99%a8%e4%b8%8a%e5%ad%a6%e4%b9%a0openstack%ef%bc%8812%ef%bc%89-%e7%ac%ac11%e7%ab%a0-%e5%88%a9%e7%94%a8an\/\",\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8softlayer%e7%9a%84%e5%85%8d%e8%b4%b9%e8%a3%b8%e9%87%91%e5%b1%9e%e6%9c%8d%e5%8a%a1%e5%99%a8%e4%b8%8a%e5%ad%a6%e4%b9%a0openstack%ef%bc%8812%ef%bc%89-%e7%ac%ac11%e7%ab%a0-%e5%88%a9%e7%94%a8an\/\",\"name\":\"\u5728SoftLayer\u7684\u514d\u8d39\u88f8\u91d1\u5c5e\u670d\u52a1\u5668\u4e0a\u5b66\u4e60OpenStack\uff0812\uff09- \u7b2c11\u7ae0 \\\"\u5229\u7528Ansible\u8fdb\u884c\u914d\u7f6e\u7ba1\u7406\u81ea\u52a8\u5316\\\" - Blog - Silicon Cloud\",\"isPartOf\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#website\"},\"datePublished\":\"2022-11-02T10:12:19+00:00\",\"dateModified\":\"2024-04-28T17:58:36+00:00\",\"author\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/8ca01ba7f7362ad4edb7da206a12f29e\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8softlayer%e7%9a%84%e5%85%8d%e8%b4%b9%e8%a3%b8%e9%87%91%e5%b1%9e%e6%9c%8d%e5%8a%a1%e5%99%a8%e4%b8%8a%e5%ad%a6%e4%b9%a0openstack%ef%bc%8812%ef%bc%89-%e7%ac%ac11%e7%ab%a0-%e5%88%a9%e7%94%a8an\/#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8softlayer%e7%9a%84%e5%85%8d%e8%b4%b9%e8%a3%b8%e9%87%91%e5%b1%9e%e6%9c%8d%e5%8a%a1%e5%99%a8%e4%b8%8a%e5%ad%a6%e4%b9%a0openstack%ef%bc%8812%ef%bc%89-%e7%ac%ac11%e7%ab%a0-%e5%88%a9%e7%94%a8an\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8softlayer%e7%9a%84%e5%85%8d%e8%b4%b9%e8%a3%b8%e9%87%91%e5%b1%9e%e6%9c%8d%e5%8a%a1%e5%99%a8%e4%b8%8a%e5%ad%a6%e4%b9%a0openstack%ef%bc%8812%ef%bc%89-%e7%ac%ac11%e7%ab%a0-%e5%88%a9%e7%94%a8an\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.silicloud.com\/zh\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\u5728SoftLayer\u7684\u514d\u8d39\u88f8\u91d1\u5c5e\u670d\u52a1\u5668\u4e0a\u5b66\u4e60OpenStack\uff0812\uff09- \u7b2c11\u7ae0 &#8220;\u5229\u7528Ansible\u8fdb\u884c\u914d\u7f6e\u7ba1\u7406\u81ea\u52a8\u5316&#8221;\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#website\",\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/\",\"name\":\"Blog - Silicon Cloud\",\"description\":\"\",\"inLanguage\":\"zh-Hans\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/8ca01ba7f7362ad4edb7da206a12f29e\",\"name\":\"\u79d1, \u9896\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/8a6fb3cc7ba2f69d2189ba532aec4633ea7ed75ac0af162ec367cb3abc0fb2af?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/8a6fb3cc7ba2f69d2189ba532aec4633ea7ed75ac0af162ec367cb3abc0fb2af?s=96&d=mm&r=g\",\"caption\":\"\u79d1, \u9896\"},\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/author\/keying\/\"},{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8softlayer%e7%9a%84%e5%85%8d%e8%b4%b9%e8%a3%b8%e9%87%91%e5%b1%9e%e6%9c%8d%e5%8a%a1%e5%99%a8%e4%b8%8a%e5%ad%a6%e4%b9%a0openstack%ef%bc%8812%ef%bc%89-%e7%ac%ac11%e7%ab%a0-%e5%88%a9%e7%94%a8an\/#local-main-organization-logo\",\"url\":\"\",\"contentUrl\":\"\",\"caption\":\"Blog - Silicon Cloud\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"\u5728SoftLayer\u7684\u514d\u8d39\u88f8\u91d1\u5c5e\u670d\u52a1\u5668\u4e0a\u5b66\u4e60OpenStack\uff0812\uff09- \u7b2c11\u7ae0 \"\u5229\u7528Ansible\u8fdb\u884c\u914d\u7f6e\u7ba1\u7406\u81ea\u52a8\u5316\" - Blog - Silicon Cloud","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.silicloud.com\/zh\/blog\/\u5728softlayer\u7684\u514d\u8d39\u88f8\u91d1\u5c5e\u670d\u52a1\u5668\u4e0a\u5b66\u4e60openstack\uff0812\uff09-\u7b2c11\u7ae0-\u5229\u7528an\/","og_locale":"zh_CN","og_type":"article","og_title":"\u5728SoftLayer\u7684\u514d\u8d39\u88f8\u91d1\u5c5e\u670d\u52a1\u5668\u4e0a\u5b66\u4e60OpenStack\uff0812\uff09- \u7b2c11\u7ae0 \"\u5229\u7528Ansible\u8fdb\u884c\u914d\u7f6e\u7ba1\u7406\u81ea\u52a8\u5316\"","og_description":"\u4e0a\u56de\u662f\u5728\u8fd9\u91cc-\u4e0b\u56de\u662f\u5728\u8fd9\u91cc\u3002 \u8fd9\u662f\u4ec0\u4e48\uff1f \u4f7f\u7528ansible\u5b9e\u73b0\u914d\u7f6e\u7ba1\u7406\u7684\u81ea\u52a8\u5316\u7684\u7b2c11\u7ae0 \u5728\u524d\u9762\u7684\u4e5d\u4e2a\u7ae0\u8282\u4e2d [&hellip;]","og_url":"https:\/\/www.silicloud.com\/zh\/blog\/\u5728softlayer\u7684\u514d\u8d39\u88f8\u91d1\u5c5e\u670d\u52a1\u5668\u4e0a\u5b66\u4e60openstack\uff0812\uff09-\u7b2c11\u7ae0-\u5229\u7528an\/","og_site_name":"Blog - Silicon Cloud","article_published_time":"2022-11-02T10:12:19+00:00","article_modified_time":"2024-04-28T17:58:36+00:00","og_image":[{"url":"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d4ec437434c4406cc199d\/3-0.png"}],"author":"\u79d1, \u9896","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"\u79d1, \u9896","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"22 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8softlayer%e7%9a%84%e5%85%8d%e8%b4%b9%e8%a3%b8%e9%87%91%e5%b1%9e%e6%9c%8d%e5%8a%a1%e5%99%a8%e4%b8%8a%e5%ad%a6%e4%b9%a0openstack%ef%bc%8812%ef%bc%89-%e7%ac%ac11%e7%ab%a0-%e5%88%a9%e7%94%a8an\/","url":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8softlayer%e7%9a%84%e5%85%8d%e8%b4%b9%e8%a3%b8%e9%87%91%e5%b1%9e%e6%9c%8d%e5%8a%a1%e5%99%a8%e4%b8%8a%e5%ad%a6%e4%b9%a0openstack%ef%bc%8812%ef%bc%89-%e7%ac%ac11%e7%ab%a0-%e5%88%a9%e7%94%a8an\/","name":"\u5728SoftLayer\u7684\u514d\u8d39\u88f8\u91d1\u5c5e\u670d\u52a1\u5668\u4e0a\u5b66\u4e60OpenStack\uff0812\uff09- \u7b2c11\u7ae0 \"\u5229\u7528Ansible\u8fdb\u884c\u914d\u7f6e\u7ba1\u7406\u81ea\u52a8\u5316\" - Blog - Silicon Cloud","isPartOf":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/#website"},"datePublished":"2022-11-02T10:12:19+00:00","dateModified":"2024-04-28T17:58:36+00:00","author":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/8ca01ba7f7362ad4edb7da206a12f29e"},"breadcrumb":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8softlayer%e7%9a%84%e5%85%8d%e8%b4%b9%e8%a3%b8%e9%87%91%e5%b1%9e%e6%9c%8d%e5%8a%a1%e5%99%a8%e4%b8%8a%e5%ad%a6%e4%b9%a0openstack%ef%bc%8812%ef%bc%89-%e7%ac%ac11%e7%ab%a0-%e5%88%a9%e7%94%a8an\/#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8softlayer%e7%9a%84%e5%85%8d%e8%b4%b9%e8%a3%b8%e9%87%91%e5%b1%9e%e6%9c%8d%e5%8a%a1%e5%99%a8%e4%b8%8a%e5%ad%a6%e4%b9%a0openstack%ef%bc%8812%ef%bc%89-%e7%ac%ac11%e7%ab%a0-%e5%88%a9%e7%94%a8an\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8softlayer%e7%9a%84%e5%85%8d%e8%b4%b9%e8%a3%b8%e9%87%91%e5%b1%9e%e6%9c%8d%e5%8a%a1%e5%99%a8%e4%b8%8a%e5%ad%a6%e4%b9%a0openstack%ef%bc%8812%ef%bc%89-%e7%ac%ac11%e7%ab%a0-%e5%88%a9%e7%94%a8an\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.silicloud.com\/zh\/blog\/"},{"@type":"ListItem","position":2,"name":"\u5728SoftLayer\u7684\u514d\u8d39\u88f8\u91d1\u5c5e\u670d\u52a1\u5668\u4e0a\u5b66\u4e60OpenStack\uff0812\uff09- \u7b2c11\u7ae0 &#8220;\u5229\u7528Ansible\u8fdb\u884c\u914d\u7f6e\u7ba1\u7406\u81ea\u52a8\u5316&#8221;"}]},{"@type":"WebSite","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#website","url":"https:\/\/www.silicloud.com\/zh\/blog\/","name":"Blog - Silicon Cloud","description":"","inLanguage":"zh-Hans"},{"@type":"Person","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/8ca01ba7f7362ad4edb7da206a12f29e","name":"\u79d1, \u9896","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/8a6fb3cc7ba2f69d2189ba532aec4633ea7ed75ac0af162ec367cb3abc0fb2af?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/8a6fb3cc7ba2f69d2189ba532aec4633ea7ed75ac0af162ec367cb3abc0fb2af?s=96&d=mm&r=g","caption":"\u79d1, \u9896"},"url":"https:\/\/www.silicloud.com\/zh\/blog\/author\/keying\/"},{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8softlayer%e7%9a%84%e5%85%8d%e8%b4%b9%e8%a3%b8%e9%87%91%e5%b1%9e%e6%9c%8d%e5%8a%a1%e5%99%a8%e4%b8%8a%e5%ad%a6%e4%b9%a0openstack%ef%bc%8812%ef%bc%89-%e7%ac%ac11%e7%ab%a0-%e5%88%a9%e7%94%a8an\/#local-main-organization-logo","url":"","contentUrl":"","caption":"Blog - Silicon Cloud"}]}},"_links":{"self":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/42770","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/comments?post=42770"}],"version-history":[{"count":2,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/42770\/revisions"}],"predecessor-version":[{"id":73376,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/42770\/revisions\/73376"}],"wp:attachment":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/media?parent=42770"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/categories?post=42770"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/tags?post=42770"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}