Ansible之前

image-20200504132245297

image-20200504132329133

运维工程师职能划分

云计算

image-20200504145257181

Linux

image-20200504145309817

企业实际应用场景分析

  • Dev开发环境

    • 使用者:程序员
    • 功能:程序员开发软件,测试BUG的环境
    • 管理者:程序员
  • 测试环境

    • 使用者:QA测试工程师

    • 功能:测试经过Dev环境测试通过的软件的功能

    • 管理者:运维

    • 说明:测试环境往往有多套,测试环境满足测试功能即可,不宜过多

      1、测试人员希望测试环境有多套,公司的产品多产品线并发,即多个版本, 意味着多个版本同步测试

      2、通常测试环境有多少套和产品线数量保持一样

  • 发布环境:代码发布机,有些公司为堡垒机(安全屏障)

    • 使用者:运维

    • 功能:发布代码至生产环境

    • 管理者:运维(有经验)

    • 发布机:往往需要有2台(主备)

  • 生产环境

    • 使用者:运维,少数情况开放权限给核心开发人员,极少数公司将权限完全 开放给开发人员并其维护
    • 功能:对用户提供公司产品的服务
    • 管理者:只能是运维
    • 生产环境服务器数量:一般比较多,且应用非常重要。往往需要自动工具协 助部署配置应用
  • 灰度环境(生产环境的一部分)

    • 使用者:运维

    • 功能:在全量发布代码前将代码的功能面向少量精准用户发布的环境,可基 于主机或用户执行灰度发布

    • 案例:共100台生产服务器,先发布其中的10台服务器,这10台服务器就是灰度服务器

    • 管理者:运维

    • 灰度环境:往往该版本功能变更较大,为保险起见特意先让一部分用户优化体验该功能,待这部分用户使用没有重大问题的时候,再全量发布至所有服务器

程序发布

  • 程序发布要求:

    • 不能导致系统故障或造成系统完全不可用
    • 不能影响用户体验
  • 预发布验证:

    • 新版本的代码先发布到服务器(跟线上环境配置完全相同,只是未接入到调度器)
  • 灰度发布:

    • 基于主机,用户,业务
  • 发布路径:

    • /webap/tuangou
    • /webap/tuangou-1.
    • /webap/tuangou-1.2
  • 发布过程:在调度器上下线一批主机(标记为maintance状态) -> 关闭服务 -> 部署新版本的应用程序 -> 启动服务 -> 在调度器上启用这一批服务器

  • 自动化灰度发布:脚本、发布平台

运维自动化发展例程

image-20200504145951721

自动化运维应用场景

  • 文件传输
  • 应用部署
  • 配置管理
  • 任务流编排

常用自动化运维工具

  • Ansible:python,Agentless,中小型应用环境
  • Saltstack:python,一般需部署agent,执行效率更高
  • Puppet:ruby, 功能强大,配置复杂,重型,适合大型环境
  • Fabric:python,agentless
  • Chef:ruby,国内应用少
  • Cfengine
  • func

Ansible

发展史

  • Ansible

    • Michael DeHaan( Cobbler 与 Func 作者)
    • 名称来自《安德的游戏》中跨越时空的即时通信工具
    • 2012-03-09,发布0.0.1版,2015-10-17,Red Hat宣布收购
    • 官网:https://www.ansible.com/
    • 官方文档:https://docs.ansible.com/
  • 同类自动化工具GitHub关注程度(2016-07-10)

    image-20200504150237464

特性

  • 模块化:调用特定的模块,完成特定任务
  • Paramiko(python对ssh的实现),PyYAML,Jinja2(模板语言)三个关键模块
  • 支持自定义模块,可使用任何编程语言写模块
  • 基于Python语言实现
  • 部署简单,基于python和SSH(默认已安装),agentless
  • 安全,基于OpenSSH
  • 支持playbook编排任务
  • 幂等性:一个任务执行1遍和执行n遍效果一样,不因重复执行带来意外情况
  • 无需代理不依赖PKI(无需ssl)
  • 可使用任何编程语言写模块
  • YAML格式,编排任务,支持丰富的数据结
  • 较强大的多层解决方案

架构

image-20200504150356647

工作原理

image-20200504150413852

