参考博客(平台:博客园 作者:珂儿吖):
自动执行某项自定义的任务,如批量安装中间件、自动更新等。
一个 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
文件:指定此项任务的特殊设定及其依赖关系# 注释
[主机组名称]
主机1
主机2
......
示例如下:
[docker]
192.168.10.100
192.168.10.101
192.168.10.102
---
# 注释
- 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
--
# 注释
参数1名称: 参数1值
参数2名称:
参数2-1名称: 参数2-1值
示例如下:
--
# 安装与运行 Docker 服务的参数
type: x86_64
docker:
package: docker-20.10.21.tgz
---
# 注释
- 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
vim /etc/ansible/hosts
[docker]
192.168.10.101
192.168.10.102
192.168.10.103
vim /etc/ansible/roles/docker.yml
- hosts: docker
remote_user: root
become: yes
gather_facts: yes
tags:
- docker
roles:
- role: docker
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'
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
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
}
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
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
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
ansible-playbook /etc/ansible/roles/docker.yml -e cmd=install
ansible-playbook /etc/ansible/roles/docker.yml -e cmd=remove