zoukankan      html  css  js  c++  java
  • 运维简介&Ansible详解

    1. 运维工作简介

    1.1 运维简述

    1.1.1 运维工作

    • 运维工作的核心任务:
      • 发布、变更、故障处理
    • 系统安装(物理机、虚拟机)--> 程序包安装、配置、服务启动 --> 批量操作 --> 程序发布 --> 监控
      • 系统安装(物理机、虚拟机)
      • 程序安装、配置、服务启动
      • 批量操作(批量运行命令)
      • 程序发布
      • 监控

    预发布验证:

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

    程序发布:

    • 不能影响用户体验
    • 系统不能停机
    • 不能导致系统故障或造成系统完全不可用

    1.1.2 灰度发布

    发布路径:

    • /webapp/tuangou-1.1
    • /web/app/tuangou
    • /webapp/tuangou-1.2

    在调度器上下线一批主机(maintanance) --> 关闭服务 --> 部署新版本的应用程序 --> 启动服务 --> 在调度器上启用这一批服务器

    1. 通过调度器将线上的一批服务器标记为down模式(软关闭,比如将权重调为0)(maintanance)
    2. 关闭相应服务
    3. 部署新版本的应用程序至目标位置
    4. 启动相关应用
    5. 调度主机上线

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

    • 灰度发布:
      • 基于主机
      • 基于用户

    一些专业名词:

    • CI:持续集成
    • CD:持续交付
    • CD:持续部署
    • 以上三个过程如果能够串联起来自动执行,就叫:DevOps

    1.1.3 运维工具的分类

    • agent:
      • puppet、func
    • agentless:
      • ansible、fabric
      • ssh

    1.1.4 监控工具

    不允许没有被监控的系统上线

    • 监控数据采集:
      • 用户行为日志
      • 服务器性能
      • 运行数据报告
    • 监控管理:
      • 异常报警
      • 失效转移
      • 自动优雅降级

    1.1.5 运维工具的层次

    1. OS Provisioning:系统安装
      • 物理机:PXE、Cobbler
      • 虚拟机(云环境下):Image、Templates
    2. Configuration:
      • puppet(ruby)
      • saltstack(python)
      • chef
      • cfengine
    3. Command and Control:
      • func
      • ansible(python)
      • fabric

    1.1.6 运维工具图示

    1.2 持续集成、持续交付、持续部署

    1.2.1 集成、部署、交付

    集成:

    • 指软件个人研发的部分向软件整体部分交付,以便尽早发现个人开发部分的问题

    部署:

    • 代码尽快向可运行的开发/测试环节交付,以便尽早测试

    交付:

    • 指研发尽快向客户交付,以便尽早发现生产环节中存在的问题
    • 如果等到所有东西都完成了才向下个环节交付,导致所有的问题只能在最后才爆发出来,解决成本巨大

    持续:

    • 每完成一个完整的部分,就向下个环节交付,发现问题可以马上调整,问题不会放大到其他部分和后面的环节

    1.2.2 CI、CD

    持续集成(CI):

    • 开发人员提交了新代码之后,立刻进行构建、(单元)测试
    • 根据测试结果,我们可以确定新代码和原有代码能否正确的集成在一起

    持续交付(CD):

    • 在持续集成的基础上,将集成后的代码部署到更贴近真实运行环境中(类生产环境)
    • 如果代码没问题,可以继续手动部署到生产环境中

    持续部署(CD):

    • 在持续交付的基础上,把部署到生产环境的过程自动化

    2. Ansible简介&模块详解

    2.1 Ansible的安装&基本结构

    2.1.1 ansible简介

    • 模块化,调用特定的模块,完成特定的任务
    • 基于python语言实现,由Paramiko、PyYAML和Jinja2三个关键模块
    • 部署简单,agentless
    • 主从模式
    • 支持自定义模块
    • 支持Playbook
    • 幂等性

    2.1.2 ansible的安装

    • 安装:直接yum安装(epel、ansible)
    • 配置文件:
      • 配置文件:/etc/ansible/ansible.cfg
      • 主机清单:/etc/ansible/hosts
        • 在这个文件中定义要控制的主机
    • 主程序:
      • ansible
      • ansible-playbook
      • ansible-doc

    2.1.3 ansible的使用

    准备操作:

    1. ansible在使用前要先在/etc/ansible/hosts中定义要控制的主机
    2. 还要将Ansible Server的ssh公钥分发到各被管控节点上:
      • ssh-keygen  -t  rsa  -f  ~/.ssh/id_rsa  -N ""
      • ssh-copy-id  root@10.0.0.205
      • ssh-copy-id  root@10.0.0.206
      • ssh-copy-id  root@10.0.0.207
      • ssh-copy-id  root@10.0.0.208
    3. 然后就可以在主控server上进行控制了

    ansible的简单使用格式:

    • ansible  HOST-PATTERN  -m  MOD_NAME  -a  MOD_ARGS    -f   FORKS  -C  -u   USERNAME 
      • -m:指明模块
      • -a:指明调用的模块参数
      • -f:一批管控多少主机,这里的FORKS也可以在/etc/ansible/ansible.cfg文件中定义,可以将这个值改大点
      • -C:--check,干跑,而不真正执行
      • -u:指明用户名
      • -c:指明连接方式,默认是smart,自动选择
    • 使用示例:
      • ansible 10.0.0.207 -m ping
        • 测试10.0.0.207主机的连通性
      • ansible all -m ping
        • 测试在/etc/ansible/hosts中定义的所有主机的连通性

    ansible的工作图示:

    2.2 Ansible常用模块详解

    2.2.1 获取模块列表

    • ansible-doc -l
      • 列出ansible所有支持的模块
    • ansible-doc -s GROUP_NAME
      • 查看对应模块的用法说明,例如ansible-doc -s group 查看group模块的用法说明
    • ansible使用要点:
      • 定义所期望的目标状态
      • 操作必须是幂等的(所谓幂等就是指重复数次的结果是相同的)

    2.2.2 group

    • 作用:
      • 管理用户组
    • 模块参数:
      • name=指定该用户组的组名
      • gid=指定该用户组的gid
      • system=指定该组是否为系统组,yes表示是,no表示不是系统组
      • state=指定目标状态,present表示要创建出来,absent就表示要删除它
    • 使用示例:
      • 创建一个gid为3000的名叫mygrp的非系统组
        • ansible all -m group -a "gid=3000 name=mygrp state=present system=no"
      • 删除刚刚创建的那个组:
        • ansible all -m group -a "gid=3000 name=mygrp state=absent system=no"

    2.2.3 user

    • 作用:
      • 管理用户账号
    • 模块参数:
      • name=指定用户名
      • uid=指定用户uid
      • group=指定用户的主组
      • groups=指定用户的附加组
      • home=指定用户家目录
      • shell=指定用户登录的shell
      • comment=指定对该用户的描述
      • system=指定用户是否为系统用户yes或者no
      • state=present或者absent
    • 使用示例:
      • ansible all -m user -a "uid=5000 name=mytestuser state=present groups=mygrp shell=/bin/bash"

    2.2.4 copy

    • 作用:
      • 复制文件
      • 从本机到目标主机,或者从远程主机到目标主机
    • 模块参数:
      • dest=指定的目标路径,如果源是一个目录,则目标必须是目录
      • src=指定的源路径,如果源是目录,则默认就会做递归复制,这里如果结尾带了/ 则表示只复制目录中的内容,不带斜线则表示复制所有
      • remote_src=可以指定远程的源路径
      • owner=指定目标文件的属主
      • group=指定目标文件的属组
      • mode=指定目标文件的权限
      • content=不使用src拷贝文件时,使用content直接指定文件内容(src和content必须有其一)
    • 注意:
      • 如果不指定属主属组,它是默认不变的,以哪个用户复制就以哪个用户来生成,
      • 如果自己指明用户,要确保目标主机存在那个用户
    • 使用示例:
      • ansible all -m copy -a "src=/etc/fstab dest=/tmp/fstab mode=600"
      • 也可以使用content生成文件:
        • ansible all -m copy -a "content='hello world ' dest=/tmp/hello.txt"

    2.2.5 fetch

    • 作用:
      • 从远程主机上复制文件到本地
    • 使用参数:
      • dest=指定目标路径
      • src=指定源路径
      • fail_on_missing 远程主机如果没有文件则报错退出(在ansible2.4中已经默认就是yes了)
    • 拉取过来之后会在本地保存成一个嵌套目录:
      • ansible 10.0.0.205 -m fetch -a "src=~/test.txt dest=/tmp/"
      • 在本地存储为:/tmp/10.0.0.205/root/test.txt

    2.2.6 command

    • 作用:
      • 直接在远程主机上执行命令
    • 注意:
      • 对于这个模块,-a中的命令不用写成键值对形式,直接指定命令即可
      • command模块使用时,-a中引号内的内容不使用shell来解析,所以要指明shell来解析(貌似指明了executable也没用)
    • 使用参数:
      • chdir=切换到指定的目录下去执行命令
        • 注意:chdir不是幂等的,也就是说执行成功之后再执行就会失败
      • executable=由哪个shell命令发起执行程序,可以指明一个新的shell
    • 使用示例:
      • 在每个远程主机上执行ifconfig命令:
        • ansible all -m command -a "ifconfig"
      • 切换目录后执行命令:
        • ansible all -m command -a "chdir=/tmp mkdir hello.dir"

    2.2.7 shell

    • 作用:
      • 真正的执行shell命令的模块,可以识别命令行中的众多字符
    • 注意:
      • 这个模块可以实现众多真正shell命令行中的功能
      • 使用参数及用法与command相同
    • 识别shell命令行中的元字符的两种方法:
      • ansible 10.0.0.205 -m shell -a "/bin/bash -c  'ls -alh /tmp/wzhhg'"
      • ansible 10.0.0.205 -m shell -a "executable=/bin/bash  ls -alh /tmp/wzhhg"

    2.2.8 file

    • 作用:
      • 创建文件,真正意义上来说是修改文件属性的
    • 使用示例:
      • 在指定的路径下创建一个目录:
        • ansible all -m file -a "path=/tmp/testhello.dir state=directory"
      • 在指定的路径下创建一个文件:
        • ansible all -m file -a "path=/tmp/testhello.txt state=file"
      • 创建一个符号链接文件:
        • ansible all -m file -a "src=/tmp/fstab path=/tmp/fstab.link state=link"

    2.2.9 cron

    • 作用:
      • 定义任务计划
    • 使用参数:
      • day=、hour=、minute=、month=、weekday= 指定的间隔时间,默认使用的是*,为空表示是*
      • name=指明任务的名称,如果不指定名字,默认为None,删除的时候要指定名字,否则删不掉
      • user=任务为哪个用户的
      • state=任务是添加还是删除,present表示添加,absent表示删除,如果不写,默认就是present
      • job=指明任务
    • 使用示例:
      • 每隔3分钟同步一次时间:(这里虽好指定name,以便以后方便调用)
        • ansible all -m cron -a "minute=*/3  job='/usr/sbin/update 10.0.0.203 &> /dev/null'"
      • 删除刚刚添加的任务:
        • ansible all -m cron -a "minute=*/3 job='/usr/sbin/update 10.0.0.203 &> /dev/null' name=None state=absent"

    2.2.10 yum

    • 作用:
      • 安装程序包
    • 使用参数:
      • name=指明程序包名
      • state=安装还是卸载,present、installed、latest都表示安装,absent、removed表示卸载
      • disable_gpg_check:安装的过程中禁用密钥检测
      • disablerepo=指明安装过程中禁用的某个仓库
      • enablerepo=指明安装过程中开启的某个仓库
    • 使用示例:
      • 安装httpd包:ansible all -m yum -a "name=httpd  state=installed"

    2.2.11 service

    • 作用:
      • 管理服务
    • 使用参数:
      • name=指明服务命令,如果是CentOS7可以不用加.service
      • enabled=是否设置为开机自启动,yes或者no
      • runlevel=在哪些级别下开机自启动
      • state=服务是启动还是关闭,started表示启动,stopped表示关闭,restarted表示重启,reloaded表示平滑重载
      • pattern=指明的匹配格式,如果匹配到了这里指定的字符串就表示成功
    • 使用示例:
      • 启动nginx服务:ansible all -m service -a "name=nginx state=started"

    2.2.12 script

    • 作用:
      • 执行脚本,自动把本地的脚本复制到远程主机上,并在远程主机上执行
    • 使用参数:
      • 直接指明脚本
    • 使用示例:
      • 将脚本复制到远程主机上并执行脚本
        • ansible all -m script -a "/tmp/test.sh"

    2.2.13 ping

    • 使用示例:
      • ansible all -m ping --list-hosts
    • 注意:
      • 这里使用all表示ansible的hosts文件中定义的所有主机,这里也可以直接指定主机,或者用正则表达式匹配
      • 这里使用--list-hosts可以列出适配出来的主机,不真正执行

    3. Ansible之playbook详解

    3.1 playbook简介

    3.1.1 YAML格式简介

    • 让每一台主机要执行的任务保存在一个文件中,这个文件组织成YAML格式
    • YAML:是一个可读性高,用来表达数据序列的格式,它其实是一种标记语言
    • Playbook:YAML格式,任务(task)
    • 基本数据结构:
      • 标量、数组、关联数组

    3.1.2 Playbook的核心元素

    • Hosts:主机(谁负责来唱这出戏)
    • Tasks:任务列表(要唱哪几出戏)
    • Variables:变量
    • Templates:包含了模板语法的文本文件
    • Handlers:由特定条件触发的任务,要触发handlers,只需要在某个任务上加上notify
    • Roles:角色

    3.1.3 playbook的基础组件

    • hosts:运行指定任务的目标主机
    • remote_user:在远程主机上执行任务的用户(在目标主机上以哪种用户的身份执行命令)
      • sudo_user:sudo到哪个用户去执行
    • tasks:任务列表
      • 模块,模块参数
      • 格式:
        • action:module arguments
        • module:arguments
        • 注意:shell和command模块后面直接跟命令,而非键值对的参数列表

    3.1.4 运行playbook的方式

    测试操作:

    • ansible-playbook --check
      • 只检测可能会发生的改变,但不真正执行操作,干跑
    • ansible-playbook --list-hosts
      • 列出运行任务的主机
    • ansible-playbook --syntax-check:
      • 检查语法,真正的检查语法

    ansible-playbook:

    • -C:--check,检查语法,这里是干跑一遍
    • --list-hosts:列出相关主机
    • --list-tasks:列出所有任务
    • --list-tags:列出所有标签
    • --syntax-check:检查语法

    特别注意:

    • 如果有一个任务在某一主机上停止了,则所有任务在所有主机上都无法完成
    • 它是按任务分派给所有主机,先执行第一个,再执行第二个,再执行第三个,一次类推

    3.2 playbook文件详解

    3.2.1 定义playbook文件

    - hosts: all
      remote_user: root           # 以什么用户去执行任务
      tasks:                      # 指定任务列表
        - name: install redis
              yum: name=redis state=latest
        - name: copy config file
              copy: src=/root/playbooks/redis.conf dest=/etc/redis.conf
              notify: restart redis   # 触发名称为restart redis的任务,该任务在handlers中定义 
              tags: configfile        # 这里对该任务加上了名为configfile的标签
        - name: start redis
              service: name=redis state=started enabled=true
      handlers:
            - name: restart redis
              service: name=redis state=restarted

    注意:

    • handlers只会在所有任务执行完成后执行。而且即使被通知了很多次,它也只会执行一次

    后续操作:

    • 然后语法检查:
      • ansible-playbook --syntax-check first.yaml
    • 然后干跑一遍:
      • ansible-playbook -C first.yaml
    • 然后直接执行:
      • ansible-playbook first.yaml

    定义标签:

    • 可以在playbook的yaml配置文件中的特定任务中加上一个标签,然后在执行时只调用这一个标签
    • 使用:ansible-playbook -t configfile second.yaml 这里是只执行加上了configfile标签的任务

    3.2.2 handlers简介

    • 作用:任务,特定条件下触发的任务
    • 说明:收到其他任务的通知时被触发:
      • 如:notify: restart redis , 触发名称为restart redis的任务,该任务在handlers中定义
    • handlers只会在所有任务执行完成后执行,而且即使被通知了很多次,它也只会执行一次

    3.2.3 variables详解

    1) facts:可直接调用的变量

    • 说明:可以使用setup模块直接获取目标主机的facters
    • setup模块:
      • 作用:用来收集每一个被ansible管控的主机之上相关的环境变量
      • 使用:ansible 10.0.0.206 -m setup
      • 查看用法:ansible-doc -s setup
    • 在yaml文件中调用变量:(将变量置于双花括号内以调用)
      • - hosts: all
          remote_user: root  
          tasks:                  
          - name: copy file
                copy: content={{ ansible_env }} dest=/tmp/ansible.env  # 双花括号以调用变量

    2) ansible-playbook命令的命令行中自定义变量

    • 在yaml文件中定义:
      • - hosts: all
          remote_user: root
          tasks:
                - name: install {{ pkgname }}
                  yum: name={{ pkgname }} state=latest 
    • 在命令行中使用-e参数进行传递变量:
      • ansible-playbook  -e  pkgname=memcached   forth.yaml    将memcached赋值给变量package

    3) Host Inventory

    用户自定义变量:

    • 向不同的主机传递不同的变量:(在ansible的hosts文件中定义)
      • 格式:IP/HOSTNAME varaiable=value var2=value2
      • 示例:
        [websrvs]
        172.16.0.67  http_port=8080  my_num=10080 # 添加两个自定义变量
        172.16.0.68
      • 说明:
        • 这里定义的变量在playbook当中(也就是yaml文件中)是可以直接引用的
        • 这里定义的值在模板中也是可以直接变量引用的
    • 向组中的主机传递相同的变量:(在ansible的hosts文件中定义)
      • 格式:
        • [ groupname:vars ]
        • variable=value
      • 示例:
        [websrvs]
        172.16.0.67  
        172.16.0.68
        
        [websrvs:vars]
        http_port=8080  
        my_num=10080  
        # 表示在websrvs组中的所有主机上都定义上这里面所定义的两个变量

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

    • 定义的位置:直接写在ansible的hosts文件中远程主机的IP地址后面
      • ansible_ssh_host=使用远程主机另外的地址来连接
      • ansible_ssh_prot=使用其他的端口来连接远程主机
      • ansible_ssh_user=使用其他的用户登录,不写默认是root
      • ansible_ssh_pass
      • ansible_sudo_pass
    • 使用示例:
      • 172.16.0.67 ansible_ssh_port=22122 ansible_ssh_user=hgzero

    3.2.4 templates模板

    说明:文本文件,嵌套有脚本(使用模板编程语言编写)

    Jinja2:

    • 字面量:
      • 字符串:使用单引号或者双引号
      • 数字:整数,浮点数
      • 列表:[ item1, item2, ...]
      • 元组:( item1, tiem2, ...)
      • 字典:{ key1:value, key2:value, ...}
      • 布尔型:true/false
    • 算术运算:
      • +, -, *, / , //, %, **
    • 比较运算:
      • ==, !=, >, >=, <, <=
    • 逻辑运算:
      • and,or,not

    template模块:基于模板方式生成一个文件复制到远程主机

    • 使用参数:
      • src=模板文件
      • dest=基于模板生成以后的数据流,保存下来生成一个文件
      • owner=属主
      • group=属组
      • mode=权限

    在配置文件中内嵌一个变量:

    • vim /root/playbooks/redis.conf.j2
      • bind {{ ansible_eno16777736.ipv4.address }}
      • 说明:可以用点号调用某个变量一个子集下的一个子集...
    • 在yaml文件中定义:
      - hosts: 172.16.0.67
        remote_user: root
        tasks:
              - name: install config file
                template: src=/root/playbooks/redis.conf.j2  dest=/tmp/redis.conf

    3.3 playbook高级用法

    3.3.1 条件测试

    • when语句:在task中使用,jinja2的语法格式
    • 示例:
      - hosts: websrvs
        remote_user: root
        tasks:
        - name: install httpd
          yum: name=httpd state=latest
              when: ansible_os_family == "RedHat"  # 可以用when关键字对变量进行判断
        - name: install apache2
          apt: name=apache2 state=latest
              when: ansible_os_family == "Debian"

    3.3.2 循环、迭代操作

    • 使用:
      • 需要重复执行的任务,对迭代项的应用,固定变量名为"item"
      • 而后,要在task中使用with_items给定要迭代的元素列表
    • 列表方法:
      • 字符串迭代:
        - name: install {{ item}} package
          yum: name={{ itme }} state=present # 迭代with_items中的每个字符串
          with_items:
          - nginx
          - memcached
          - php-fpm
      • 字典迭代:
        - name: add some users
          user: name={{ item.name }} group={{ item.group }} state=present # 迭代with_items中的每个字典
          with_items:
          - { name: 'user11', group: 'group11' }
          - { name: 'user12', group: 'group12' }
          - { name: 'user13', group: 'group13' }

    4. Ansible之role角色详解

    4.1 角色(roles)简介

    1) 描述:自包含的所需要的各种文件的集合

    2) 角色的集合

    roles/
            mysql/
            httpd/
            nginx/
            memcached/

    3) 每个角色,以特定的层级目录结构进行组织(至少要有一个task,其他都是可选的)

    mysql/
            files/:存放由copy或script模块等调用的文件
            templates/:template模块查找所需要模板文件的目录
            tasks/:至少应该包含一个名为main.yml的文件,其他的文件需要在此文件中通过include进行包含
            vars/:至少应该包含一个名为main.yml的文件,其他的文件需要在此文件中通过include进行包含
            meta/:至少应该包含一个名为main.yml的文件,定义当前角色的特殊设定及其依赖关系
                                 其他的文件需要在此文件中通过include进行包含
            default/:设定默认变量时使用此目录中的main.yml文件
    • 注意:ansible的role的存放位置:应该放在/etc/ansible/ansible.cfg中指定的路径中

    4.2 创建角色

    1) 创建基本角色目录集:

    • mkdir  -pv  /etc/ansible/roles/nginx/{files,templates,tasks,vars,handlers,meta,default}

    2) 编辑创建工作任务tasks文件:

    vim  /etc/ansible/roles/nginx/tasks/main.yml
            - name: install nginx
              yum: name=nginx state=latest
              when: ansible_os_family == "RedHat"
            - name: install conf
              template: src=vhost1.conf.j2  dest=/etc/nginx/conf.d/vhost1.conf
              tags: conf                # 为配置任务打个标签
              notify: restart nginx     # 触发handlers中定义的restart nginx
            - name: install site home directory
              file: path={{ ngxroot }} state=directory   # 这里调用的变量被定义在了vars目录下
            - name: install index page
              copy: src=index.html  dest={{ ngxroot }}/
            - name: start nginx
              service: name=nginx state=started

    3) 编辑创建模板templates文件:

    vim roles/nginx/templates/vhost1.conf.j2
            server {
                    listen 8080;
                    server_name {{ ansible_fqdn }};
                    location  /  {
                            root  "/ngin"
                    }
            }

    4) 编辑创建handlers文件:

    vim roles/nginx/handlers/main.yml   
            - name: restart nginx      # 这里定义的内容会被notify触发
            service: name=nginx state=restarted

    5) 编辑创建变量vars文件:

    vim roles/nginx/vars/main.yml
            ngxroot: /ngxdata/vhost1   # 定义变量要用字典的格式,是yaml格式的字典

    6) 编辑创建files文件:

    vim  roles/nginx/files/index.html
            <h1>Vhost1</h1>

    7) 编辑创建主执行文件:

    vim  nginx.yml
            - hosts: websrvs
              remote_user: root
              roles:
              - nginx

    8) 执行:

    • 直接执行:
      • ansible-playbook nginx.yml
    • 只修改配置文件:
      • ansible-playbook -t conf nginx.yml
  • 相关阅读:
    leetcode_question_67 Add Binary
    几种常用控件的使用方法
    JavaBean讲解 规范
    [置顶] JDK-CountDownLatch-实例、源码和模拟实现
    恋人分手后需要做的不是挽回而是二次吸引
    leetcode_question_70 Climbing Stairs
    偶然碰到的Win7 64位下CHM 的问题解决
    FTP中各文件目录的说明
    深入理解line-height与vertical-align(1)
    行内元素和块级元素
  • 原文地址:https://www.cnblogs.com/hgzero/p/13172324.html
Copyright © 2011-2022 走看看