开始使用Ansible进行配置管理工具_Part1
使用Ansible开始配置管理工具_Part1
Ansible是什么
【Ansible】是一种”配置管理工具”。
在管理构成时,可以使用一种名为“基础架构即代码”(Infrastructure as a Code)的工具来管理服务器的基础架构。这些工具包括Chef和Puppet等类似的工具。
在【Chef】和【Puppet】中,如果要进行高级管理,则必须以Ruby为基础,因此对于基础设施开发人员来说,学习成本很高,而且需要代理程序,因此引入的难度很大。
“而【Ansible】具备以下特点。”
-
- エージェントレスな構成管理ツール
-
- クライアントは、SSH接続(要鍵認証)でき、Pythonが導入されていること
-
- 設定がシンプル(そのため、複雑なことは苦手)
- ツールにより、冪等性(べきとうせい)を担保
需要注意的是,Ansible需要设定操作系统IP地址,并且必须满足连接条件。
因此,要自動化進行操作系統安裝,就需要使用【Kickstart】或【Cobbler】等工具。
为什么需要Ansible?
目前的情况
目前服务器构建的现状是,根据设计书创建参数表和构建步骤书,根据构建步骤书进行实际构建工作,并通过参数表进行配置设置。在测试中确认是否按照参数表进行设置,并确认是否按照设计书的要求正常运行。
【问题点、风险】
如果要建立大量的服务器,会浪费很多时间。(通过备份和恢复来解决部分问题,但仍需要部分修正配置的需要)
由于重复相同的操作,存在操作失误和设置值混淆的风险。(通过测试可以解决问题,但检查方也会重复相同的操作,从而可能忽略错误,导致时间浪费)
如果修改设计文档,存在实际设备未反映的风险。(如果在构建过程中进行了配置文件的版本管理和持续集成,可以避免这种风险)
【結論】毋庸置疑。
从以上内容可以看出,如果使用【配置管理工具】在机械化构建的服务器上,可以减少风险并实现时间上的工数减少。然而,项目成员必须将运营规则视作绝对条件。
然而,目前在供应商和SIer方面,即使进行机械化配置,持续进行单体测试参数设置确认的时间上的工数减少可能并不多。
【优点】
通过引入配置管理工具,可以实现风险减少和工时减少,当然还可以将操作系统和中间件的参数表作为配置管理工具的设置文件来代替,并通过对该设置文件进行版本管理,可以实现对IT基础设施的以代码【基础设施即代码】方式进行管理。
由于工具的多样化,虽然可以减轻实际工作量,但由于运营规则的增加,规则管理、运营流程展开、运营文件化和管理内容变得更加复杂。
请参考
- Webサイト
官方网站
文件
Ansible入门
面向初学者的Ansible教程
超级Ansible入门教程
日本Ansible用户协会
- 書籍
Ansible Kindle版入門
Ansible实践指南第2版
0. 验证环境
操作系统: CentOS 7.5
中间件: ansible 2.7.5
前提中间件: EPEL
1. 安装Ansible
1.1 安装 Ansible
# yum install -y epel-release ※1
# yum install -y ansible
# yum -y install python-pip ※2
# pip install --upgrade pip ※2
# pip install pywinrm ※2
# ansible --version ※3
安装完毕。只需进行操作设置,本身构建过程非常简单。
Ansible的设置已在/etc/ansible/ansible.cfg中完成,但不太可能需要更改此文件(因为可以通过Ansible的hosts文件和playbook进行控制)。
※1: 为了安装Ansible,需要添加适用于企业版Linux的扩展包(EPEL),因为Ansible不在标准软件库中存在。
※2: 如果要管理包括Windows Server在内的客户端,需要安装【pywinrm】。
※3: 为了确认安装成功,执行了显示版本的命令。
2. Ansible的配置
2.1. Ansible的组件
- Ansible用hostsファイル(/etc/ansible/hosts)
描述构成对象的客户端。
- playbook
这是一个将多个模块组合起来执行的【JOB】。
在其中记录了目标服务器的连接条件(目标服务器、用户、是否执行sudo、变量)。
playbook以【YAML格式】进行编写。
关于【YAML格式】的详细信息,请参考《面向程序员的YAML入门指南(初级篇)》。
- モジュール
在实际目标服务器上,描述安装软件包、复制文件或执行操作的内容。
在playbook的【task】中使用【YAML格式】进行描述。
2.2. Ansible使用hosts文件
Ansible使用hosts文件(/etc/ansible/hosts)作为Ansible的默认清单,可以通过将其分组为像[WebServerGroup]这样的组并进行相同的配置来简化在【playbook】中执行的内容。
当然,如果每个服务器有不同的配置,则需要为每个服务器提供相应的设置,因此需要制定并设置正确的运营规则。
执行Ansible的服务器是本地服务器,因此需要设置ansible_connection=local。顺便说一下,默认值是ssh。
主机名可以使用正则表达式来表示,比如可以写成[DBServerGroup]或[APServerGroup]等等。
关于连接的端口,可以在主机名后面加上冒号进行指定连接。另外,也可以使用ansible_port进行指定。顺便提一下,默认的ansible_port是假设使用SSH连接,所以默认是22。
并且,您也可以像以下示例中的[GatewayServerGroup]一样为ansible指定临时主机名,并使用【ansible_host】指定实际的IP地址。
[localhost]
127.0.0.1 ansible_connection=local
[WebServerGroup]
192.168.1.100
192.168.1.101
192.168.1.102
[DBServerGroup]
DB-[a:f].example.com:5501
[APServerGrroup]
www[01:10].example.com
[GatewayServerGroup]
Gateway01 ansible_port=1022 ansible_host=192.168.101.92
如果要使用除了默认库存( /etc/ansible/hosts )之外的文件,在ansible命令的选项中指定-i(–inventory),或者在ANSIBLE_HOSTS环境变量中指定路径是必需的。如果是指定了除了默认库存之外的文件,也可以以YAML格式进行描述。
请参阅官方文档【Working with Inventory】以获取详细信息。
另外,如果要与Windows进行连接,则需要确保客户端已启动Windows远程管理(WinRM)。
[windows]
192.168.99.3
ansible_ssh_user=<Windows側のユーザ名>
ansible_ssh_pass=<Windows側ユーザのパスワード>
ansible_ssh_port=5986
ansible_connection=winrm
ansible_winrm_server_cert_validation=ignore
2.3. 播放手冊配置
主持人
通过指定Ansible的hosts文件中的组名来执行操作。
通过指定”all”,可以在所有被写入到Ansible的hosts文件中的服务器上执行相同的操作。
远程用户
指定远程执行用户。由于Ansible使用SSH连接,因此需要设置执行用户的密钥认证。
使用sudo(切换为超级用户)
如果要执行sudo,请指定为yes。
需要指定在sudo_user中以sudo用户的身份进行执行。
另外,在执行ansible命令时,也可以指定-s(–sudo)。
可以在每个需要执行sudo的模块(task)中进行指定。
※1:在Ansible1.9及以上版本中,请使用become。
sudo_user (成为用户※2)
在执行sudo时指定执行用户。
※2:自Ansible1.9版本开始,请使用become_user。
变成的方法
如果你想要使用su而不是sudo来更改权限,你可以在become_method中指定su。
顺便说一下,默认的become_method是sudo。
公式文件(成为)
变量
在执行模块(任务)时,在此处进行设置并声明变量。
若按照以下方式声明,可供 ${HOME}、${INI_File}、${TmpDir} 等进行引用。
vars:
HOME: "/home/hogeuser"
INI_File: "/etc/local/ansible_local.ini"
TmpDir:/tmp
处理人员
当任务的状态发生改变时(即发生了”changed”事件),这个任务将在最后只执行一次。
任务端需要设置通知(notify),处理器端通过监听(listen)等待并与之关联。
- hosts: localhost
handlers:
- name: TEST handlers JOB
msg:execute handler
listen:Start handler A
tasks:
- name: TEST JOB
msg: message
changed_when: true
dest: /foo/bar/
notify: Start handler A
工作
这是playbook的核心项目。我们将列举要执行的模块。如果指定了name,在执行时会进行输出。此外,似乎name并非必需项。如果不写的话,模块部分的字符串将直接输出。
请参阅【2.5.任务模块】以获取每个任务的详细模块。
当
只有在满足指定条件的情况下才执行任务。
在以下情况下,将文件复制的结果存储在register中,并根据成功和失败进行处理。
- copy: src=/etc/hosts dest=/etc/hosts.old
register: result
ignore_errors: True
- debug: msg='File copy succeeded(succedded)'
when: result|succeeded
- debug: msg='File copy failed(failed)'
when: result|failed
使用项目
循环处理。
在以下情况下,将所描述的数组分配给变量,创建名为[/tmp/test1]、[/tmp/test2]、[/tmp/test3]的目录。
- name: ディレクトリの作成
file: path=/tmp/{{ item }} state=directory
with_items:
- test1
- test2
- test3
要使用 with_items 进行循环执行命令结果,需要先执行命令并将其结果注册(register),然后将该结果赋值给 with_items 的变量。
- name: retrieve the list of home directories
command: ls /home
register: home_dirs
- name: add home dirs to the backup spooler
file: path=/mnt/bkspool/{{ item }} src=/home/{{ item }} state=link
with_items: home_dirs.stdout_lines
# same as with_items: home_dirs.stdout.split()
直到
循环处理。
直到条件符合时,循环才会跳出(在这种情况下,直到标准输出显示“OK”为止循环)。
重试次数为 retries
延迟为睡眠的秒数
- shell: /u
sr/bin/foo
register: result
until: result.stdout.find("OK") != -1
retries: 5
delay: 10
导入剧本
创建将指定文件进行组件化并进行调用的策略。
创建按任务细分的playbook并进行include,这样如果需要修改每个playbook,影响程度就会较小。
- import_playbook: include_1.yml
名字
在各个项目评论中使用。在playbook的概述中简明地记录下来,以便以后查看时更容易理解。
- name: install via yum
yum: name={{ item }} state=installed
with_items:
- bash
- git
- ntp
请把以下信息用中文进行意译,只需要给出一种选项:
信息
向标准输出打印出一条消息。
在调试时使用指针非常方便。
请参考样本中的调试信息。
调试
在进行调试时,添加此项以便确认内容。
下面的示例中,我们正在检查变量是否被赋值给register。
在执行ansible-playbook命令时,无论使用-v、-vv还是-vvv,都可以进行同样的调试。
- name: check file exists
stat:
path: /etc/hosts
register: res_exists
- name: debug var res_exists
debug:
msg: "{{ res_exists }}"
2.4 模块(任务).
外壳
在Shell上执行命令。
shell: sample_script.sh arg1 arg1 >> sample_log.log
命令
在远程节点上执行命令。
只要[/path/to/database]存在,就执行shell。
- command: /usr/bin/make_database.sh arg1 arg2 creates=/path/to/database
文件
创建文件和目录,设置权限。但是,下列内容的状态是链接,因此会成为符号链接。
当涉及文件的情况时,需要注意Ansible服务器是源服务器。
- file:
src=/usr/local/foo.txt
dest=/opt/foo.txt
owner=root
group=root
mode=0755
state=link
在文件中的每一行
逐行修改文件内容。
只需提供一种选择,以下情况下需要将开头的SELINUX=行替换为SELINUX=enforcing。
- lineinfile:
path: /etc/selinux/config
regexp: '^SELINUX='
line: 'SELINUX=enforcing'
模板
通过使用模板复制文件。模板文件需要放置在/etc/ansible/templates/路径下。
- template:
src=template.j2
dest=/opt/file.conf
owner=root
group=root
mode=0644
同步
从「rsync启动主机(Ansible服务器)」复制文件和目录到「操作目标主机(通过清单指定的主机)」。
- synchronize:
src=source_dir
dest=/tmp/target_dir
recursive=yes
复制
- copy:
src=foo.txt
dest=/tmp/foo.txt
owner=root
group=root
mode=0755
美味
使用yum软件包管理器进行软件包的安装、升级和删除
yum: name=httpd state=latest
其他
其他模块请参考Ansible模块列表。
最佳做法
在Ansible官方网站中更新的最佳实践是按照以下配置进行的。
对于这些,我们只能根据实际现场环境和运营规则进行定制。
/etc/ansible/
├inventories/
│ ├production/
│ │ ├hosts # 用于生产环境服务器的清单文件
│ │ ├group_vars/
│ │ │ ├group1.yml # 将变量分配给特定的组
│ │ │ └group2.yml
│ │ └host_vars/
│ │ ├hostname1.yml # 将变量分配给特定的系统
│ │ └hostname2.yml
│ │
│ └staging/
│ ├hosts # 用于开发环境服务器的清单文件
│ ├group_vars/
│ │ ├group1.yml # 将变量分配给特定的组
│ │ └group2.yml
│ └host_vars/
│ ├stagehost1.yml # 将变量分配给特定的系统
│ └stagehost2.yml
│
├library/ # 放置自定义模块(可选)。
├module_utils/ # 放置module_utils(可选)。
├filter_plugins/ # 放置自定义过滤器插件(可选)。
│
├site.yml # 主要playbook
├webservers.yml # 用于web服务器层的playbook
├dbservers.yml # 用于数据库服务器层的playbook
│
└roles/
├common/ # 此层表示”角色”
│ ├tasks/
│ │ └main.yml
│ ├handlers/
│ │ └main.yml
│ ├templates/
│ │ └ntp.conf.j2
│ ├files/
│ │ └source files # 用于复制资源的文件
│ │ └script files # 用于脚本资源的脚本文件
│ ├vars/
│ │ └main.yml # 与此角色相关的变量
│ ├defaults/
│ │ └main.yml # 角色的默认低优先级变量
│ ├meta/
│ │ └main.yml # 角色依赖关系
│ ├library/ # 包括自定义模块
│ ├module_utils/ # 包括自定义module_utils
│ └lookup_plugins/ # 类似于搜索或其他类型的插件
├webtier/ # 与common具有相同结构
├monitoring/
└fooapp/
3. 执行指令 (zhí zhǐ lì)
3.1. Ansible命令
在使用Ansible执行临时处理时使用的命令。
-
- 「(インベントリファイルに書かれた)対象のホスト」 ( コマンド引数 )
-
- 「インベントリファイル」 ( -i )
-
- 「使うモジュール」 ( -m )
- 「モジュールに与える引数」 ( -a )
在远程主机上执行echo命令。
使用Ansible在目标主机上执行命令: ansible target_host -i inventory_file -m shell -a ‘echo “Hello World”‘
在远程主机上,以root用户身份执行ping命令
ansible目标主机 -m ping -i inventory_file -u root
在远程主机上启动httpd。
ansible 目标主机 -m 服务 -a “name=httpd state=started”
在远程主机上添加用户。
在中国语中的表达为:
使用 Ansible 目标主机命令 `-m user -a “name=username password=<密文密码>”`。
3.2.执行ansible-playbook命令
用 YAML 描述一系列处理流程,并执行该命令。
-
- 通常実行
-
- ansible-playbook -i inventory_file playbook.yml
-
- 構文チェック
-
- ansible-playbook -i inventory_file playbook.yml –syntax-check
-
- 実行されるタスクの一覧を表示
-
- ansible-playbook -i inventory_file playbook.yml –list-tasks
-
- verboseオプション(-vvv)で詳細情報の表示する。
-
- ansible-playbook -i inventory_file -u root -k playbook.yml -vvv
- 実行時にパラメータを付与する。
使用变量 “xxx=yes” 和 inventory_file 主机清单文件运行 playbook.yml 的 ansible-playbook 命令。
ansible-playbook -e “xxx=yes” -i inventory_file playbook.yml
使用inventory_file中的主机清单,运行playbook.yml的ansible-playbook,同时传递变量xxx=yes。
-
- 実行するときのユーザの秘密鍵を指定して実行する
- ansible-playbook -i inventory_file playbook.yml –private-key=/path/key.pem
3.3. 使用ansible-doc命令
-
- モジュール確認
- ansible-doc -l
最后
由于Ansible的特性,应该使用root用户来执行每个基础设施的配置,包括操作系统的设置和中间件的安装。而中间件的配置应该使用专门的中间件用户来执行。
因此,在SSH密钥身份验证中,务必将密钥认证配置给执行playbook的用户,并将公钥配置在客户端上以防忘记。
另外,当升级版本时,需要注意的是,有些在Ansible playbook中使用的【键】(配置项)可能会因版本不同而改变其名称。
构成管理工具确实在有几百台服务器时是必要的,但是Ansible无法完成虚拟机创建、操作系统安装以及IP设置等任务。
因此,目前我并没有强烈地感受到它的必要性。(Shell已经足够)
我正在考虑验证包括操作系统安装在内的工具,以及验证配置管理工具的必要性作为下一个任务。