Docker容器化技术详解与实践
1. 相关概念
1.1 什么是Docker
Docker是一种开源的应用容器引擎,基于Go语言开发。它可以让开发者打包应用以及应用的依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的Linux机器或Windows机器上,也可以实现虚拟化。它是一种容器化技术的具体实现。
1.2 什么是Docker Compose
Docker Compose 是 Docker 官方编排工具,用于定义和运行多容器 Docker 应用程序。通过 docker-compose.yml 文件来配置应用程序的服务,然后使用单个命令即可创建并启动所有服务。它是一种编排技术的具体实现。
1.3 核心概念
- 镜像(Image): Docker镜像是一个只读的模板,用来创建Docker容器。例如,一个镜像可以包含一个完整的Ubuntu操作系统环境。
- 容器(Container): Docker利用容器来运行应用。容器是从镜像创建的运行实例,可以被启动、开始、停止、删除。
- 仓库(Repository): 集中存放镜像文件的场所。每个仓库可以包含多个标签(tag)的镜像。
- Dockerfile: 一个文本文件,包含了一条条的指令,用于创建镜像。
- docker-compose.yml: 定义服务和项目配置的文件,包含端口映射、路径映射等,用于创建容器。
- 服务(Service): 应用中的某个服务组件。
- 项目(Project): 完整的应用项目,包含多个服务,在
docker-compose.yml文件中定义。 - 容器化(Containerizatio): 一种操作系统级别的虚拟化技术,将应用程序及其依赖打包到轻量级、可移植的容器中。
- 编排(Orchestration): 自动化容器的部署、管理、扩展和联网的过程。
2. 软件架构
2.1 Docker架构组件
Docker Client -> Docker Daemon -> Container Runtime -> Container
Docker Compose CLI -> Docker Engine API -> Docker Daemon -> Containers
- Docker客户端(Docker Client): 用户与Docker交互的主要方式,通过命令行或其他工具发送指令。
- Docker守护进程(Docker Daemon): 运行在主机上的后台进程,负责管理Docker对象如镜像、容器、网络和卷等。
- Docker注册中心(Registry): 存储Docker镜像的地方,Docker Hub是最常用的公共注册中心。
- Container Runtime: 容器运行时环境
graph TD
A[Docker Client] --> B[Docker Daemon]
B --> C[Container Runtime<br/>containerd/runc]
subgraph "Docker Daemon"
B
C
end
subgraph "镜像管理"
D[Docker Registry<br/>Docker Hub/私有仓库] --> E[Image Layers]
E --> F[Local Image Cache]
B --> F
F --> G[Container]
end
subgraph "Docker Compose编排"
H[docker-compose.yml] --> I[Docker Compose CLI]
I --> J[Project<br/>多服务应用]
J --> K[Service 1<br/>Web App]
J --> L[Service 2<br/>Database]
J --> M[Service 3<br/>Cache]
end
subgraph "容器运行时"
G --> N[Namespaces<br/>隔离]
G --> O[CGroups<br/>资源限制]
G --> P[Union FS<br/>文件系统]
end
subgraph "网络与存储"
Q[Docker Network] --> K
Q --> L
Q --> M
R[Docker Volume] --> L
end
K --> B
L --> B
M --> B
style H fill:#e1f5fe
style I fill:#e1f5fe
style J fill:#f3e5f5
style K fill:#f3e5f5
style L fill:#f3e5f5
style M fill:#f3e5f5
style D fill:#fff3e0
style E fill:#fff3e0
style F fill:#fff3e0
2.2 底层技术支持
- Namespaces: 提供隔离的工作区,包括PID、Network、Mount、UTS、IPC、User等命名空间。
- Control Groups(cgroups): 限制和隔离资源使用(CPU、内存、磁盘I/O等)。
- Union File Systems: 用于构建层次化的文件系统,支持Docker镜像的轻量级和快速。
3. 关键交互流程
3.1. 镜像生命周期
Docker Client→Docker Daemon: 发送pull命令Docker Daemon→Docker Registry: 下载镜像层Docker Registry→Docker Daemon: 返回镜像数据Docker Daemon→ 本地存储: 缓存镜像层
3.2. 容器运行流程
Docker Client→Docker Daemon: 发送run命令Docker Daemon→Local Image Cache: 获取镜像Docker Daemon→Container Runtime: 创建容器Container Runtime→ 内核: 应用Namespaces和CGroups
3.3 Docker Compose编排流程
Docker Compose CLI→ 解析docker-compose.ymlDocker Compose CLI→Docker Daemon: 依次创建服务Docker Daemon→ 自动创建: 网络、数据卷等资源Docker Compose CLI→ 管理: 服务间的依赖关系和生命周期
4. 基本原理
4.1 容器化与虚拟化区别
| 特性 | 容器化 | 虚拟化 |
|---|---|---|
| 启动速度 | 秒级 | 分钟级 |
| 硬盘使用 | MB级别 | GB级别 |
| 性能 | 接近原生 | 有一定损耗 |
| 系统支持量 | 单机支持上千个容器 | 一般几十个 |
4.2 镜像分层原理
Docker镜像采用分层存储架构:
- 每个镜像由一系列只读层组成
- 每一层代表Dockerfile中的一条指令
- 容器运行时添加一个可读写层(RW layer)
FROM ubuntu:18.04 # Layer 1
COPY . /app # Layer 2
RUN make /app # Layer 3
CMD ["python", "/app/app.py"] # Layer 4
4.3 容器生命周期管理
- 创建:
docker create - 启动:
docker start - 运行:
docker run - 暂停:
docker pause - 恢复:
docker unpause - 停止:
docker stop - 重启:
docker restart - 删除:
docker rm
4.4 服务间通信原理
- 默认网络: Docker Compose 会自动创建一个默认网络,所有服务都在此网络中
- 服务发现: 服务可以通过服务名称进行DNS解析和通信
- 网络隔离: 不同项目的服务默认网络隔离
5. Docker + Docker Compose实践
5.1 如何搭建Docker环境?
######## 一、安装docker 和 docker compose
【CentOS系统】
# 1. 安装Docker服务
sudo yum update -y
sudo yum install -y docker
# 2. 启动Docker服务并实现开机自启动
sudo systemctl start docker
sudo systemctl enable docker
# 3. 安装Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
【Ubuntu系统】
## 1. 安装Docker服务
# 更新apt包索引
sudo apt update -y
# 安装必要的包
sudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release
# 添加Docker官方GPG密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
或
curl -fsSL --tlsv1.2 https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# 添加Docker仓库
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 更新apt包索引
sudo apt update -y
# 安装Docker Engine
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# 配置docker镜像加速器(解决网络问题导致下载镜像失败问题)
sudo vim /etc/docker/daemon.json
{
"registry-mirrors": [
"https://docker-0.unsee.tech"
]
}
注:其它镜像地址可参考 https://cloud.tencent.com/developer/article/2524388
## 2. 启动Docker服务
# 启动Docker服务
sudo systemctl start docker
# 设置开机自启
sudo systemctl enable docker
# 将当前用户添加到docker组(可选,避免每次使用sudo)
sudo usermod -aG docker $USER
## 3. 安装Docker Compose
# 方法一:使用apt安装(推荐)
sudo apt install -y docker-compose-plugin
sudo apt install docker-compose
# 方法二:或者下载二进制文件
sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# 验证安装
docker-compose version
docker compose version
例:
docker-compose version 1.25.0, build unknown
docker-py version: 4.1.0
CPython version: 3.8.10
OpenSSL version: OpenSSL 1.1.1f 31 Mar 2020
例:
Docker Compose version v2.35.1
5.2 如何部署第三方的MySQL服务?
# 1.进入mysql docker文件夹位置
cd /xx/xx/mysql
# 2.创建并编写docker-compose.yml文件
version: '3.3'
services:
mysql:
image: mysql:8.0
container_name: mysql-server
restart: always
environment:
MYSQL_ROOT_PASSWORD: rootpassword
# 指定需要创建的数据库名
MYSQL_DATABASE: myapp
MYSQL_USER: appuser
MYSQL_PASSWORD: userpassword
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
- ./init:/docker-entrypoint-initdb.d
command: --default-authentication-plugin=mysql_native_password
# 定义命名卷,右侧空白代表使用默认配置
volumes:
mysql_data:
# 3.创建并后台启动容器
docker-compose up -d
# 4.运行效果如下图所示
实践:



5.3 如何部署自定义的SpringBoot服务?
代码工程结构:
project-root/
├── src/
├── pom.xml
├── Dockerfile
├── docker-compose.yml
├── application-docker.yml
└── .dockerignore
部署目录结构:
demoAPP/
├── Dockerfile
├── docker-compose.yml
├── application-docker.yml
└── .dockerignore
└── demo.jar
1. 创建Dockerfile 和 .dockerignore
######### Dockerfile
# 基础镜像
FROM openjdk:8-jdk-alpine
# 设置时区
RUN apk add --no-cache tzdata
ENV TZ=Asia/Shanghai
# 创建应用目录
WORKDIR /app
# 复制jar包
COPY *.jar app.jar
# 复制用于docker环境部署的业务配置文件
COPY application-docker.yml /app/config/
# 暴露端口
EXPOSE 9100
# 启动应用
ENTRYPOINT ["java", "-jar", "app.jar"]
######### .dockerignore
# 构建输出目录
target/
!.mvn/wrapper/maven-wrapper.jar
# Git相关文件
.git
.gitignore
# IDE相关文件
.idea/
.vscode/
*.iml
*.iws
# 日志文件
*.log
logs/
# 临时文件
tmp/
temp/
# 配置文件(如果不想包含)
application-local.yml
.env
# 文档文件
README.md
docs/
2. 创建docker-compose.yml
version: '3.3'
services:
# springboot服务
demoapp:
build: .
container_name: demoService
ports:
- "9100:9100"
volumes:
- ./logs:/app/logs
- ./application-docker.yml:/app/config/application-docker.yml
environment:
- spring.profiles.active=docker
# 使用host网络模式,可以直接访问宿主机网络
network_mode: "host"
3. 创建docker运行环境配置文件
创建 application-docker.yml(专门用于docker环境部署,用于与原环境进行隔离且原配置文件不动):
# application-docker.yml
server:
port: 9100 # 保持与原配置一致
idworker:
workerId: 1
datacenterId: 1
max-http-header-size: 10240
servlet:
context-path: /forum
tomcat:
uri-encoding: UTF-8
spring:
profiles:
active: docker
application:
name: ForumApplication
servlet:
multipart:
max-request-size: 20MB
max-file-size: 10MB
cloud:
sentinel:
transport:
dashboard: sentinel-dashboard:8080 # 使用服务名
port: 8719
eager: true
web-context-unify: false
# 数据源配置 - 使用环境变量
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
druid:
url: jdbc:mysql://${DB_HOST:192.168.75.244}:${DB_PORT:6668}/dev_db_forum?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: ${DB_USERNAME:root}
password: ${DB_PASSWORD:sfdgdh}
initialSize: 5
minIdle: 10
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
maxEvictableIdleTimeMillis: 900000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
webStatFilter:
enabled: true
statViewServlet:
enabled: true
url-pattern: /druid/*
filter:
stat:
enabled: true
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: true
wall:
config:
multi-statement-allow: true
# Redis缓存配置 - 使用环境变量
redis:
cluster:
nodes: ${REDIS_NODES:192.168.75.244:7000,192.168.75.244:7001,192.168.75.244:7002,192.168.75.244:7003,192.168.75.244:7004,192.168.75.244:7005}
password: ${REDIS_PASSWORD:dfsfs}
timeout: 5000
lettuce:
pool:
max-active: 200
max-idle: 10
min-idle: 5
max-wait: -1
database: 8
# 健康检查
management:
health:
defaults:
enabled: false
# mybatis plus 设置
mybatis-plus:
mapper-locations: classpath*:mapper/**/*Mapper.xml
typeAliasesPackage: com.fenda.**.entity
global-config:
banner: false
db-config:
id-type: AUTO
table-underline: true
configuration:
call-setters-on-nulls: true
4. 构建和部署流程
# 1.打包应用 并 上传到服务器指定位置/xx/xx/demoAPP/
mvn clean package -DskipTests
或
IDEA 右侧栏 先后点击clean和Install
# 2.构建并后台启动所有服务
cd /xx/xx/demoAPP/
docker-compose up -d
注:该命令会先自动检测本地是否存在镜像,不存在则会基于DockFile执行docker build构建镜像,再基于镜像构建容器和启动相关服务
# 3.查看服务状态
docker-compose ps
或
docker ps
注:服务状态为up则代表容器启动成功
# 4.查看服务日志
docker-compose logs -f <服务名>
# 5.进入容器环境可查看映射的文件夹、文件、执行系统命令等
docker exec -it aa48dd91c15e bash
或
docker exec -it aa48dd91c15e sh
6. 常见问题与解决方案
6.1 容器间通信
使用Docker网络或Docker Compose实现容器互联。
6.2 数据持久化
通过数据卷或绑定挂载确保数据不会因容器删除而丢失。
6.3 镜像大小优化
使用多阶段构建、Alpine基础镜像等方式减小镜像体积。
6.4 性能调优
合理配置CPU和内存限制,使用合适的存储驱动。
浙公网安备 33010602011771号