Ansible 学习(初探)

󰃭 2017-02-23

原创作品:首发u3v3, 转载请保留

地址:https://www.u3v3.com/ar/1260

作者ID:noomrevils

首发日期:2017.2.24

简介

Ansible 是一个基于Python语言开发的配置管理和应用部署工具。相比业界前辈 Chef,Puppet,Saltstack。Ansible轻量,模块化等特点让他具有很强的扩展和二次开发的能力,成为devops领域一颗冉冉升起的新星。

特性

  • 轻量:

    • 默认基于ssh协议,不需要在被控节点上安装任何客户端,
    • 管理节点不以daemons方式来启动和守护,没有额外的数据库配置,直接命令行操作
  • 强大的内置模块, apt/yum, service, cron, 协助完成日常运维场景的工作,并可以定制开发拓展

  • 采用yaml来描述和管理流程,并有基于yaml的playbook来重用和组织任务, playbook有强大的社区支持

框架结构

工作流程

基于上面的动图描述一个使用场景: (使用ansible部署web服务)

前提条件:

  • 管理节点安装ansible,并和被控节点建立基于公钥的ssh信任
  • 主机清单(Invetory) 定义了被控节点的域名,端口,ip等信息
  • playbook中描述了任务执行的流程和对应操作处理

流程:

  • ansibe查看playbook中定义的参数,渲染playbook模板
  • 读取主机清单, 和对应的被控节点建立ssh连接
  • 按照playbook中定义的流程(安装依赖软件包,git拉取最新代码,更新配置文件,启动web服务)
  • 全部被控节点执行后,返回执行状态报告

安装

官方文档有上有详细针对不同linux发行版本的安装教程

这里只列出在Debian上使用apt-get的安装步骤

  • 将ansible的官方源加入到debian可信源列表中
deb http://ppa.launchpad.net/ansible/ansible/ubuntu trusty main
  • 执行下面的命令
$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 93C4A3FD7BB9C367
$ sudo apt-get update
$ sudo apt-get install ansible

$ which ansible # 确认安装成功
/usr/bin/ansible

$ ansible --version # 查看安装的版本, 和配置文件&模块加载路径
ansible 2.2.1.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides

节点ssh配置

为了说明,假设上面安装ansible的Debian机器为A, A机器是管理节点,它在私有网络的ip是10.99.0.10, 这个时候,再创建一台预装CentOS 7虚拟机器B, B机器是被控节点,它的私有网络ip是10.99.0.11。

生成管理节点公钥

    ssh-keygen -b 1024 -t rsa -f ~/.ssh/id_rsa -P ""

被控节点创建deploy用户, (可选,ansible默认使用root账户登录被控节点)

这里的目的是从服务器安全角度出发,不随意使用root账户

useradd deploy
usermod -s /bin/bash deploy #指定 deploy 用户的默认shell
passwd deploy # 给deploy用户添加密码,后面管理节点分发公钥会用到

分发管理节点的公钥到被控节点

推荐采用 ssh-copy-id 命令, 格式如下, -i用于指定公钥文件

$ ssh-copy-id -i /path/id_rsa.pub usr@remote-host

上面在被控节点B上添加了deploy用户,执行命令得到如下结果,测试可以ssh登录,

$ ssh-copy-id -i /home/deploy/.ssh/id_rsa.pub deploy@10.99.0.11

/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
deploy@10.99.0.11's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'deploy@10.99.0.11'"
and check to make sure that only the key(s) you wanted were added.

如果你的发行版本上没有ssh-copy-id, 或无法安装,不想安装的话, 可以执行下面的命令

cat ~/.ssh/id_rsa.pub | ssh <user>@<hostname> 'umask 0077; mkdir -p .ssh; cat >> .ssh/authorized_keys && echo "Key copied"'

主机清单配置

默认的主机清单存放的位置是 /etc/ansible/hosts, 先对原始文件做个备份, 然后修改hosts文件

cp -v /etc/ansible/hosts /etc/ansible/hosts.bak 
$ sudo vim /etc/ansible/hosts 

添加如下内容, 这里指定被控节点B所属于web这个组

[web]
10.99.0.11

基本测试

基本命令: ansible group -m module -u user

  • group 对应被控节点组名
  • -m 指定使用模块, ping是内置用于测试远程主机的连接状态的模块
  • -u 指定登录被控节点的账户
