menu 学习笔记
search self_improvement
目录

自动化运维工具 Ansible 学习笔记(三):Ansible Playbook

huty
huty 2022年11月24日  ·  阅读 1,377

参考博客(平台:博客园 作者:珂儿吖):

功能

自动执行某项自定义的任务,如批量安装中间件、自动更新等。

组成

一个 Ansible Playbook 由以下部分组成:

  • hosts 文件 :用于指定执行任务的主机(对应 Ansible 的 hosts 文件)
  • playbook.yml 文件:Ansible Playbook 的 Roles 文件,用于指定需要执行的任务(单项或多项)
  • roles 文件夹:用于保存需要执行的 Ansible Playbook 脚本
    • role 文件夹:用于保存某项任务需要执行的具体脚本(文件夹名称通常见名知意)
      • defaults 文件夹 :指定此项任务的默认值
        • main.yml 文件:指定此项任务的默认值
      • vars 文件夹 :指定此项任务的参数
        • main.yml 文件:指定此项任务的参数
      • tasks 文件夹 :指定此项任务的指令
        • main.yml 文件:指定此项任务的指令
      • handlers 文件夹 :指定此项任务的触发器
        • main.yml 文件:指定此项任务的触发器
      • templates 文件夹 :此项任务需要使用的模板文件
      • files 文件夹 :此项任务需要使用的资源文件
      • meta 文件夹 :指定此项任务的特殊设定及其依赖关系
        • main.yml 文件:指定此项任务的特殊设定及其依赖关系

image

语法

hosts 文件

# 注释
[主机组名称]
主机1
主机2
......

示例如下:

[docker]
192.168.10.100
192.168.10.101
192.168.10.102

playbook.yml 文件

---
# 注释
- hosts: 主机组名称
  remote_user: 执行命令的用户名
  become: yes
  gather_facts: yes
  roles:
  - role: role文件夹名称

示例如下:

---
# 安装与运行 Docker 服务
- hosts: docker
  remote_user: root
  become: yes
  gather_facts: yes
  roles:
  - role: docker

参数 yml 文件

--
# 注释
参数1名称: 参数1值
参数2名称:
  参数2-1名称: 参数2-1值

示例如下:

--
# 安装与运行 Docker 服务的参数
type: x86_64
docker:
  package: docker-20.10.21.tgz

指令( tasks ) yml 文件

---
# 注释
- name: 指令名称
  模块名称: 模块指令

示例如下:

---
# 安装与运行 Docker 服务的指令
- name: 'Shell 测试'
    shell: ll /root

注:关于 Ansible 的模块说明,见:https://hty1024.com/archives/zi-dong-hua-yun-wei-gong-ju-ansible-xue-xi-bi-ji--er--chang-yong-ming-ling-ji-mo-kuai-shuo-ming

示例

使用 Ansible Playbook 安装和卸载 Docker 和 Docker Compose 服务

  1. 编辑 host 文件
vim /etc/ansible/hosts
[docker]
192.168.10.101
192.168.10.102
192.168.10.103
  1. 编辑 docker.yml 文件
vim /etc/ansible/roles/docker.yml
- hosts: docker
  remote_user: root
  become: yes
  gather_facts: yes
  tags:
    - docker
  roles:
  - role: docker
  1. 编辑 defaults/main.yml 文件
vim /etc/ansible/roles/docker/defaults/main.yml
--
flag: ~/.flag/{{ role_name }}
docker:
  package: docker-20.10.21.tgz
    dir:
      main: '/opt/docker'
      bin: '/opt/docker/bin'
      data: '/optdocker/data'
  1. 编辑 tasks/main.yml 文件
vim /etc/ansible/roles/docker/tasks/main.yml
---
- name: '<{{ cmd | upper }}> |  校验 Docker 是否安装'
  shell: |
    . /etc/profile
    docker info
  register: docker_ret
  ignore_errors: true

- name: '<{{ cmd | upper }}> |  校验 Docker Compose 是否安装'
  shell: |
    . /etc/profile
    docker-compose version
  register: compose_ret
  ignore_errors: true

- block:
  - name: '<{{ cmd | upper }}> |  编辑 ~/.bashrc 文件'
    blockinfile:
      path: ~/.bashrc
      block: |
        export DOCKER_HOME={{ docker.dir.bin }}
        export PATH=$PATH:$DOCKER_HOME
      marker: '#{mark} DOCKER Environment'
      insertbefore: 'BOF'

  - name: '<{{ cmd | upper }}> |  编辑 /etc/profile 文件'
    blockinfile:
      path: /etc/profile
      block: |
        export DOCKER_HOME={{ docker.dir.bin }}
        export PATH=$PATH:$DOCKER_HOME
      marker: '#{mark} DOCKER Environment'
      insertafter: 'EOF'

  - name: '<{{ cmd | upper }}> | 创建 Docker 用户组'
    shell: 
      groupadd -r docker
    ignore_errors: yes

  - name: '<{{ cmd | upper }}> |  创建 Docker 目录'
    shell: |
      source /etc/profile
      mkdir -p {{ docker.dir.main }}
      mkdir -p {{ docker.dir.bin }}
      mkdir -p {{ docker.dir.data }}
      mkdir -p /etc/docker
      if [[ -e /etc/docker/daemon.json ]];then
          cp /etc/docker/daemon.json /etc/docker/daemon.json.bak
      fi
      modprobe br_netfilter
      echo 'net.bridge.bridge-nf-call-ip6tables = 1' > /etc/sysctl.d/docker.conf
      echo 'net.bridge.bridge-nf-call-iptables = 1' >> /etc/sysctl.d/docker.conf
      echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.d/docker.conf
      sysctl --system

  - name: '<{{ cmd | upper }}> |  上传 Docker 二进制包'
    unarchive: 
      src: 'files/{{ ansible_architecture }}/{{ docker.package }}'
      dest: '{{ docker.dir.bin }}'
      mode: 0755
