使用 Ansible 批量安装 Docker
1. 主机列表
IP | 主机名 | 内存(GB) | CPU核数 | 磁盘 | 操作系统 | CPU 架构 |
---|---|---|---|---|---|---|
10.0.0.13 | arc-pro-dc01 | 8 | 1 | 500GB | CentOS 7.9.2009 | x86_64 |
10.0.0.14 | arc-pro-dc02 | 8 | 1 | 500GB | CentOS 7.9.2009 | x86_64 |
10.0.0.15 | arc-pro-dc03 | 8 | 1 | 500GB | CentOS 7.9.2009 | x86_64 |
10.0.0.16 | arc-pro-dc04 | 16 | 2 | 500GB | CentOS 7.9.2009 | x86_64 |
10.0.0.17 | arc-pro-dc05 | 16 | 2 | 500GB | CentOS 7.9.2009 | x86_64 |
10.0.0.18 | arc-pro-dc06 | 16 | 2 | 500GB | CentOS 7.9.2009 | x86_64 |
10.0.0.19 | arc-pro-dc07 | 16 | 2 | 500GB | CentOS 7.9.2009 | x86_64 |
10.0.0.20 | arc-pro-dc08 | 16 | 2 | 500GB | CentOS 7.9.2009 | x86_64 |
10.0.0.21 | arc-pro-dc09 | 16 | 2 | 500GB | CentOS 7.9.2009 | x86_64 |
说明:
- 每个服务器均存在一个管理员用户 admin,该用户可以免密码执行 sudo 命令;
- 在 arc-pro-dc01 机器上,可以使用 admin 用户免密码 ssh 到其他机器;
- 在 arc-pro-dc01 机器上,已经安装好了 ansible 命令
- 执行 ansible 命令时,工作目录是 /home/admin/ansible
参考以下文章完成虚拟机创建、虚拟机优化以及集群基础配置:
- 使用 VMware Workstation 安装 CentOS-7 虚拟机
- 使用 Ansible 批量完成 CentOS 7 操作系统基础配置
2. 准备工作
2.1 上传安装包
在 arc-pro-dc01 服务器操作
Docker 下载地址:https://download.docker.com/linux/static/stable/x86_64/
Docker Compose 下载地址:https://github.com/docker/compose/releases/
准备好安装包:
- docker-28.3.3.tgz
- docker-compose-linux-x86_64
上传到 /home/admin/ansible/docker 目录下
2.2 ansible 目录结构
$ pwd
/home/admin/ansible$ tree .
.
├── ansible.cfg
├── docker
│ ├── containerd.service
│ ├── docker-28.3.3.tgz
│ ├── docker-compose-linux-x86_64
│ ├── docker.service
│ ├── docker.socket
│ └── install-docker.yml
└── hosts
下面分别列出每个文件的内容。
2.3 hosts
[cluster]
arc-pro-dc01
arc-pro-dc02
arc-pro-dc03
arc-pro-dc04
arc-pro-dc05
arc-pro-dc06
arc-pro-dc07
arc-pro-dc08
arc-pro-dc09[cluster:vars]
ansible_user=admin
2.4 ansible.cfg
[defaults]
inventory=./hosts
host_key_checking=False
2.5 docker.service
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target docker.socket firewalld.service containerd.service time-set.target
Wants=network-online.target containerd.service
Requires=docker.socket[Service]
Type=notify
# 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=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutStartSec=0
RestartSec=2
Restart=always# Note that StartLimit* options were moved from "Service" to "Unit" in systemd 229.
# Both the old, and new location are accepted by systemd 229 and up, so using the old location
# to make them work for either version of systemd.
StartLimitBurst=3# Note that StartLimitInterval was renamed to StartLimitIntervalSec in systemd 230.
# Both the old, and new name are accepted by systemd 230 and up, so using the old name to make
# this option work for either version of systemd.
StartLimitInterval=60s# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNPROC=infinity
LimitCORE=infinity
# Older systemd versions default to a LimitNOFILE of 1024:1024, which is insufficient for many
# applications including dockerd itself and will be inherited. Raise the hard limit, while
# preserving the soft limit for select(2).
LimitNOFILE=1024:524288# Comment TasksMax if your systemd version does not support it.
# Only systemd 226 and above support this option.
TasksMax=infinity# 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
OOMScoreAdjust=-500[Install]
WantedBy=multi-user.target
2.6 containerd.service
# Copyright The containerd Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target local-fs.target[Service]
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/bin/containerdType=notify
Delegate=yes
KillMode=process
Restart=always
RestartSec=5
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=infinity
# Comment TasksMax if your systemd version does not supports it.
# Only systemd 226 and above support this version.
TasksMax=infinity
OOMScoreAdjust=-999[Install]
WantedBy=multi-user.target
2.7 docker.socket
[Unit]
Description=Docker Socket for the API[Socket]
# If /var/run is not implemented as a symlink to /run, you may need to
# specify ListenStream=/var/run/docker.sock instead.
ListenStream=/run/docker.sock
SocketMode=0660
SocketUser=root
SocketGroup=docker[Install]
WantedBy=sockets.target
2.8 install-docker.yml
---
- name: Install Dockerhosts: allbecome: truegather_facts: falsevars:admin_user: admin docker_data_root: "/data/docker"docker_registry_mirrors:- "https://docker.1ms.run"- "https://docker.xuanyuan.me"tasks:- name: Stop Docker service if runningservice:name: "{{ item }}"state: stoppedignore_errors: yesloop:- docker.service- containerd.service- name: Delete {{ docker_data_root }} recursivelyfile:path: "{{ docker_data_root }}"state: absent- name: Remove Docker related packagesansible.builtin.yum:name:- docker- docker-client- docker-client-latest- docker-common- docker-latest- docker-latest-logrotate- docker-logrotate- docker-enginestate: absent- name: Create docker group if not existsgroup: name: docker state: present - name: Ensure temporary directory exists on management nodefile:path: /tmp/dockerstate: directorydelegate_to: localhost- name: Extract Docker tarballunarchive:src: docker-28.3.3.tgzdest: /tmp/dockerremote_src: noextra_opts:- "--strip-components=1"delegate_to: localhost- name: Copy Docker binaries to remote /usr/bincopy:src: "{{ item }}"dest: "/usr/bin/"mode: '0755'owner: rootgroup: rootremote_src: noloop: "{{ lookup('ansible.builtin.fileglob', '/tmp/docker/*', wantlist=True) }}"- name: Copy Docker compose binaries to remote /usr/bin copy: src: "docker-compose-linux-x86_64" dest: "/usr/bin/docker-compose" mode: '0755' owner: root group: root remote_src: no - name: Copy Docker service file to remotecopy: src: "{{ item }}"dest: "/usr/lib/systemd/system/{{ item }}"owner: root group: root remote_src: no loop:- docker.service- containerd.service- docker.socket- name: Ensure docker data-root directory existsfile:path: "{{ docker_data_root }}"state: directoryowner: rootgroup: root- name: Ensure docker config directory existsfile:path: /etc/dockerstate: directoryowner: rootgroup: docker- name: Create /etc/docker/daemon.jsoncopy:dest: /etc/docker/daemon.jsoncontent: |{"data-root": "{{ docker_data_root }}","registry-mirrors": {{ docker_registry_mirrors | to_nice_json }}}owner: rootgroup: dockermode: '0644'- name: Add {{ admin_user }} to docker groupuser:name: "{{ admin_user }}"groups: dockerappend: yes- name: Start Docker to apply changessystemd:name: "{{ item }}"state: startedenabled: truedaemon_reload: yesloop:- containerd.service- docker.service- name: Check Docker Compose versioncommand: docker-compose versionregister: compose_versionignore_errors: yes- name: Check Docker versioncommand: docker -vregister: docker_versionignore_errors: yes- name: Get docker service statussystemd:name: dockerregister: docker_status- name: Print Docker Compose versiondebug:msg: "{{ compose_version.stdout }}"- name: Print Docker version debug: msg: "{{ docker_version.stdout }}"- name: Print docker service statusdebug:msg: |"Docker is {{ docker_status.status.ActiveState }} (running=active, stopped=inactive, failed=failed)""Docker service is {{ 'enabled' if docker_status.status.UnitFileState == 'enabled' else 'disabled' }}"- name: Cleanup temporary directory on management nodeshell: rm -rf /tmp/dockerdelegate_to: localhost
3. 安装 Docker
在 arc-pro-dc01 服务器操作
$ pwd
/home/admin/ansible$ ansible-playbook docker/install-docker.yml# 部分检查结果输出
TASK [Print Docker Compose version] *********************************
ok: [arc-pro-dc01] => {"msg": "Docker Compose version v2.39.2"
}
ok: [arc-pro-dc02] => {"msg": "Docker Compose version v2.39.2"
}
ok: [arc-pro-dc03] => {"msg": "Docker Compose version v2.39.2"
}
ok: [arc-pro-dc04] => {"msg": "Docker Compose version v2.39.2"
}
ok: [arc-pro-dc05] => {"msg": "Docker Compose version v2.39.2"
}
ok: [arc-pro-dc06] => {"msg": "Docker Compose version v2.39.2"
}
ok: [arc-pro-dc07] => {"msg": "Docker Compose version v2.39.2"
}
ok: [arc-pro-dc08] => {"msg": "Docker Compose version v2.39.2"
}
ok: [arc-pro-dc09] => {"msg": "Docker Compose version v2.39.2"
}TASK [Print Docker version] ****************************************
ok: [arc-pro-dc01] => {"msg": "Docker version 28.3.3, build 980b856"
}
ok: [arc-pro-dc02] => {"msg": "Docker version 28.3.3, build 980b856"
}
ok: [arc-pro-dc03] => {"msg": "Docker version 28.3.3, build 980b856"
}
ok: [arc-pro-dc04] => {"msg": "Docker version 28.3.3, build 980b856"
}
ok: [arc-pro-dc05] => {"msg": "Docker version 28.3.3, build 980b856"
}
ok: [arc-pro-dc06] => {"msg": "Docker version 28.3.3, build 980b856"
}
ok: [arc-pro-dc08] => {"msg": "Docker version 28.3.3, build 980b856"
}
ok: [arc-pro-dc07] => {"msg": "Docker version 28.3.3, build 980b856"
}
ok: [arc-pro-dc09] => {"msg": "Docker version 28.3.3, build 980b856"
}TASK [Print docker service status] *******************************
ok: [arc-pro-dc02] => {"msg": "\"Docker is active (running=active, stopped=inactive, failed=failed)\"\n\"Docker service is enabled\"\n"
}
ok: [arc-pro-dc01] => {"msg": "\"Docker is active (running=active, stopped=inactive, failed=failed)\"\n\"Docker service is enabled\"\n"
}
ok: [arc-pro-dc03] => {"msg": "\"Docker is active (running=active, stopped=inactive, failed=failed)\"\n\"Docker service is enabled\"\n"
}
ok: [arc-pro-dc05] => {"msg": "\"Docker is active (running=active, stopped=inactive, failed=failed)\"\n\"Docker service is enabled\"\n"
}
ok: [arc-pro-dc04] => {"msg": "\"Docker is active (running=active, stopped=inactive, failed=failed)\"\n\"Docker service is enabled\"\n"
}
ok: [arc-pro-dc06] => {"msg": "\"Docker is active (running=active, stopped=inactive, failed=failed)\"\n\"Docker service is enabled\"\n"
}
ok: [arc-pro-dc08] => {"msg": "\"Docker is active (running=active, stopped=inactive, failed=failed)\"\n\"Docker service is enabled\"\n"
}
ok: [arc-pro-dc07] => {"msg": "\"Docker is active (running=active, stopped=inactive, failed=failed)\"\n\"Docker service is enabled\"\n"
}
ok: [arc-pro-dc09] => {"msg": "\"Docker is active (running=active, stopped=inactive, failed=failed)\"\n\"Docker service is enabled\"\n"
}