主要组成部分

  • ANSIBLE PLAYBOOKS:任务剧本(任务集),编排定义Ansible任务集的配置文件,由Ansible顺序依次执行,通常是JSON格式的YML文件

  • INVENTORY:Ansible管理主机的清单/etc/anaible/hosts

  • MODULES:Ansible执行命令的功能模块,多数为内置核心模块,也可自定义

  • PLUGINS:模块功能的补充,如连接类型插件、循环插件、变量插件、过滤插 件等,该功能不常用

  • API:供第三方程序调用的应用程序编程接口

  • ANSIBLE:组合INVENTORY、API、MODULES、PLUGINS的绿框,可以理解 为是ansible命令工具,其为核心执行工具

  • Ansible命令执行来源:

    • USER,普通用户,即SYSTEM ADMINISTRATOR
    • CMDB(配置管理数据库) API 调用
    • PUBLIC/PRIVATE CLOUD API调用
    • USER-> Ansible Playbook -> Ansibile
  • 利用ansible实现管理的方式:

    • Ad-Hoc 即ansible命令,主要用于临时命令使用场景
    • Ansible-playbook 主要用于长期规划好的,大型项目的场景,需要有前期的规划过程
  • Ansible-playbok(剧本)执行过程

    • 将已有编排好的任务集写入Ansible-Playbok
    • 通过ansible-playbok命令分拆任务集至逐条ansible命令,按预定规则逐条执行
  • Ansible主要操作对象

    • HOST主机
    • NETWORKING网络设备

注意事项

  • 执行ansible的主机一般称为主控端,中控,master或堡垒机
  • 主控端Python版本需要2.6或以上
  • 被控端Python版本小于2.4需要安装python-simplejson
  • 被控端如开启SELinux需要安装libselinux-python
  • windows不能做为主控端