#      extra_opts:
#        - --strip-components 1

  - name: '<{{ cmd | upper }}> |  删除 Docker 临时文件'
    shell: |
      mv {{ docker.dir.bin }}/docker {{ docker.dir.bin }}/docker-tmp
      mv -f {{ docker.dir.bin }}/docker-tmp/* {{ docker.dir.bin }}
      rm -rf {{ docker.dir.bin }}/docker-tmp

  - name: '<{{ cmd | upper }}> |  安装 Docker'
    template:
      src: '{{ item.src }}'
      dest: '{{ item.dest }}'
      group: docker
    loop: 
    - src: docker.service.j2
      dest: /lib/systemd/system/docker.service
    - src: docker.socket.j2
      dest: /lib/systemd/system/docker.socket
    - src: daemon.json.j2
      dest: /etc/docker/daemon.json

  - name: '<{{ cmd | upper }}> |  启动 Docker 服务
    systemd:
      daemon_reload: yes
      state: restarted
      name: docker.service
      enabled: yes

  - name: '<{{ cmd | upper }}> |  创建 Docker 安装标记'
    shell: |
      set -ex
      mkdir -p ~/.flag
      touch {{ flag }}

  when:
  - docker_ret.failed
  - cmd == "install"

- block: 
  - name: '<{{ cmd | upper }}> |  安装 Docker Compose'
    copy:
      src: files/{{ ansible_architecture }}/docker-compose
      dest: '{{ docker.dir.bin }}/docker-compose'
      mode: 0755

  when: 
  - compose_ret.failed
  - cmd == "install"

- block:
  - name: '<{{ cmd | upper }}> |  停止 Docker 服务'
    systemd:
      state: stopped
      name: docker.service
      enabled: no

  - name: '<{{ cmd | upper }}> |  清除 Docker 环境变量'
    blockinfile:
      path: '{{ item }}'
      marker: '#{mark} DOCKER Environment'
      state: absent
      backup: yes
    loop:
    - ~/.bashrc
    - /etc/profile    

  - name: '<{{ cmd | upper }}> |  卸载 Docker 和 Docker Compose'
    file: 
      path: '{{ item }}'
      state: absent
    loop:
    - /lib/systemd/system/docker.service 
    - /lib/systemd/system/docker.socket
    - '{{ docker.dir.bin }}'
    - '{{ docker.dir.data }}'
    - '{{ flag }}'

  when:
  - cmd == "remove"
  - not docker_ret.failed
  1. 编辑 templates/daemon.json.j2 文件
vim /etc/ansible/roles/docker/templates/daemon.json.j2
{
  "exec-opts" : ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-level": "warn",
  "bip": "10.21.21.1/24",
  "data-root": "{{ docker.dir.data }}",
  "log-opts": {
    "max-size": "100m",
    "max-file": "3"
  },
  "registry-mirrors": ["https://registry.docker-cn.com","https://docker.mirrors.ustc.edu.cn","http://hub-mirror.c.163.com"],
   "live-restore": true
}
  1. 编辑 templates/docker.service.j2 文件
vim /etc/ansible/roles/docker/templates/docker.service.j2
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target
Requires=docker.socket

[Service]
Type=notify
Environment=PATH={{ docker.dir.bin }}:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart={{ docker.dir.bin }}/dockerd -H unix://var/run/docker.sock
ExecReload=/bin/kill -s HUP
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
# Uncomment TasksMax if your systemd version supports it.
# Only systemd 226 and above support this version.
#TasksMax=infinity
TimeoutStartSec=0
# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes
# kill only the docker process, not all processes in the cgroup
KillMode=process
# restart the docker process if it exits prematurely
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s

[Install]
WantedBy=multi-user.target
  1. 编辑 templates/docker.socket.j2 文件
vim /etc/ansible/roles/docker/templates/docker.socket.j2
[Unit]
Description=Docker Socket for the API
PartOf=docker.service

[Socket]
ListenStream=/var/run/docker.sock
SocketMode=0660
SocketUser=root
SocketGroup=docker

[Install]
WantedBy=sockets.target
  1. 获取 Docker 二进制文件
    下载地址:
    Docker :https://download.docker.com
    Docker Compose :https://github.com/docker/compose/releases
cd /etc/ansible/roles/docker/files/x86_64
wget https://download.docker.com/linux/static/stable/x86_64/docker-20.10.21.tgz
wget https://github.com/docker/compose/releases/download/v2.12.2/docker-compose-linux-x86_64 -O docker-compose
cd /etc/ansible/roles/docker/files/aarch64
wget https://download.docker.com/linux/static/stable/aarch64/docker-20.10.21.tgz
wget https://github.com/docker/compose/releases/download/v2.12.2/docker-compose-linux-aarch64 -O docker-compose
  1. 运行 Ansible Playbook 脚本
  • 安装 Docker
ansible-playbook /etc/ansible/roles/docker.yml -e cmd=install
  • 卸载 Docker
ansible-playbook /etc/ansible/roles/docker.yml -e cmd=remove
分类: Ansible
标签: Ansible

评论已关闭