Ansible结合Docker容器自动化部署实战教程:从零基础到精通,解决环境配置难题与高效运维挑战

引言:自动化部署的现代需求
在当今快速迭代的软件开发环境中,手动部署应用不仅效率低下,还容易出错。Ansible和Docker的结合为解决这些问题提供了完美的方案。Ansible作为一款强大的自动化工具,负责配置管理和应用部署;而Docker则通过容器化技术确保环境的一致性和隔离性。本教程将从零开始,逐步引导您掌握如何使用Ansible和Docker实现高效的自动化部署,解决环境配置的复杂性,并提升运维效率。
第一部分:基础概念与环境准备
1.1 Ansible简介
Ansible是一个开源的自动化工具,使用YAML语言编写剧本(Playbook),通过SSH协议管理远程服务器。它无需在目标服务器上安装代理(Agentless),这使得它非常轻量级和易于部署。Ansible的核心组件包括:
Inventory
:定义要管理的主机列表。
Playbook
:定义自动化任务的YAML文件。
Modules
:执行具体任务的单元,如安装软件、复制文件等。
Roles
:组织Playbook的结构,便于复用和共享。
1.2 Docker简介
Docker是一个开源的容器化平台,允许开发者将应用及其依赖打包到一个可移植的容器中。Docker的核心概念包括:
Image
:容器的模板,包含运行应用所需的所有文件和配置。
Container
:基于Image运行的实例。
Dockerfile
:用于构建Image的文本文件。
Docker Compose
:用于定义和运行多容器应用的工具。
1.3 环境准备
在开始之前,您需要准备以下环境:
控制节点
:运行Ansible的机器(可以是您的本地电脑或一台服务器),建议使用Linux(如Ubuntu 20.04)。
目标节点
:部署Docker容器的远程服务器,至少一台。
软件安装
:
在控制节点上安装Ansible:
sudo apt update && sudo apt install ansible -y
在目标节点上安装Docker:
sudo apt update && sudo apt install docker.io -y
1.4 配置SSH免密登录
Ansible通过SSH连接目标节点,建议配置免密登录以简化流程:
在控制节点生成SSH密钥(如果尚未生成):
ssh-keygen -t rsa -b 4096
将公钥复制到目标节点:
ssh-copy-id user@target_host
替换
user
和
target_host
为您的目标节点用户名和IP地址。
第二部分:Ansible基础使用
2.1 创建Inventory文件
Inventory文件用于定义目标主机。创建一个名为
inventory.ini
的文件:
[web_servers]
192.168.1.100 ansible_user=ubuntu
192.168.1.101 ansible_user=ubuntu
这里定义了两个Web服务器,Ansible将使用
ubuntu
用户连接。
2.2 编写第一个Playbook
创建一个简单的Playbook来测试连接。新建文件
ping.yml
:
—
– name: Test Ansible Connection
hosts: web_servers
tasks:
– name: Ping all hosts
ansible.builtin.ping:
运行Playbook:
ansible-playbook -i inventory.ini ping.yml
如果一切正常,您将看到每个主机返回”pong”。
2.3 常用Ansible模块
command
:执行命令。
“`yaml
name: Check Docker version
ansible.builtin.command: docker –version
”`
copy
:复制文件到目标主机。
“`yaml
name: Copy a file
ansible.builtin.copy:
src: local_file.txt
dest: /remote/path/file.txt
”`
apt
:管理软件包(适用于Debian/Ubuntu)。
“`yaml
name: Install Docker
ansible.builtin.apt:
name: docker.io
state: present
update_cache: yes
”`
第三部分:Docker基础与容器化应用
3.1 编写Dockerfile
假设我们有一个简单的Python Flask应用。首先,创建项目结构:
myapp/
├── app.py
├── requirements.txt
└── Dockerfile
app.py
内容:
from flask import Flask
app = Flask(__name__)

@app.route(‘/’)
def hello():
return “Hello from Dockerized App!”

if __name__ == ‘__main__’:
app.run(host=’0.0.0.0′, port=5000)
requirements.txt
内容:
Flask==2.0.1
Dockerfile
内容:
# 使用官方Python运行时作为父镜像
FROM python:3.9-slim

# 设置工作目录
WORKDIR /app

# 复制当前目录内容到容器的/app
COPY . .

# 安装依赖
RUN pip install –no-cache-dir -r requirements.txt

# 使容器监听指定端口
EXPOSE 5000

# 定义环境变量
ENV FLASK_APP=app.py

# 运行应用
CMD [“flask”, “run”, “–host=0.0.0.0”]
3.2 构建和运行Docker镜像
在控制节点上构建镜像:
docker build -t myflaskapp:latest .
运行容器:
docker run -d -p 5000:5000 –name myapp myflaskapp
访问
http://localhost:5000
,您将看到”Hello from Dockerized App!“。
3.3 使用Docker Compose管理多容器应用
对于复杂应用,可能需要数据库等其他服务。创建
docker-compose.yml
:
version: ‘3’
services:
web:
build: .
ports:
– “5000:5000”
depends_on:
– db
db:
image: postgres:13
environment:
POSTGRES_DB: mydb
POSTGRES_USER: user
POSTGRES_PASSWORD: password
运行多容器应用:
docker-compose up -d
第四部分:Ansible与Docker的集成
4.1 使用Ansible管理Docker
Ansible提供了Docker模块,可以远程控制Docker。首先,确保目标节点安装了
docker
Python库:
– name: Install Docker Python library
ansible.builtin.pip:
name: docker
4.2 编写部署Playbook
创建
deploy.yml
,实现从构建镜像到运行容器的全流程:
—
– name: Deploy Flask App with Docker
hosts: web_servers
vars:
app_name: myflaskapp
image_tag: “{{ app_name }}:latest”
container_name: “{{ app_name }}”
tasks:
– name: Ensure Docker is installed
ansible.builtin.apt:
name: docker.io
state: present
update_cache: yes

