从零开始理解容器化技术
一、什么是 Docker
1. 概念
Docker 是一个开源的应用容器引擎,帮助开发者在任何地方快速构建、分享、运行和验证应用程序,而无需繁琐的环境配置或管理。它通过以下四个步骤简化了应用开发流程:
- Build (构建):使用 Dockerfile 定义应用程序及其所有依赖项,并将其打包到一个独立的容器镜像中,确保无论在哪里运行,应用程序都能保持一致的行为。
- Share (分享):容器可以轻松地在不同的开发团队成员之间共享,甚至可以在不同的环境中(如开发、测试和生产)之间共享,便于协作与部署。
- Run (运行):容器可以在任何支持 Docker 的环境中运行,无论是本地机器还是云端服务器,这极大地提高了部署的灵活性和效率。
- Verify (验证):通过容器化,你可以确保应用程序在不同环境中的行为一致,从而更容易进行测试和验证。
2. 架构
Docker 系统主要由三部分组成:
- Client(客户端):用户通过命令行工具(如
docker-cli
)或其他 API 客户端与 Docker 进行交互。 - Docker Host(Docker 主机):运行 Docker 守护进程(Docker Daemon),负责管理镜像、容器等资源。
- Registry(镜像仓库):存储和分发镜像的平台,包括公共仓库(如 Docker Hub)和私有仓库。
3. 工作流程
- Pull: 使用
docker pull
命令从 Registry 下载镜像到 Docker Host。 - Run: 使用
docker run
命令在 Docker Host 上启动并运行容器。 - Build: 使用
docker build
命令基于 Dockerfile 创建新的镜像。 - Push: 使用
docker push
命令将新创建的镜像上传到 Registry。
二、常用命令
1. 镜像操作
- 搜索镜像
docker search nginx
- 拉取镜像
拉取latest标签的镜像,没有latest标签则会报错 Error: No such image
docker pull nginx:1.19
# 拉取指定版本镜像
docker pull nginx:1.19
- 查看本地镜像列表
# 列出所有镜像
docker images
# 仅输出镜像 ID
docker images -q
- 删除本地镜像
# 删除单个镜像
docker rmi nginx
# 强制删除名称包含 "test" 的镜像
docker rmi $(docker images --filter=reference='*test*' -q)
2. 容器操作
- 创建并启动容器
核心参数:
-d
:后台运行(detach 模式)
--name
:指定容器名称(避免随机命名)
-p
:端口映射(主机端口:容器端口
)
-v
:卷挂载(主机路径:容器路径
)
--restart
:重启策略(no
/on-failure
/always
/unless-stopped
)
-e
:设置环境变量(如 -e MYSQL_ROOT_PASSWORD=123456
)
--memory
:限制内存(如 --memory=4g
)
--cpus
:限制CPU核心(如 --cpus=2
)
--cpu-shares
:调整 CPU 使用的相对权重,默认值是1024(如 --cpu-shares=512
)
--memory-swap
:内存 + 交换分区总限制(设为 -1
表示禁用交换)。
docker run -d --name mysql-server \
--restart unless-stopped \ # 自动重启策略
--network mysql-net \
--memory="2g" \ # 限制内存
--cpus="1.5" \ # 限制 CPU
-p 3306:3306 \
-v mysql_data:/var/lib/mysql \ # 数据持久化
-v /host/mysql/conf.d:/etc/mysql/conf.d \
-v /host/mysql/logs:/var/log/mysql \
-e MYSQL_ROOT_PASSWORD="123456" \
-e TZ=Asia/Shanghai \ # 设置时区
mysql:8.0 \
--default-authentication-plugin=mysql_native_password # 兼容旧客户端
卷映射:
Docker 自动创建卷和存储目录,语法为-v volume_name:/container/path,可以使用docker volume inspect volume_name查看详细信息,Docker托管的默认路径为/var/lib/docker/volumes/。文件以容器为主。
目录挂载:
必须手动创建宿主机目录,否则报错,语法为-v /host/path:/container/path。文件以宿主机为主。
- 启停容器
# 停止 web 和 redis 容器
docker stop web redis
# 启动容器,容器ID为1ff9ef97ba4d,可以不用输入完整容器ID,能唯一标识即可
docker start 1ff
# 重启容器
docker restart redis
- 查看容器列表
# 列出所有退出的容器 ID
docker ps -a -q -f status=exited
- 实时资源监控
# 监控所有运行中容器
docker stats
# 仅监控特定容器(如 web 和 mysql)
docker stats web mysql
- 日志
核心参数:
-f
:实时跟踪日志(类似 tail -f
)
--tail
:显示最后 N 行(如 --tail 100
)
-t
:显示时间戳
--since
:指定时间范围(如 --since 2024-01-01
)
# 实时查看 nginx 容器的日志并显示时间戳
sudo docker logs --tail 500 -f -t nginx
- 进入容器
参数:
-it
:分配交互式终端。
docker exec -it mysql /bin/bash
docker exec -it mysql mysql -u root -p123456 -e "CREATE DATABASE appdb;"
- 删除容器
参数:
-f
:强制删除运行中的容器
-v
:同时删除关联的匿名卷
# 强制删除所有容器
docker rm -f $(docker ps -aq)
- 修改资源限制
docker update --memory=3g --cpus=1.5 mysql
- 查看容器资源配置
docker inspect mysql_container
3. 镜像管理
保存镜像
使用 docker commit
命令可以基于现有容器的更改创建一个新的镜像。这对于快速保存对容器所做的修改(例如安装软件或更新配置)非常有用。
- 参数说明:
-a
或--author
:指定作者。-m
或--message
:提交信息,描述此次提交的内容。-c
或--change
:应用 Dockerfile 指令(如 CMD、ENV 等),以在创建新镜像时进行一些额外的修改。
- 示例:基于名为
nginx
的容器创建一个名为my-nginx:v1
的新镜像,并添加提交信息和作者信息。
docker commit -a "Dev Team" -m "Updated homepage" nginx my-nginx:v1
镜像离线备份
将一个或多个镜像打包为 .tar
归档文件,保留完整分层结构,以便于迁移或备份。
# 导出单个镜像
docker save -o nginx-alpine.tar nginx:alpine
# 导出多个镜像并压缩
docker save nginx:alpine redis:6.0 | gzip > apps.tar.gz
恢复镜像
从 .tar
文件恢复镜像到本地仓库,支持直接加载压缩文件。
docker load -i apps.tar.gz
登录镜像仓库
登录到 Docker 镜像仓库(如 Docker Hub、私有仓库),获取推送/拉取权限。
参数说明:
-u
:用户名。
-p
:密码(不建议在命令行中明文输入,可交互式输入或通过环境变量设置)。
SERVER
:仓库地址(默认为 docker.io
)。
# 登录 Docker Hub
docker login -u your-username
# 登录私有仓库
docker login registry.example.com -u admin
镜像标记
为镜像创建别名(支持仓库前缀),便于版本管理和推送至指定仓库。
# 将本地镜像标记为仓库格式,未指定 REGISTRY_HOST 时默认使用 Docker Hub (docker.io)。
docker tag my-app:v1 registry.example.com/project/my-app:1.0
镜像推送
将本地镜像上传至远程仓库,实现镜像共享或持久化存储。
# 推送至 Docker Hub
docker push your-username/my-app:1.0
# 推送至私有仓库
docker push registry.example.com/project/my-app:1.0
4. 网络
Docker0网络
Docker 安装时自动创建的桥接网络(bridge 驱动)。默认子网为 172.17.0.0/16
,容器分配 172.17.0.x
。此网络不支持容器名称自动解析,依赖静态 IP 或链接。
自定义网络
- Bridge Network(桥接网络):类似于
docker0
的自定义桥接网络,但它允许你指定子网和网关,提供更好的隔离性和控制能力。
# 创建自定义桥接网络
docker network create --driver bridge my_bridge_network
- Overlay Network(覆盖网络):用于多宿主机部署的 Docker Swarm 或 Kubernetes 集群环境中,支持跨多个 Docker 守护进程的容器间通信。
# 创建 Overlay 网络(需在 Swarm 模式下)
docker network create -d overlay my_overlay_network
- Host Network(主机网络):容器直接使用宿主机的网络栈,没有网络隔离。这种方式适用于需要最高性能的应用场景,但失去了容器间的网络隔离。
# 使用 Host 网络启动容器
docker run --network host ...
三、Docker Compose
Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。通过 docker-compose.yml
文件,您可以配置应用程序的服务(如Web服务、数据库等)、网络以及卷等资源。只需一个命令即可创建并启动所有配置的服务。
基本概念
- 服务 (Service):在 Docker Compose 中,一个服务就是容器的一个实例。可以指定服务使用的镜像、端口映射、依赖关系等。
- 项目 (Project):默认情况下,项目的名称与包含
docker-compose.yml
文件的目录名称相同。可以通过-p
参数自定义项目名。 - 网络 (Networks) 和 卷 (Volumes):允许您定义共享网络和持久化存储,便于容器间通信和数据持久化。
示例 docker-compose.yml
配置
version: '3.8'
services:
app:
build: .
ports:
- "8000:8000"
restart: unless-stopped
depends_on:
redis:
condition: service_healthy # 等待 Redis 健康后再启动
mysql:
condition: service_healthy # 等待 MySQL 健康后再启动
deploy:
resources:
limits:
cpus: '1.0' # 限制最多使用 1 个 CPU 核心
memory: 1G # 限制最大内存为 1GB
healthcheck: # 应用健康检查
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
redis:
image: redis:alpine
ports:
- "6379:6379"
restart: always
volumes:
- redis_data:/data
deploy:
resources:
limits:
cpus: '0.5' # Redis 限制 0.5 核
memory: 512M # 内存限制 512MB
healthcheck: # Redis 健康检查
test: ["CMD", "redis-cli", "ping"]
interval: 20s
timeout: 5s
retries: 3
mysql:
image: mysql:8.0
ports:
- "3306:3306"
restart: on-failure
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: mydb
volumes:
- mysql_data:/var/lib/mysql
deploy:
resources:
limits:
cpus: '0.5' # MySQL 限制 0.5 核
memory: 512M # 内存限制 512MB
healthcheck: # MySQL 健康检查
test: ["CMD", "mysqladmin", "ping", "-uroot", "-p$${MYSQL_ROOT_PASSWORD}"]
interval: 30s
timeout: 10s
retries: 5
volumes:
redis_data:
mysql_data:
常用命令
- 上线: 使用
docker compose up -d
启动所有服务并在后台运行。 - 下线: 使用
docker compose down
停止并删除所有服务及其相关资源(如网络和卷)。 - 启动特定服务: 使用
docker compose start x1 x2 x3
启动指定的服务。 - 停止特定服务: 使用
docker compose stop x1 x3
停止指定的服务。 - 扩容: 使用
docker compose scale x2=3
将指定服务的实例数量扩展到3个。 - 更新配置: 使用
docker-compose -f compose.yml up -d
应用新的配置文件更改。 - 清理: 使用
docker compose -f compose.yaml down --rmi all -v
停止服务并删除所有镜像和卷。
四、Dockerfile
编写 Dockerfile 来构建 Spring Boot 应用的 Docker 镜像:
# 第一阶段:使用官方的 OpenJDK 基础镜像作为构建环境
FROM openjdk:17-jdk-alpine AS build
# 设置工作目录
WORKDIR /app
# 将当前目录下的所有文件复制到容器内的 /app 目录
COPY . .
# 构建 Spring Boot 应用程序(如果需要的话)
# 这一步取决于您的项目是如何构建的,可能需要安装 Maven 或 Gradle 等工具。
# 如果您已经有了 jar 包,这步可以省略
# RUN ./mvnw clean package -DskipTests
# 第二阶段:创建轻量级的运行时镜像
FROM openjdk:17-jre-alpine
# 设置工作目录
WORKDIR /app
# 从构建阶段复制最终的 jar 包到运行时镜像中
COPY --from=build /app/target/springboot-app.jar /app/app.jar
# 暴露应用程序运行所需的端口(根据实际情况调整)
EXPOSE 8080
# 定义启动命令
ENTRYPOINT ["java", "-jar", "/app/app.jar"]
构建 Docker 镜像
在包含 Dockerfile 的目录下运行以下命令来构建 Docker 镜像:
docker build -t springboot-app .
- 本文标签: 云原生
- 本文链接: https://lanzi.cyou/article/46
- 版权声明: 本文由咖啡豆原创发布,转载请遵循《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权