ansible 学习笔记
本文 的主要内容来自ansible官网书籍。
本文采用vagrant软件基于VirtualBox的虚拟机进行自动化管理,先要安装VirtualBox和vagrant两个软件。
类似Docker有Dockerfile
, Jenkins有Jenkinsfile
, Vagrant也有自己的Vagrantfile
, Vagrantfile是用Ruby语言写成的。
注意:这几种配置文件的使用方式类似,命名都是首字母大写的无扩展名文件。
vagrant: 流浪 stray, wandering, wanderings, vagrant, vagabonds, strayed
配置环境
创建工作目录
代码语言:javascript复制$ mkdir -p ~/ansible/vms
$ cd ~/ansible/vms
$ ls
下面放两个文件:
hosts Vagrantfile
文件内容:
$ cat hosts
输出:
代码语言:javascript复制# Lines beginning with a # are comments, and are only included for
# illustration. These comments are overkill for most inventory files.
# Application servers
[app]
192.168.60.4
192.168.60.5
# Database server
[db]
192.168.60.6
# Group 'multi' with all servers
[multi:children]
app
db
# Variables that will be applied to all servers
[multi:vars]
ansible_ssh_user=vagrant
ansible_ssh_private_key_file=~/.vagrant.d/insecure_private_key
代码语言:javascript复制$ cat Vagrantfile
输出:
代码语言:javascript复制# -*- mode: ruby -*-
# vi: set ft=ruby :
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
# General Vagrant VM configuration.
config.vm.box = "geerlingguy/centos7"
config.ssh.insert_key = false
config.vm.synced_folder ".", "/vagrant", disabled: true
config.vm.provider :virtualbox do |v|
v.memory = 256
v.linked_clone = true
end
# Application server 1.
config.vm.define "app1" do |app|
app.vm.hostname = "orc-app1.dev"
app.vm.network :private_network, ip: "192.168.60.4"
end
# Application server 2.
config.vm.define "app2" do |app|
app.vm.hostname = "orc-app2.dev"
app.vm.network :private_network, ip: "192.168.60.5"
end
# Database server.
config.vm.define "db" do |db|
db.vm.hostname = "orc-db.dev"
db.vm.network :private_network, ip: "192.168.60.6"
end
end
下载虚拟机镜像
代码语言:javascript复制$ vagrant box add "geerlingguy/centos7"
按Vagrantfile来初始化虚拟机:
代码语言:javascript复制$ vagrant up
$ vagrant provision
如果都安装好了,可以ping一下试试
代码语言:javascript复制$ ansible app -a 'ping -c 1 baidu.com'
192.168.60.5 | SUCCESS | rc=0 >>
PING baidu.com (220.181.38.148) 56(84) bytes of data.
64 bytes from 220.181.38.148 (220.181.38.148): icmp_seq=1 ttl=63 time=2.54 ms
--- baidu.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 2.541/2.541/2.541/0.000 ms
192.168.60.4 | SUCCESS | rc=0 >>
PING baidu.com (220.181.38.148) 56(84) bytes of data.
64 bytes from 220.181.38.148 (220.181.38.148): icmp_seq=1 ttl=63 time=3.11 ms
--- baidu.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 3.116/3.116/3.116/0.000 ms
因为以测试都是以hosts文件中的inventory定义为基础,所以可以建一个alias ansible='ansible -i hosts'
, 避免每次都输入 -i hosts
参数。为便于读者复制粘贴,以下ansible
命令前不再重复命令行提示符$
。
还可以做一此测试,如安装时间服务:
代码语言:javascript复制ansible multi -a "hostname" -f 1
ansible multi -f 1 -a "hostname"
ansible multi -a "df -h"
ansible multi -a "free -m -h "
ansible multi -a "date"
ansible multi -m setup
ansible multi -s -m yum -a "name=ntp state=present"
ansible multi -a "date"
ansible multi -s -m service -a "name=ntpd state=started enabled=yes"
ansible multi -s -a "service ntpd stop"
ansible multi -s -a "ntpdate -q 0.rhel.pool.ntp.org"
ansible multi -s -a "service ntpd start"
ansible 默认是在多台服务器上并行执行操作的, 可以通过 --forks <N>
参数指定并行度。N=1,采用串行方式执行。
-
-m
参数是指定 ansible 的模块名称,模块采用状态声明的方式,强调操作的幂等性,即次操作与一次操作的最终结果是一样的。 -
-s
参数是--sudo
的缩写。即以 root 用户身份执行操作。
安装软件
代码语言:javascript复制ansible app -s -m yum -a "name=MySQL-python state=present"
ansible app -s -m yum -a "name=python-setuptools state=present"
ansible app -s -m easy_install -a "name=django state=present"
#在我机器上因为用 easy_install 安装 django 因 python 版本没有成功,后改为 pip3安装。
ansible app -s -m yum -a "name=python3-pip state=present"
ansible app -s -m pip -a "name=django state=present"
测试 django
代码语言:javascript复制 ansible app -a "python3 -c 'import django; print(django.get_version())'"
代码语言:javascript复制192.168.60.4 | SUCCESS | rc=0 >>
2.2.5
192.168.60.5 | SUCCESS | rc=0 >>
2.2.5
安装MySQL
代码语言:javascript复制ansible db -s -m yum -a "name=mariadb-server state=present"
ansible db -s -m service -a "name=mariadb state=started enabled=yes"
ansible db -s -a "iptables -F"
ansible db -s -a "iptables -A INPUT -s 192.168.60.0/24 -p tcp -m tcp --dport 3306 -j ACCEPT"
设置MySQL
代码语言:javascript复制ansible db -s -m yum -a "name=MySQL-python state=present"
ansible db -s -m mysql_user -a "name=django host=% password=12345 priv=*.*:ALL state=present"
常用操作一览
检查服务状态
代码语言:javascript复制ansible app -s -a "service ntpd status"
只检查一台机器
代码语言:javascript复制ansible app -s -a "service ntpd restart" --limit "192.168.60.4"
正则匹配~
代码语言:javascript复制 ansible app -s -a "service ntpd restart" --limit ~".*.4"
建组
代码语言:javascript复制ansible app -s -m group -a "name=admin state=present"
删除组
代码语言:javascript复制ansible app -s -m group -a "name=admin state=absent"
建用户
代码语言:javascript复制 ansible app -s -m user -a "name=johndoe group=admin createhome=yes"
如果要为新用户自动创建 SSH 密钥(如果不存在的话),您可以使用参数generate_ssh_key=yes
。您还可以通过传入 uid=[uid]
,来设置用户的 UID,shell=[shell]
设置用户外壳 ,password=[encryptedpassword]
设置密码 等。
删除用户
代码语言:javascript复制ansible app -s -m user -a "name=johndoe state=absent remove=yes"
系统无关的包安装
代码语言:javascript复制ansible app -s -m package -a "name=git state=present"
状态检查
代码语言:javascript复制ansible multi -m stat -a "path=/etc/environment"
拷贝文件
代码语言:javascript复制 ansible multi -m copy -a "src=/etc/hosts dest=/tmp/hosts"
下载(会产生以host/ip目录开头的多个文件)
代码语言:javascript复制 ansible multi -s -m fetch -a "src=/etc/hosts dest=/tmp"
后台执行
-
-B <seconds>
: 指定最多用时。 -
-P <seconds>
:指定任务执行状态的更新时间。默认10秒。
ansible multi -s -B 3600 -a "yum -y update"
启动就不理的长时任务
代码语言:javascript复制ansible multi -B 3600 -P 0 -a "/path/to/fire-and-forget-script.sh"
检查日志文件
ansible执行完后回显输出,所以不适合跟踪大量的文本输出。
代码语言:javascript复制 ansible multi -s -a "tail /var/log/messages"
#或
ansible multi -s -m shell -a "tail /var/log/messages |
grep ansible-command | wc -l"
克隆任务执行
增加每日定时任务
代码语言:javascript复制ansible multi -s -m cron -a "name='daily-cron-all-servers'
hour=4 job='/path/to/daily-script.sh'"
去掉任务
代码语言:javascript复制ansible multi -s -m cron -a "name='daily-cron-all-servers'
state=absent"
git
代码语言:javascript复制ansible package -s -m yum -a "name=git state=present".
ansible app -s -m git -a "repo=git://example.com/path/to/repo.git dest=/opt/myapp update=yes version=1.2.4"
ansible 执行加速
SSH pipelining
SSH pipelining 是一个加速 Ansible 执行速度的简单方法。ssh pipelining 默认是关闭,之所以默认关闭是为了兼容不同的 sudo 配置,主要是 requiretty 选项。此选项可以减少 ansible 执行没有传输时 ssh 在被控机器上执行任务的连接数。如果使用 sudo,必须关闭 requiretty 选项。修改 /etc/ansible/ansible.cfg 文件可以开启 pipelining
将
代码语言:javascript复制pipelining=False
修改为
代码语言:javascript复制pipelining=True
修改完后,可以批量对机器执行命令试下,可以明显感受到速度的提升。
ControlPersist
ControlPersist 特性需要高版本的 SSH 才支持,CentOS 6 默认是不支持的,如果需要使用,需要自行升级 openssh。ControlPersist 即持久化 socket,一次验证,多次通信。并且只需要修改 ssh 客户端就行。
ControlPersist 设置的办法:
代码语言:javascript复制cat ~/.ssh/config
Host *
Compression yes
ServerAliveInterval 60
ServerAliveCountMax 5
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 4h
在开启了 ControlPersist 特性后,SSH 在建立了 sockets 之后,节省了每次验证和创建的时间。在网络状况不是特别理想时,带来的性能提升是非常可观的。
小结
以上是 ansible 的一些初步使用展示。更高级的 playbook 用法没有涉及到。