– name: Ensure Docker Python library is installed
ansible.builtin.pip:
name: docker

– name: Build Docker image
community.docker.docker_image:
name: “{{ image_tag }}”
build:
path: /path/to/app # 控制节点上的应用路径
source: build
state: present

– name: Run Docker container
community.docker.docker_container:
name: “{{ container_name }}”
image: “{{ image_tag }}”
state: started
ports:
– “5000:5000”
restart_policy: unless-stopped
运行Playbook:
ansible-playbook -i inventory.ini deploy.yml
4.3 使用Ansible部署Docker Compose
如果您的应用使用Docker Compose,Ansible也可以管理:
– name: Deploy with Docker Compose
hosts: web_servers
tasks:
– name: Ensure Docker Compose is installed
ansible.builtin.get_url:
url: https://github.com/docker/compose/releases/download/v2.23.0/docker-compose-Linux-x86_64
dest: /usr/local/bin/docker-compose
mode: ‘0755’

– name: Copy docker-compose.yml
ansible.builtin.copy:
src: ./docker-compose.yml
dest: /opt/myapp/docker-compose.yml

– name: Run Docker Compose
community.docker.docker_compose:
project_src: /opt/myapp
state: present
restarted: yes
第五部分:高级技巧与最佳实践
5.1 使用Roles组织代码
随着项目复杂度增加,使用Roles可以更好地管理Playbook。创建Role结构:
ansible-galaxy init roles/deploy_docker
在
roles/deploy_docker/tasks/main.yml
中定义任务,然后在Playbook中引用:
—
– name: Deploy using Role
hosts: web_servers
roles:
– deploy_docker
5.2 处理敏感数据:Ansible Vault
对于密码等敏感信息,使用Ansible Vault加密:
ansible-vault create secrets.yml
在Playbook中引用加密变量:
vars_files:
– secrets.yml
5.3 集成CI/CD流水线
将Ansible Playbook集成到Jenkins或GitLab CI中,实现自动化部署。例如,在
.gitlab-ci.yml
中:
deploy:
stage: deploy
script:
– ansible-playbook -i inventory.ini deploy.yml
only:
– main
5.4 监控与日志
使用Ansible收集Docker容器日志:
– name: Fetch container logs
ansible.builtin.shell: docker logs {{ container_name }} > /tmp/app.log
register: log_output

– name: Display logs
ansible.builtin.debug:
var: log_output.stdout_lines
第六部分:实战案例:部署一个WordPress应用
6.1 项目结构
wordpress-deploy/
├── inventory.ini
├── deploy.yml
└── docker-compose.yml
6.2 docker-compose.yml
version: ‘3’
services:
db:
image: mysql:5.7
volumes:
– db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
image: wordpress:latest
ports:
– “80:80”
restart: always
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
volumes:
db_data:
6.3 deploy.yml
—
– name: Deploy WordPress with Docker Compose
hosts: web_servers
tasks:
– name: Ensure Docker is installed
ansible.builtin.apt:
name: docker.io
state: present
update_cache: yes

– name: Ensure Docker Compose is installed
ansible.builtin.get_url:
url: https://github.com/docker/compose/releases/download/v2.23.0/docker-compose-Linux-x86_64
dest: /usr/local/bin/docker-compose
mode: ‘0755’

– name: Create project directory
ansible.builtin.file:
path: /opt/wordpress
state: directory
mode: ‘0755’

– name: Copy docker-compose.yml
ansible.builtin.copy:
src: ./docker-compose.yml
dest: /opt/wordpress/docker-compose.yml

– name: Run Docker Compose
community.docker.docker_compose:
project_src: /opt/wordpress
state: present
restarted: yes
6.4 执行部署
ansible-playbook -i inventory.ini deploy.yml
部署完成后,访问目标服务器的80端口,即可看到WordPress安装界面。
第七部分:常见问题与解决方案
7.1 SSH连接失败
问题
:Permission denied (publickey)。
解决方案
:检查SSH密钥是否正确复制,目标节点的
/etc/ssh/sshd_config
中
PasswordAuthentication
是否设置为
yes
。
7.2 Docker权限问题
问题
:Got permission denied while trying to connect to the Docker daemon socket。
解决方案
:将用户加入docker组:
sudo usermod -aG docker $USER
,然后重新登录。
7.3 Playbook执行超时
问题
:任务执行时间过长。
解决方案
:在Playbook中增加
async
和
poll
参数:
“`yaml
name: Long running task
ansible.builtin.shell: sleep 30
async: 60
poll: 0
”`
第八部分:总结与进阶学习
通过本教程,您已经学习了如何使用Ansible和Docker实现自动化部署,从基础概念到实战案例。这种组合不仅解决了环境配置的难题,还大大提升了运维效率。进阶学习建议:
学习Ansible的Jinja2模板和条件判断。
探索Kubernetes与Ansible的集成。
使用Terraform与Ansible结合进行基础设施即代码(IaC)管理。
自动化是现代运维的核心,掌握Ansible和Docker将为您的职业生涯带来巨大优势。继续实践,不断优化您的部署流程!