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 ClientDocker Daemon: 发送 pull 命令
  • Docker DaemonDocker Registry: 下载镜像层
  • Docker RegistryDocker Daemon: 返回镜像数据
  • Docker Daemon → 本地存储: 缓存镜像层

3.2. 容器运行流程

  • Docker ClientDocker Daemon: 发送 run 命令
  • Docker DaemonLocal Image Cache: 获取镜像
  • Docker DaemonContainer Runtime: 创建容器
  • Container Runtime → 内核: 应用 NamespacesCGroups

3.3 Docker Compose编排流程

  • Docker Compose CLI → 解析 docker-compose.yml
  • Docker Compose CLIDocker 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 容器生命周期管理

  1. 创建: docker create
  2. 启动: docker start
  3. 运行: docker run
  4. 暂停: docker pause
  5. 恢复: docker unpause
  6. 停止: docker stop
  7. 重启: docker restart
  8. 删除: 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.运行效果如下图所示

实践:
image

image

image

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和内存限制,使用合适的存储驱动。

posted @ 2025-10-24 14:18  chance_for_ready  阅读(35)  评论(0)    收藏  举报