$ ansible web -m ping -u deploy

10.99.0.11 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

再来看一个例子, 这里all指定所有被控节点, --private-key指定ssh登录采用公钥

ansible all -m ping -u root --private-key=~/.ssh/id_ansible

root权限

在做部署的时候,难免会需要root权限, 由于上面采用自建用户deploy登录,下面来给deloy用户sudo的权限

    $ sudo groupadd sudo #添加一个组(sudo), 这个组拥有sudo权限
    $ usermod -aG sudo deploy # 将 deploy 加入到这个组

然后使用visudo命令编辑权限, 在root下面添加一行

root    ALL=(ALL)       ALL
%sudo   ALL=(ALL:ALL)  ALL  # sudo依然需要密码

来测试一下

-b, –become 成为指定用户,留空默认为root

# 以deploy登录, 切换到root
$ ansible web -m ping -u deploy -b

10.99.0.11 | FAILED! => {
    "changed": false,
    "failed": true,
    "module_stderr": "Shared connection to 10.99.0.11 closed.\r\n",
    "module_stdout": "sudo: a password is required\r\n",
    "msg": "MODULE FAILURE"
}

报错了,看下错误信息 "module_stdout": "sudo: a password is required\r\n", 提示我们需要密码。使用-K, --ask-become-pass选项再试下

$ ansible web -m ping -u deploy -b -K
SUDO password:
10.99.0.11 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

当然也可以将deploy用户设置为不需要密码, 将之间通过visudo添加的一行改为下面的内容

# %sudo   ALL=(ALL:ALL) NOPASSWD: ALL

常用模块

setup

用来查看被控节点的基本信息

$ ansible web -m setup -u deploy 
10.99.0.11 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "10.99.0.11",
            "xx.xx.xx.xx"
        ],
        "ansible_all_ipv6_addresses": [
                ...
        ],
        "ansible_architecture": "x86_64",
        "ansible_bios_date": "04/01/2014",
        "ansible_bios_version": "rel-1.9.3-0-ge2fc41e-prebuilt.qemu-project.org",
        "ansible_cmdline": {
            "BOOT_IMAGE": "/boot/vmlinuz-3.10.0-514.2.2.el7.x86_64",
            "LANG": "en_US.UTF-8",
            "consoleblank": "0",
            ...

command

在远程主机上执行命令 -a 指定cmd需要执行的命令

$ ansible web -u deploy -m command -a "uptime"
10.99.0.11 | SUCCESS | rc=0 >>
 17:38:13 up  5:31,  3 users,  load average: 0.00, 0.01, 0.05

$ ansible web -u deploy -m command -a "who" -b
10.99.0.11 | SUCCESS | rc=0 >>
root     pts/0        2017-02-23 15:41 (xx.xx.xx.xx)
root     pts/1        2017-02-23 17:13 (xx.xx.xx.xx)
deploy   pts/2        2017-02-23 17:39 (10.99.0.10)

shell

shell模块和command模块类似, 此外这个命令还支持管道

$ ansible web -m shell -a "ping -c 3 www.google.com" -u deploy 

10.99.0.11 | SUCCESS | rc=0 >>
PING www.google.com (216.58.200.4) 56(84) bytes of data.
64 bytes from hkg12s11-in-f4.1e100.net (216.58.200.4): icmp_seq=1 ttl=53 time=47.7 ms
64 bytes from hkg12s11-in-f4.1e100.net (216.58.200.4): icmp_seq=2 ttl=53 time=47.9 ms
64 bytes from hkg12s11-in-f4.1e100.net (216.58.200.4): icmp_seq=3 ttl=53 time=47.7 ms

--- www.google.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 47.788/47.834/47.923/0.260 ms

其他更多模块

  • file: 设置文件属性

  • copy: 文件复制

  • service: 系统服务管理

  • cron: 计划任务管理

  • apt/yum: 软件包安装管理

  • synchronize: 使用rsync同步文件

  • user: 系统用户管理

  • group: 系统用户组管理

题外话 & 小广告

vps创建过程,内网ip启用等, 感兴趣请参考

下面是vultr注册邀请码,如果有需要还请使用, 你可以额外获得20刀,我也可以额外获得奖励, 感谢阅读和支持。