安装

  • rpm包安装: EPEL源
    dnf install ansible -y

  • 编译安装:

    1
    2
    3
    4
    5
    6
    7
    8
    yum -y instal python-jina2 PyYAML python-parmiko python-bael
    python-crypto
    tar xf ansible-1.54.tar.gz
    cd ansible-1.54
    python setup.y build
    python setup.y install
    mkdir /etc/ansible
    cp -r examples/*etc/ansible
  • Git方式:

    1
    2
    3
    git clone git:/github.com/ansible/ansible.git -recursive
    cd ./ansible
    source ./hacking/env-setup
  • pip安装: pip是安装Python包的管理器,类似dnf

    1
    2
    3
    4
    dnf install python-pip python-devel
    dnf install gcc glibc-devel zibl-devel rpm-bulid openssl-devel
    pip install --upgrade pip
    pip install ansible --upgrade
  • 确认安装 :

    ansible --version

部署

关于ssh的部署请参看此篇博客https://kinmfer.github.io/2020/05/05/Linux%E5%9F%BA%E7%A1%80-14-%E5%8A%A0%E5%AF%86%E5%92%8C%E5%AE%89%E5%85%A8/

相关文件

  • 配置文件

    • /etc/ansible/ansible.cfg 主配置文件,配置ansible工作特性(一般保持默认)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      [defaults]
      #inventory = /etc/ansible/host # 主机列表配置文件
      #library = /usr/share/my_modules/ # 库文件存放目录
      #remote_tmp = $HOME/.ansible/tmp #临时py命令文件存放在远程主机目录
      #local_tmp = $HOME/.ansible/tmp # 本机的临时命令执行目录
      #forks = 5 # 默认并发数
      #sudo_user = root # 默认sudo 用户
      #ask_sudo_pass = True #每次执行ansible命令是否询问sh密码
      #ask_pass = True
      #remote_port = 2
      #host_key_checking = False # 检查对应服务器的host_key,建议取消注释
      #log_path=/var/log/ansible.log #日志文件
      #module_name = comand #默认模块
    • /etc/ansible/host 主机清单

    • /etc/ansible/roles/ 存放角色的目录

  • 程序

    • /usr/bin/ansible 主程序,临时命令执行工具
    • /usr/bin/ansible-doc 查看配置文档,模块功能查看工具
    • /usr/bin/ansible-galxy 下载/上传优秀代码或Roles模块的官网平台
    • /usr/bin/ansible-playbok 定制自动化任务,编排剧本工具
    • /usr/bin/ansible-pul 远程执行命令的工具
    • /usr/bin/ansible-vault 文件加密工具
    • /usr/bin/ansible-console 基于Console界面与用户交互的执行工具

系列命令

  • Ansible系列命令

    • ansible

      此工具通过ssh协议,实现对远程主机的配置管理、应用部署、任务执行等功能
      建议:使用此工具前,先配置ansible主控端能基于密钥认证的方式联系各个被管理节点
      范例:利用sshpass批量实现基于key验证

      1
      2
      3
      4
      5
      6
      ssh-keygen -f /root/.ssh/id_ rsa -P
      NET=192.168.100
      export SSHPASS=kinmfer
      for IP in {1. .200};do
      sshpass -e ssh-copy-id $NET. $IP
      done
    • ansible <host-patern> [-m module_name] [-a args]

      • –version 显示版本
      • -m module 指定模块,默认为comand
      • -v 详细过程 –vv -vvv更详细
      • –list-host 显示主机列表,可简写 –list
      • -k, –ask–pass 提示输入ssh连接密码,默认Key验证
      • -C, –check 检查,并不执行
      • -a, 指定执行模块使用的参数, 必须写上一个合法linux命令信息
      • -T, –timeout=TIMEOUT 执行命令的超时间,默认10s
      • -u, –user=REMOTE_USER 执行远程执行的用户
      • -b, –become 代替旧版的sudo 切换
      • –become-user=USERNAME 指定sudo的run as用户,默认为root
      • -K, –ask-become-pass 提示输入sudo时的口令
      • ansible-doc [options] [module.] : 显示模块帮助
    • -l,-list 列出可用模块

      • -s, -snipet显示指定模块的playbok片段

      示例:

  • ansible-doc -l 列出所有模块

  • ansible-doc ping 查看指定模块帮助用法

    • ansible-doc -s ping 查看指定模块帮助用法

    • ansible-playbok 执行playbook

      示例:ansible-playbook hello.yml

      1
      2
      3
      4
      5
      6
      7
      cat	hello.yml
      #hello world yml file
      - hosts: websrvs
      remote_user: root
      tasks:
      - name: hello world
      command: /usr/bin/wall hello world
    • ansible-vault 管理加密解密yml文件

      • ansible-vault [create|decrypt|edit|encrypt|rekey|view]
    • ansible-vault encrypt hello.yml 加密

      • ansible-vault decrypt hello.yml 解密
      • ansible-vault view hello.yml查看
      • ansible-vault edit hello.yml 编辑加密文件
      • ansible-vault rekey hello.yml 修改口令
      • ansible-vault create new.yml 创建新文件
    • ansible-console 2.0+新增,可交互执行命令,支持tab

      • root@test (2)[f:10] $

        执行用户@当前操作的主 机组 (当前组的主机数量)[f:并发数]$

      • 设置并发数: forks n 例如: forks 10

      • 切换组: cd 主机组 例如: cd web

      • 列出当前组主机列表: list

      • 列出所有的内置命令: ?或help

      • 示例:

        1
        2
        3
        4
        5
        root@all (2)[f:5]$ list
        root@all (2)[f:5] cd appsrvs
        root@appsrvs (2)[f:5] list
        root@appsrvs (2)[f:5] yum name=httpd state=present
        root@appsrvs (2)[f:5] service name=httpd state=started
    • ansible-galxy

    • 列出所有已安装的galaxy

      • ansible-galaxy list

      • 安装galaxy

        • ansible-galaxy install geerlingguy.redis
      • 删除galaxy

      • ansible-galaxy remove geerlingguy.redis

    • ansible-pull 推送命令至远程,效率无限提升,对运维要求较高

  • ansible通过ssh实现配置管理、应用部署、任务执行等功能,建议配置ansible端能基于密钥认证的方式联系各被管理节点

命令执行过程

  • ansible命令执行过程

    1. 加载自己的配置文件 默认/etc/ansible/ansible.cfg

    2. 加载自己对应的模块文件,如command

    3. 通过ansible将模块或命令生成对应的临时py文件,并将该文件传输至远程服务器的对应执行用户$HOME/.ansible/tmp/ansible-tmp-数字/XXX.PY文件

    4. 给文件+x执行

    5. 执行并返回结果

    6. 删除临时py文件,退出

  • 执行状态:

    • 绿色:执行成功并且不需要做改变的操作
    • 黄色:执行成功并且对目标主机做变更
    • 红色:执行失败

主机清单inventory

  • Inventory 主机清单
    ansible的主要功用在于批量主机操作,为了便捷地使用其中的部分主机,可以在inventory file中将其分组命名

  • 默认的inventory file为/etc/ansible/hosts

  • inventory file可以有多个,且也可以通过Dynamic Inventory来动态生成

  • /etc/ansible/host文件格式

  • inventory文件遵循INI文件风格,中括号中的字符为组名。可以将同一个主机同时归并到多个不同的组中;此外,当如若目标主机使用了非默认的SSH端口,还可以在主机名称之后使用冒号加端口号来标明

1
2
3
4
5
6
7
[webservers]
ww1.xxx.com:22
ww2.xxx.com
[dbservers]
db1.xxx.com
db2.xxx.com
db3.xxx.com
  • 如果主机名称遵循相似的命名模式,还可以使用列表的方式标识各主机

    示例:

    1
    2
    3
    4
    [websrvs]
    ww[1:0].example.com
    [dbsrvs]
    db-[a:f].example.com
  • 跟上非标准远程端口

    1
    2
    [websrvs]
    web01:52113
  • 使用特殊的变量

    1
    2
    [websrvs]
    web01 ansible_ssh_host=172.16.1.7 ansible_ssh_port=52113 ansible_ssh_user=root ansible_ssh_pass=123456
  • 嵌入配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    [rsync:children]    --- 嵌入子组信息
    rsync_server
    rsync_client

    [rsync_server]
    172.16.1.41
    [rsync_client]
    172.16.1.31
    172.16.1.7

    [web:vars] --- 嵌入式变量信息
    ansible_ssh_host=172.16.1.7
    ansible_ssh_port=52113
    ansible_ssh_user=root
    ansible_ssh_pass=123456


    [web]
    web01
  • invertory参数:用于定义ansible远程连接目标主机时使用的参数,而非传递给 playbook的变量

    • ansible_ssh_host

    • ansible_ssh_port

    • ansible_ssh_user

    • nsible_ssh_pass

    • ansbile_sudo_pass

    • 示例:

      cat /etc/ansible/hosts [websrvs]

      1.ansible_ssh_user=root ansible_ssh_pass=123123

      2.ansible_ssh_user=root ansible_ssh_pass=123123

  • 更多配置方法

    https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html

Host-pattern

  • ansible的Host-patern
    匹配主机的列表
    • all :表示所有Inventory中的所有主机
      ansible all –m ping
    • * :通配符
      ansible “*” -m ping
      ansible 192.168.1* -m ping
      ansible “*srvs” -m ping
    • 或关系
      ansible “websrvs:apsrvs” -m ping
      ansible “192.168.10:192.168.120” -m ping
    • 逻辑与
      ansible “websrvs:&dbsrvs” –m ping
      在websrvs组并且在dbsrvs组中的主机
    • 逻辑非
      ansible ‘websrvs:!dbsrvs’ –m ping
      在websrvs组,但不在dbsrvs组中的主机
      注意:此处为单引号
    • 综合逻辑
      ansible ‘websrvs:dbsrvs:&apsrvs:!ftpsrvs’ –m ping
    • 正则表达式
      ansible “websrvs:&dbsrvs” –m ping
      ansible “~(web|db).*\kinmfer\.com” –m ping

使用实例

  • 以king用户执行ping存活检测

    ansible all -m ping -u king -k

  • 以king sudo至root执行ping存活检测

    ansible all -m ping -u king -k -b

  • 以king sudo至k1用户执行ping存活检测

    ansible all -m ping -u king -k -b --become-user=k1

  • 以king sudo至root用户执行ls

    ansible all -m command -u king -a 'ls /root' -b --become-user=root -k -K

常用模块

  • 模块文档:

    https://docs.ansible.com/ansible/latest/modules/modules_by_category.html

  • Command:在远程主机执行命令,默认模块,可忽略-m选项

    简单用法:

    1
    2
    3
    [root@m01 scripts]# ansible 172.16.1.31 -m command -a "hostname"
    172.16.1.31 | CHANGED | rc=0 >>
    nfs01

    扩展应用:

    1. chdir 在执行命令之前对目录进行切换
      ansible 172.16.1.31 -m command -a "chdir=/tmp touch xxx.txt"

    2. creates 如果文件存在了,不执行命令操作

    ansible 172.16.1.31 -m command -a "creates=/tmp/hosts touch xxx.txt"

    1. removes 如果文件存在了, 这个步骤将执行
      ansible 172.16.1.31 -m command -a "removes=/tmp/hosts chdir=/tmp touch xxx.txt"
    2. free_form(required)
      The command module takes a free form command to run.
      There is no parameter actually named ‘free form’. See the examples!
    • 此命令不支持 $VARNAME < > | ; & 等,用shell模块实现
  • Shell:和command相似,用shell执行命令

    • ansible srv -m shell -a ‘echo 123123|passwd –stdin kinmfer’

    • 调用bash执行命令类似 cat /tmp/stanley.md | awk -F‘|’ ‘{print $1,$2}’ &> /tmp/example.txt 这些复杂命令,即使使用shell也可能会失败,解决办法:写到脚本时,copy到远程,执行,再把需要的结果拉回执行命令的机器

    • 修改默认模块

      1
      2
      [root@ansible ~]#vim /etc/ansib1e/ansible.cfg
      module_name = shell
  • Script:在远程主机上运行ansible服务器上的脚本

    • -a “/PATH/TO/SCRIPT_FILE“

    • ansible websrvs -m script -a /data/test.sh

  • Copy:从主控端复制文件到远程主机

    • ansible srv -m copy -a “src=/root/test1.sh dest=/tmp/test2.sh owner=wang mode=600 backup=yes”

      如目标存在,默认覆盖,此处指定先备份

    • ansible srv -m copy -a “content='test content\n' dest=/tmp/test.txt” 指定内容,直接生成目标文件

  • Fetch:从远程主机提取文件至主控端,copy相反,目前不支持目录

    ansible srv -m fetch -a ‘src=/root/test.sh dest=/data/scripts’

  • File:设置文件属性

    • state 参数

      • absent — 缺席/删除数据信息
      • directory — 创建一个目录信息
      • file — 检查创建的数据信息是否存在 绿色存在 红色不存在
      • hard — 创建一个硬链接文件
      • link — 创建一个软链接文件
      • touch — 创建一个文件信息
    • ansible srv -m file -a "path=/root/test.sh owner=kinmfer mode=755“

    • ansible srv -m file -a "path=/data/testdir state=directory"

    • ansible srv -m file -a ‘src=/data/testfile dest=/data/testfile-link state=link’

  • unarchive:解包解压缩,有两种用法:

    1、将ansible主机上的压缩包传到远程主机后解压缩至特定目录,设置copy=yes.

    2、将远程主机上的某个压缩包解压缩到指定路径下,设置copy=no

    常见参数:

    • copy:默认为yes,当copy=yes,拷贝的文件是从ansible主机复制到远程主机上,如果设置为copy=no,会在远程主机上寻找src源文件

    • src:源路径,可以是ansible主机上的路径,也可以是远程主机上的路径,如果是远程主机上的路径,则需要设置copy=no

    • dest:远程主机上的目标路径

    • mode:设置解压缩后的文件权限

    • 示例:

      • ansible srv -m unarchive -a 'src=foo.tgz dest=/var/lib/foo'

      • ansible srv -m unarchive -a 'src=/tmp/foo.zip dest=/data copy=no mode=0777'

      • ansible srv -m unarchive -a 'src=https://example.com/example.zip dest=/data copy=no'

  • Archive:打包压缩

    ansible all -m archive -a 'path=/etc/sysconfig dest=/data/sysconfig.tar.bz2 format=bz2 owner=king mode=0777'

  • Hostname:管理主机名

    ansible node1 -m hostname -a “name=websrv”

  • Cron:计划任务

    支持时间:minute,hour,day,month,weekday

    • job 用于定义定时任务需要干的事情

    • disabled 用于批量注释任务

    • ansible srv -m cron -a “minute=*/5 job=‘/usr/sbin/ntpdate 172.16.0.1 &>/dev/null’ name=Synctime” 创建任务

    • ansible srv -m cron -a ‘state=absent name=Synctime’ 删除任务

    • ansible srv -m cron -a "name='time sync' job='/usr/sbin/ntpdate ntp1.aliyun.com >/dev/null 2>&1' disabled=yes" 批量注释任务

  • Yum:管理包

    • name — 指定安装软件名称

    • state — 指定是否安装软件

      • installed — 安装软件
      • present
      • latest
      • absent — 卸载软件
    • ansible srv -m yum -a ‘name=httpd state=present’ 安装

    • ansible srv -m yum -a ‘name=httpd state=absent’ 删除

  • mount:挂载服务

    • src: 需要挂载的存储设备或文件信息
    • path: 指定目标挂载点目录
    • fstype: 指定挂载时的文件系统类型
    • state
      • present/mounted — 进行挂载
      • present: 不会实现立即挂载,修改fstab文件,实现开机自动挂载
      • mounted: 会实现立即挂载, 并且会修改fstab文件,实现开机自动挂载
      • absent/unmounted — 进行卸载
      • absent: 会实现立即卸载, 并且会删除fstab文件信息,禁止开机自动挂载
      • unmounted: 会实现立即卸载, 但是不会删除fstab文件信息
  • Service:管理服务

    • name: — 指定管理的服务名称

    • state: — 指定服务状态

      • started 启动
      • restarted 重启
      • stopped 停止
      • reloaded 重载
    • enabled — 指定服务是否开机自启动

    • ansible srv -m service -a 'name=httpd state=stopped'

    • ansible srv -m service -a 'name=httpd state=started enabled=yes'

    • ansible srv -m service -a 'name=httpd state=reloaded’

    • ansible srv -m service -a 'name=httpd state=restarted'

  • User:管理用户

    • ansible srv -m user -a 'name=user1 comment=“test user” uid=2048 home=/app/user1 group=root groups=xxx shell=xxx create_home=no‘

    • ansible srv -m user -a 'name=sysuser1 system=yes home=/app/sysuser1 ’

    • ansible srv -m user -a ‘name=user1 state=absent remove=yes‘ 删除用户及家目录等数据

  • Group:管理组

    • ansible srv -m group -a "name=testgroup system=yes“

    • ansible srv -m group -a "name=testgroup state=absent"

  • Lineinfile

    ansible在使用sed进行替换时,经常会遇到需要转义的问题,而且ansible在遇到特殊符号进行替换时,存在问题,无法正常进行替换.其实在ansible自身提供了两个模块: lineinfile模块和replace模块, 可以方便的进行替换
    功能:相当于sed,可以修改文件内容

    • ansible all -m lineinfile -a "path=/etc/selinux/config regexp= '^SELINUX=' line='SELINUX=enforcing'"

    • ansible all -m lineinfile -a 'dest=/etc/fstab state=absent regexp="^#"'

  • Replace

    该模块有点类似于sed命令,主要也是基于正则进行匹配和替换

    • ansible all -m replace -a "path=/etc/fstab regexp= '^(UUID.*)' replace= '#\1'"
  • Setup

    功能: setup 模块来收集主机的系统信息,这些facts信息可以直接以变量的形式使用,但是如果主机较多,会影响执行速度,可以使用gather_facts: no来禁止Ansible收集facts信息

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    ansible srv -m setup
    ansible srv -m setup -a "filter=ansible_nodename"
    ansible srv -m setup -a "filter=ansible_hostname "
    ansible srv -m setup -a "filter=ansible_domain"
    ansible srv -m setup -a "filter=ansible_memtotal_mb"
    ansible srv -m setup -a "filter=ansible_memory_mb"
    ansible srv -m setup -a "filter=ansible_memfree_mb"
    ansible srv -m setup -a "filter=ansible_os_family"
    ansible srv -m setup -a "filter=ansible_distribution_major_version'
    ansible srv -m setup -a "filter=ansib1e_distribution_version"
    ansible srv -m setup -a "filter=ansible_processor_vcpus"
    ansible srv -m setup -a "filter=ansible_al1_ipv4_addresses"
    ansible srv -m setup -a "filter=ansible_architecture"