云原生(docker容器技术)

一、Docker 基础认知

1.1 Docker 简介与发展历程

  • Docker 是由 Docker, Inc 开发的开源分布式应用平台,是管理容器的引擎,为应用提供打包、部署的运行环境,而非单纯的虚拟化技术。Docker 之父 Solomon Hykes 将其类比为传统货运集装箱,解决了应用在不同环境中的标准化交付问题。
  • 技术发展背景:2008 年 LXC(Linux Container)发布,但缺乏行业标准、兼容性极差;2013 年 Docker 首次发布,基于 LXC 构建并形成标准化容器生态,彻底推动了容器技术的普及。
  • 核心组件:
    • Docker Engine:可移植、轻量级的应用运行时与打包工具;
    • Docker Hub:用于共享应用、自动化工作流的云服务。

1.2 Docker 核心特性与优势

Docker 核心价值是实现了开发一次,到处运行(Build once, Run anywhere) ,对运维则实现了配置一次,运行任何应用(Configure once, Run anything),核心特性如下:

  1. 轻量级虚拟化:容器启动为秒级,远快于虚拟机的分钟级启动,大幅节省系统资源;
  2. 环境一致性:确保应用在开发、测试、生产等不同环境中表现完全一致,杜绝 "本地能跑线上不能跑" 的环境差异问题;
  3. 高可移植性:容器可无缝从本地环境迁移到云服务器,无需担心依赖与配置差异;
  4. 高效资源利用:多个容器共享宿主机操作系统内核,单机可支持上千个容器,远高于虚拟机的运行密度;
  5. 快速部署与扩展:可秒级完成应用实例部署,支持按需水平扩展。

1.3 Docker 企业级应用场景

Docker 在企业中作为业务的最小载体被广泛应用,核心场景覆盖 IaaS、PaaS、SaaS 三层架构:

  • SaaS 层:云盘、微店、企业网站、各类 SaaS 应用的标准化部署;
  • PaaS 层:Redis、MySQL、NGINX、MongoDB 等中间件与数据库的容器化交付;
  • IaaS 层:基于 Docker 构建企业级云平台,实现基础设施的标准化与资源池化。

补充概念:

  • IaaS(基础设施即服务):提供服务器、存储、网络等底层硬件资源;
  • PaaS(平台即服务):提供应用开发、运行的平台环境,屏蔽底层基础设施;
  • SaaS(软件即服务):通过网络直接提供开箱即用的软件应用。

1.4 Docker 容器与传统虚拟机的对比

对比维度 传统虚拟机 Docker 容器
操作系统 宿主机上运行完整虚拟机 OS 共享宿主机 OS 内核
存储占用 镜像体积大(GB 级) 镜像体积小(MB 级)
性能表现 操作系统额外消耗 CPU、内存 几乎无性能损耗
移植性 笨重,与虚拟化技术耦合度高 轻量,灵活跨平台迁移
隔离性 系统级完全隔离 安全的进程级隔离
部署速度 慢,分钟级 快速,秒级
运行密度 单机一般支持几十个 单机支持上千个容器

二、Docker 环境部署

2.1 Docker 核心工作架构

Docker 采用 C/S(客户端 - 服务端)架构,核心三大组件:

  • Client(客户端):通过 docker 命令向服务端发送 build、pull、run 等指令;
  • DOCKER_HOST(宿主机):运行 Docker daemon 守护进程,负责镜像管理、容器生命周期管理;
  • Registry(镜像仓库):集中存储与分发 Docker 镜像,客户端可从仓库拉取镜像,也可将本地镜像推送至仓库。

2.2 部署前准备与软件仓库配置

以 RHEL 9 系列系统为例,配置阿里云 Docker 软件源:

复制代码
# 进入yum仓库配置目录
cd /etc/yum.repos.d
# 创建docker仓库配置文件
vim docker.repo

配置文件内容:

复制代码
[docker]
name=docker-ce
baseurl=https://mirrors.aliyun.com/docker-ce/linux/rhel/9/x86_64/stable
gpgcheck=0

2.3 Docker 安装与服务启动

安装 Docker 社区版

复制代码
yum install -y docker-ce

配置服务启动参数(指定 iptables 网络模式)

复制代码
# 编辑docker服务启动文件
vim /usr/lib/systemd/system/docker.service
# 修改ExecStart行,添加iptables=true参数
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --iptables=true

启动服务并设置开机自启

复制代码
# 重载系统服务配置
systemctl daemon-reload
# 启动docker并设置开机自启
systemctl enable --now docker
# 验证docker服务状态
docker info

2.4 内核网络参数优化配置

Docker 容器网络依赖内核桥接模块与转发能力,需激活相关内核参数:

加载桥接内核模块

复制代码
# 配置开机自动加载br_netfilter模块
echo br_netfilter > /etc/modules-load.d/docker_mod.conf
# 即时加载模块
modprobe br_netfilter

配置内核网络转发参数

复制代码
# 创建sysctl配置文件
vim /etc/sysctl.d/docker.conf

配置内容:

复制代码
# 开启桥接流量经过iptables链
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
# 开启IPv4内核转发
net.ipv4.ip_forward = 1

生效配置并重启服务

复制代码
# 加载所有sysctl配置
sysctl --system
# 重启docker服务使配置生效
systemctl restart docker

三、Docker 核心基础操作

3.1 Docker 镜像管理

镜像是容器运行的只读模板,包含应用运行所需的代码、依赖、环境变量、配置文件等所有内容,核心操作如下:

3.1.1 搜索镜像

从镜像仓库中搜索目标镜像,示例:

复制代码
docker search nginx

关键返回字段说明:

  • NAME:镜像名称
  • DESCRIPTION:镜像功能说明
  • STARS:社区点赞数量,代表镜像受欢迎程度
  • OFFICIAL:是否为官方维护镜像
3.1.2 拉取镜像

从仓库拉取镜像到本地,支持指定版本标签,无标签默认拉取 latest 最新版:

复制代码
# 拉取最新版busybox镜像
docker pull busybox
# 拉取指定版本的nginx轻量镜像
docker pull nginx:1.26-alpine
# 查看本地已下载镜像
docker images

补充:alpine 版本是基于 Alpine Linux 的极简发行版,大幅缩减镜像体积,例如 nginx:1.26-alpine 仅 43.2MB,远小于标准版的 188MB。

3.1.3 镜像信息查看与管理
复制代码
# 查看镜像详细元数据、配置信息
docker image inspect nginx:1.26-alpine

# 导出镜像到本地文件,支持多镜像打包、压缩
docker image save nginx:latest -o nginx-latest.tar.gz
# 同时导出多个镜像到一个压缩包
docker image save nginx:latest nginx:1.26-alpine -o nginx.tag.gz
# 批量导出本地所有镜像
docker save `docker images | awk 'NR>1{print $1":"$2}'` -o images.tar.gz

# 导入本地镜像包
docker load -i nginx-latest.tar.gz

# 删除本地镜像
docker rmi nginx:latest
# 批量删除本地所有镜像
docker rmi `docker images | awk 'NR>1{print $1":"$2}'`

3.2 Docker 容器生命周期管理

容器是镜像的运行实例,是一个独立的、可运行的沙箱环境,核心操作覆盖启动、查看、启停、删除全生命周期。

3.2.1 容器启动

核心启动命令docker run,关键参数说明:

  • -d:后台守护进程运行容器
  • -i:交互式运行,保持输入流开启
  • -t:为容器分配虚拟终端
  • --name:指定容器唯一名称
  • -p:端口映射,格式为宿主机端口:容器端口
  • --rm:容器停止后自动删除
  • --network:指定容器使用的网络

常用启动示例:

复制代码
# 后台启动马里奥游戏容器,映射宿主机80端口到容器8080端口
docker run -d --name mario -p 80:8080 timinglee/mario

# 交互式启动centos7容器,进入容器终端
docker run -it --name centos7 centos:7

关键注意事项:

  1. 容器内第一个进程必须持续前台运行,否则容器会直接退出;
  2. 交互式容器退出方式:按ctrl+d退出并停止容器;按ctrl+p+q退出但不停止容器;
  3. 重新进入运行中的容器:docker attach centos7
  4. 在运行中的容器内执行命令:docker exec -it 容器名/容器ID 命令,示例:docker exec -it test ifconfig
3.2.2 容器状态查看
复制代码
# 查看当前正在运行的容器
docker ps
# 查看所有容器(包括已停止的)
docker ps -a
# 查看容器详细配置、网络、挂载等元数据
docker inspect 容器名/容器ID
3.2.3 容器启停与删除
复制代码
# 停止运行中的容器
docker stop 容器名/容器ID
# 强制杀死容器(支持发送系统信号)
docker kill 容器名/容器ID
# 启动已停止的容器
docker start 容器名/容器ID
# 重启容器
docker restart 容器名/容器ID

# 删除已停止的容器
docker rm 容器名/容器ID
# 强制删除运行中的容器
docker rm -f 容器名/容器ID
# 批量删除所有已停止的容器
docker container prune -f

3.3 容器数据交互与镜像提交

3.3.1 容器与宿主机文件传输
复制代码
# 将容器内的文件复制到宿主机
docker cp 容器名:/容器内文件路径 宿主机目标路径
# 示例:把test2容器内的/leefile复制到宿主机/mnt目录
docker cp test2:/leefile /mnt

# 将宿主机文件复制到容器内
docker cp 宿主机文件路径 容器名:/容器内目标路径
# 示例:把宿主机/etc/fstab复制到test2容器根目录
docker cp /etc/fstab test2:/fstab
3.3.2 容器修改提交为新镜像

默认容器删除后,容器内的所有修改都会丢失,通过docker commit可将容器内的修改提交为新的镜像,实现修改持久化:

复制代码
# 1. 运行容器并创建测试文件
docker run -it --name test busybox
touch leefile
exit

# 2. 将容器修改提交为新镜像
docker commit -m "add leefile" test busybox:v1

# 3. 查看生成的新镜像
docker images

# 4. 查看镜像构建历史
docker image history busybox:v1

企业最佳实践:docker commit不利于审计与版本管理,企业环境中禁止使用该方式构建镜像,应通过 Dockerfile 标准化构建镜像。

3.4 容器日志查看

复制代码
# 查看容器运行日志,实时输出应用打印的标准输出/标准错误
docker logs 容器名/容器ID
# 示例:查看web容器的nginx运行日志
docker logs web
# 持续实时刷新日志
docker logs -f 容器名/容器ID
# 查看最近100行日志
docker logs --tail 100 容器名/容器ID

四、Docker 镜像构建与优化

4.1 Docker 镜像底层原理

4.1.1 镜像分层结构
  • Docker 镜像采用分层存储架构,最底层为基础镜像(Base Image),提供最小化的 Linux 发行版环境,所有镜像共享宿主机的 Linux 内核;
  • 镜像层全部为只读层 ,容器启动时会在镜像层之上创建一个可写的容器层,所有对容器的修改都保存在容器层,不会修改底层镜像;
  • 分层结构的核心优势是资源共享,多个镜像可复用相同的基础层,大幅减少存储空间占用;
  • 单个 Docker 镜像最多支持 127 个分层。
4.1.2 写时复制(Copy-on-Write)机制
  • Docker 从上到下依次在镜像层中查找文件,找到后直接读取;
  • 当需要修改、新增、删除文件时,会将文件从只读镜像层复制到可写容器层进行修改,原始镜像层文件保持不变;
  • 容器删除后,容器层的所有修改会一并删除,底层镜像层保持不变。
4.1.3 镜像获取方式
  1. 从镜像仓库拉取:docker pull 镜像地址
  2. 从本地镜像包导入:docker load -i 本地镜像包
  3. 基于 Dockerfile 自定义构建(企业主流方式)
  4. 基于容器 commit 提交生成(不推荐)

4.2 Dockerfile 核心指令详解

Dockerfile 是用于构建 Docker 镜像的文本文件,包含一条条构建镜像所需的指令和步骤,核心指令如下:

指令 功能说明与用法示例
FROM 指定构建使用的基础镜像,必须为 Dockerfile 的第一条指令示例:FROM busybox:latestFROM centos:7 AS build(多阶段构建命名)
MAINTAINER 指定镜像作者信息(新版 Docker 已废弃,推荐使用 LABEL 替代)示例:MAINTAINER user@example.com
LABEL 为镜像添加元数据标签,可用于标注作者、版本、描述等信息示例:LABEL maintainer="user@example.com" version="1.0"
COPY 复制宿主机本地文件 / 目录到镜像内示例:COPY leefile /COPY ["file1","file2","/opt/"]
ADD 功能与 COPY 一致,额外支持 2 个特性:1. 自动解压 tar/zip 等压缩包到目标路径;2. 支持从 URL 下载文件到镜像内示例:ADD test.tar /mntADD http://ip/test.tar /mnt
ENV 设置容器内的环境变量,构建过程与容器运行时均生效示例:ENV NAME leeENV MYSQL_ROOT_PASSWORD=123456
EXPOSE 声明容器运行时监听的端口,仅做声明,不自动完成端口映射示例:EXPOSE 80EXPOSE 80 443
VOLUME 声明容器数据卷挂载点,实现数据持久化,避免容器删除数据丢失示例:VOLUME ["/var/www/html"]VOLUME /usr/local/nginx/html
WORKDIR 切换容器内的工作目录,若目录不存在会自动创建,后续 RUN/CMD/ENTRYPOINT 等指令均在该目录下执行示例:WORKDIR /mntWORKDIR /opt/app
RUN 在镜像构建阶段执行 shell 命令,每一条 RUN 指令会生成一个新的镜像层示例:RUN yum install -y gcc makeRUN touch leefile
CMD 容器启动时默认执行的命令,可被 docker run 命令行参数覆盖 ;一个 Dockerfile 中只有最后一条 CMD 生效- shell 格式:CMD echo $NAME(会调用 shell 解析器)- exec 格式:CMD ["/bin/echo","$NAME"](不调用 shell 解析器,无法解析环境变量)- 推荐 exec 格式:CMD ["/bin/sh","-c","echo $NAME"]
ENTRYPOINT 容器启动时执行的命令,不可被 docker run 命令行参数覆盖 ,与 CMD 配合可实现容器启动参数动态传递;用法格式与 CMD 一致示例:ENTRYPOINT ["nginx", "-g", "daemon off;"]

4.3 Dockerfile 完整构建示例

以 CentOS7 为基础镜像,源码编译构建 Nginx 镜像:

创建构建目录并准备源码包

复制代码
mkdir docker
cd docker
# 提前下载nginx源码包到当前目录
cp ~/nginx-1.23.3.tar.gz .

编写 Dockerfile 文件

复制代码
# 指定基础镜像
FROM centos:7
# 复制并解压nginx源码包到/mnt目录
ADD nginx-1.23.3.tar.gz /mnt
# 切换工作目录到源码解压路径
WORKDIR /mnt/nginx-1.23.3
# 安装编译依赖
RUN yum install -y gcc make pcre-devel openssl-devel
# 关闭debug编译模式,减小二进制体积
RUN sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc
# 配置编译参数,开启ssl与状态模块
RUN ./configure --with-http_ssl_module --with-http_stub_status_module
# 编译与安装
RUN make
RUN make install
# 声明容器监听端口
EXPOSE 80
# 声明数据持久化目录
VOLUME ["/usr/local/nginx/html"]
# 容器启动时前台运行nginx
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]

执行镜像构建

复制代码
# -t 指定镜像名称与标签,. 指定Dockerfile所在的上下文目录为当前目录
docker build -t webserver:v1 .

镜像验证与测试

复制代码
# 查看构建完成的镜像
docker images webserver
# 查看镜像构建历史与分层
docker history webserver:v1
# 启动容器测试镜像可用性
docker run -d --name checkimage webserver:v1
# 查看容器运行状态
docker ps | grep checkimage

4.4 镜像优化核心策略与实战

Docker 镜像优化核心目标是减小镜像体积、减少镜像层数、提升构建效率、降低安全风险,核心策略与实战如下:

4.4.1 核心优化策略
  1. 选择最精简的基础镜像(如 alpine、distroless);
  2. 合并 RUN 指令,减少镜像分层数量;
  3. 清理镜像构建的中间产物(如 yum 缓存、源码包、编译临时文件);
  4. 采用多阶段构建,仅保留运行所需的二进制与依赖,剔除编译环境;
  5. 关闭不必要的编译 debug 信息,减小二进制文件体积。
4.4.2 优化实战示例

基于上述 Nginx 镜像,分阶段优化效果如下:

优化方式 镜像版本 镜像体积 优化效果
原始构建 webserver:v1 494MB 基准版本
合并 RUN 指令 + 清理中间产物 webserver:v2 317MB 体积缩减 36%
多阶段构建 webserver:v3 205MB 体积缩减 58%
精简 distroless 基础镜像 webserver:v4 34MB 体积缩减 93%

优化 1:合并 RUN 指令 + 清理中间产物

复制代码
FROM centos:7
ADD nginx-1.23.3.tar.gz /mnt
WORKDIR /mnt/nginx-1.23.3
# 合并所有RUN指令,构建完成后清理源码与yum缓存
RUN yum install -y gcc make pcre-devel openssl-devel && \
    sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && \
    ./configure --with-http_ssl_module --with-http_stub_status_module && \
    make && make install && \
    cd .. && rm -fr nginx-1.23.3 && \
    yum clean all
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]

优化 2:多阶段构建第一阶段完成编译构建,第二阶段仅复制编译后的 nginx 运行文件,剔除编译环境与依赖:

复制代码
# 构建阶段:完成nginx编译
FROM centos:7 AS build
ADD nginx-1.23.3.tar.gz /mnt
WORKDIR /mnt/nginx-1.23.3
RUN yum install -y gcc make pcre-devel openssl-devel && \
    sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && \
    ./configure --with-http_ssl_module --with-http_stub_status_module && \
    make && make install && \
    cd .. && rm -fr nginx-1.23.3 && \
    yum clean all

# 运行阶段:仅保留运行所需文件
FROM centos:7
COPY --from=build /usr/local/nginx /usr/local/nginx
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]

优化 3:使用 distroless 极简基础镜像distroless 是 Google 开源的极简基础镜像,仅包含应用运行所需的最小组件,无 shell、包管理器等多余组件,极致缩减镜像体积:

复制代码
# 基础构建阶段
FROM nginx:1.23 AS base
ARG TIME_ZONE
RUN mkdir -p /opt/var/cache/nginx && \
    cp -a --parents /usr/lib/nginx /opt && \
    cp -a --parents /usr/share/nginx /opt && \
    cp -a --parents /var/log/nginx /opt && \
    cp -aL --parents /var/run /opt && \
    cp -a --parents /etc/nginx /opt && \
    cp -a --parents /etc/passwd /opt && \
    cp -a --parents /etc/group /opt && \
    cp -a --parents /usr/sbin/nginx /opt && \
    cp -a --parents /usr/sbin/nginx-debug /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/ld-* /opt && \
    cp -a --parents /usr/lib/x86_64-linux-gnu/libpcre* /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/libz.so.* /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/libc* /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/libdl* /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/libpthread* /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/libcrypt* /opt && \
    cp -a --parents /usr/lib/x86_64-linux-gnu/libssl.so.* /opt && \
    cp -a --parents /usr/lib/x86_64-linux-gnu/libcrypto.so.* /opt && \
    cp /usr/share/zoneinfo/${TIME_ZONE:-ROC} /opt/etc/localtime

# 最终运行阶段:使用distroless基础镜像
FROM gcr.io/distroless/base-debian11
COPY --from=base /opt /
EXPOSE 80 443
ENTRYPOINT ["nginx", "-g", "daemon off;"]

五、Docker 镜像仓库管理

5.1 镜像仓库核心概念与分类

Docker Registry(镜像仓库)是用于存储和分发 Docker 镜像的集中式存储库,是 Docker 生态中镜像共享、版本管理的核心组件,分为两大类:

  1. 公共仓库:面向互联网开放,任何人都可访问、拉取镜像,典型代表为 Docker Hub,国内常用的有 DaoCloud 镜像仓库、阿里云容器镜像服务等;
  2. 私有仓库:由企业 / 个人自行搭建管理,用于存储内部业务镜像,保障数据安全与访问权限管控,典型开源方案为 Docker 官方 Registry、VMware 开源的 Harbor。

5.2 Docker Hub 公共仓库使用

Docker Hub 是 Docker 官方提供的公共镜像仓库,拥有海量官方与社区维护的镜像,是最主流的公共镜像源。

5.2.1 基础使用流程
  1. 账号准备:前往https://hub.docker.com/ 注册 Docker ID;

  2. 客户端登录:

    docker login

    按提示输入Docker ID与密码,登录成功后凭证会保存在/root/.docker/config.json

镜像打标签:推送镜像前,需按照用户名/镜像名:标签格式为镜像打标签

复制代码
# 格式:docker tag 原镜像名:标签 用户名/镜像名:标签
docker tag gcr.io/distroless/base-debian11:latest timinglee/base-debian11:latest

推送镜像到 Docker Hub

复制代码
docker push timinglee/base-debian11:latest

从 Docker Hub 拉取镜像

复制代码
docker pull timinglee/base-debian11:latest

退出登录

复制代码
docker logout
5.2.2 国内镜像加速配置

国内网络访问 Docker Hub 速度较慢,可配置镜像加速地址提升拉取速度:

复制代码
# 创建/修改daemon.json配置文件
vim /etc/docker/daemon.json

配置内容:

复制代码
{
  "registry-mirrors": ["https://docker.m.daocloud.io"]
}

生效配置:

复制代码
systemctl daemon-reload
systemctl restart docker

5.3 镜像推拉核心原理

5.3.1 镜像拉取(pull)原理
  1. Docker 客户端向 Index(索引服务)发送镜像拉取请求,并完成用户认证;
  2. Index 返回认证 token 与镜像所在的 Registry 地址;
  3. 客户端携带 token,根据 Index 指引连接对应的 Registry;
  4. Registry 将客户端的 token 发送给 Index,核实身份合法性;
  5. Index 确认 token 有效并返回验证结果;
  6. Registry 向客户端传输镜像分层数据,完成拉取。
5.3.2 镜像推送(push)原理
  1. Docker 客户端向 Index 发送镜像上传请求,并完成用户认证;
  2. Index 向客户端返回临时 token,用于证明客户端合法性;
  3. 客户端携带 token 连接目标 Registry;
  4. Registry 向 Index 核实 token 的合法性;
  5. Index 验证 token 有效并返回结果;
  6. Registry 接收客户端上传的镜像分层数据,完成推送。

5.4 私有 Registry 仓库搭建与配置

Docker 官方开源了 Registry 镜像,可快速搭建轻量级私有仓库,适用于测试与小型环境。

5.4.1 基础版私有仓库搭建(HTTP)

拉取 Registry 官方镜像

复制代码
docker pull registry:latest

启动 Registry 容器

复制代码
docker run -d -p 5000:5000 --restart=always --name registry registry

配置 Docker 客户端信任 HTTP 仓库

复制代码
vim /etc/docker/daemon.json

配置内容(替换为仓库宿主机 IP):

复制代码
{
  "insecure-registries" : ["http://172.25.254.100:5000"]
}

重启 Docker 生效配置

复制代码
systemctl daemon-reload
systemctl restart docker

镜像推送与拉取测试

复制代码
# 为镜像打私有仓库标签
docker tag busybox:latest 172.25.254.100:5000/busybox:latest
# 推送镜像到私有仓库
docker push 172.25.254.100:5000/busybox:latest
# 查看仓库中的镜像列表
curl 172.25.254.100:5000/v2/_catalog
# 从私有仓库拉取镜像
docker pull 172.25.254.100:5000/busybox:latest
5.4.2 私有仓库 HTTPS 加密配置

生产环境需配置 HTTPS 保障传输安全,基于自签名证书实现:

创建证书目录并生成自签名证书

复制代码
mkdir -p /root/certs
openssl req -newkey rsa:4096 \
-nodes -sha256 -keyout certs/timinglee.org.key \
-addext "subjectAltName = DNS:reg.timinglee.org" \
-x509 -days 365 -out certs/timinglee.org.crt
# 按提示填写证书信息,Common Name需填写域名reg.timinglee.org

启动带 HTTPS 配置的 Registry 容器

复制代码
docker run -d -p 443:443 --restart=always --name registry \
-v /opt/registry:/var/lib/registry \
-v /root/certs:/certs \
-e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/timinglee.org.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/timinglee.org.key \
registry

客户端配置证书信任

复制代码
# 创建证书目录
mkdir /etc/docker/certs.d/reg.timinglee.org/ -p
# 复制CA证书到客户端目录
cp /root/certs/timinglee.org.crt /etc/docker/certs.d/reg.timinglee.org/ca.crt
# 重启docker
systemctl restart docker

测试 HTTPS 仓库

复制代码
# 打标签
docker tag busybox:latest reg.timinglee.org/busybox:latest
# 推送镜像
docker push reg.timinglee.org/busybox:latest
# 查看仓库镜像
curl -k https://reg.timinglee.org/v2/_catalog
5.4.3 私有仓库用户认证配置

为仓库添加账号密码认证,未登录用户无法推拉镜像:

安装 htpasswd 工具

复制代码
dnf install httpd-tools -y

创建认证账号密码文件

复制代码
mkdir -p /root/auth
# 创建用户timinglee,设置密码,-B使用bcrypt加密
htpasswd -Bc auth/htpasswd timinglee

启动带认证的 HTTPS Registry 容器

复制代码
docker run -d -p 443:443 --restart=always --name registry \
-v /opt/registry:/var/lib/registry \
-v /root/certs:/certs \
-v /root/auth:/auth \
-e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/timinglee.org.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/timinglee.org.key \
-e REGISTRY_AUTH=htpasswd \
-e REGISTRY_AUTH_HTPASSWD_REALM="Registry Realm" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
registry

认证测试

复制代码
# 登录仓库
docker login reg.timinglee.org
# 输入账号密码完成登录后,即可正常推拉镜像
docker push reg.timinglee.org/busybox:latest
# 未登录状态推拉镜像会提示no basic auth credentials

5.5 Harbor 企业级私有仓库部署

Harbor 是 VMware 开源的企业级 Docker Registry 项目,提供了 RBAC 角色权限控制、镜像复制、Web 管理界面、审计日志、安全扫描、垃圾回收等企业级功能,是生产环境的首选方案。

5.5.1 Harbor 部署步骤
  1. 下载 Harbor 离线安装包:前往https://github.com/goharbor/harbor/releases 下载对应版本;

  2. 解压安装包

    tar zxf harbor-offline-installer-v2.5.4.tgz
    cd harbor

复制并修改配置文件

复制代码
cp harbor.yml.tmpl harbor.yml
vim harbor.yml

核心配置修改:

复制代码
# 仓库访问域名/IP
hostname: reg.timinglee.org
# HTTPS证书与私钥路径
certificate: /data/certs/timinglee.org.crt
private_key: /data/certs/timinglee.org.key
# admin管理员初始密码
harbor_admin_password: lee

执行安装脚本

复制代码
# 可附加参数:--with-trivy开启镜像安全扫描,--with-chartmuseum开启Helm仓库支持
./install.sh --with-chartmuseum

Harbor 生命周期管理

复制代码
# 停止Harbor所有服务
docker compose stop
# 启动Harbor所有服务
docker compose up -d
5.5.2 Harbor 基础使用
  1. 访问 Web 界面:通过https://reg.timinglee.org 访问,使用 admin 账号登录;

  2. 创建项目:在 Web 界面新建项目(如 timinglee),可设置公开 / 私有访问级别;

  3. 客户端登录与镜像推送

    登录Harbor仓库

    docker login reg.timinglee.org

    为镜像打标签,格式:仓库域名/项目名/镜像名:标签

    docker tag busybox:latest reg.timinglee.org/timinglee/busybox:latest

    推送镜像

    docker push reg.timinglee.org/timinglee/busybox:latest

  4. 推送完成后,可在 Harbor Web 界面的对应项目中查看镜像详情。

六、Docker 网络体系

Docker 网络实现了容器之间、容器与宿主机、容器与外网的通信,是 Docker 核心能力之一。

6.1 Docker 原生网络模型

Docker 安装完成后,会自动创建 3 种原生网络:bridge、host、none,可通过docker network ls查看。

6.1.1 bridge(桥接网络)- 默认模式
  • Docker 安装时会自动创建名为docker0的 Linux 网桥,新建容器默认会桥接到该接口;
  • 桥接模式下,容器会获得独立的内网 IP,宿主机可直接访问容器,外部主机无法直接访问,需通过端口映射实现外网访问;
  • 容器通过宿主机的 NAT 规则实现外网访问,依赖net.ipv4.ip_forward=1内核转发参数;
  • 特点:容器之间网络隔离,通过 docker0 网桥实现通信,是最常用的网络模式。
6.1.2 host(主机网络)模式
  • 容器创建时通过--network=host指定,容器与宿主机共享网络栈;
  • 容器不会获得独立的 IP,直接使用宿主机的 IP 与端口,无需端口映射即可直接访问;
  • 特点:网络性能无损耗,但网络隔离性差,容器端口与宿主机端口会产生冲突。
6.1.3 none(无网络)模式
  • 容器创建时通过--network=none指定,禁用容器所有网络功能,仅保留 lo 本地回环接口;
  • 特点:极致的网络隔离,适用于对安全性要求极高、无需网络访问的容器场景。

6.2 Docker 自定义网络

Docker 支持用户自定义网络,提供了 bridge、overlay、macvlan 三种驱动:

  • bridge:类似默认 bridge 网络,但增加了内置 DNS 解析、更好的隔离性,是单主机容器网络的推荐方案;
  • overlay/macvlan:用于创建跨主机容器网络,实现多主机上的容器直接通信。
6.2.1 自定义桥接网络创建与配置

创建默认自定义桥接网络

复制代码
docker network create my_net1

创建自定义子网与网关的桥接网络

复制代码
docker network create my_net2 --subnet 192.168.0.0/24 --gateway 192.168.0.100

查看网络详细配置

复制代码
docker network inspect my_net2

容器使用自定义网络

复制代码
# 启动容器时指定自定义网络
docker run -d --network my_net1 --name web nginx
# 容器内可直接通过容器名ping通同网络的其他容器
docker run -it --network my_net1 --name test busybox
ping web
6.2.2 自定义网络核心优势
  • 内置 DNS 解析:同一自定义网络内的容器,可直接通过容器名称相互通信,无需依赖 IP,解决了默认 bridge 网络 IP 动态变化的问题;
  • 更好的网络隔离:不同自定义网络之间默认隔离,无法直接通信;
  • 灵活的地址管理:可自定义子网、网关、IP 地址范围,避免与宿主机网络冲突。
6.2.3 不同自定义网络互通

不同自定义网络的容器默认无法通信,可通过docker network connect将容器加入多个网络实现互通:

复制代码
# 1. 分别在两个网络启动容器
docker run -d --name web1 --network my_net1 nginx
docker run -it --name test --network my_net2 busybox

# 2. 将test容器加入my_net1网络
docker network connect my_net1 test

# 3. 此时test容器拥有两个网络的网卡,可与my_net1的web1容器通信
docker exec -it test ifconfig
docker exec -it test ping web1

6.3 joined 容器网络模式

joined 容器是一种特殊的网络模式,容器创建时通过--network=container:已运行容器名指定,使多个容器共享同一个网络栈。

  • 核心特点:多个容器共用同一个 IP、端口、网络设备,容器之间可通过localhost直接通信,网络性能极高;
  • 典型应用场景:需要在同一个网络命名空间内配合工作的多容器应用,如网络抓包、sidecar 代理、phpmyadmin 与 mysql 组合。

实战示例:phpmyadmin 与 mysql 共享网络栈

复制代码
# 1. 启动phpmyadmin容器
docker run -d --name mysqladmin --network my_net1 \
-e PMA_ARBITRARY=1 \
-p 80:80 phpmyadmin:latest

# 2. 启动mysql容器,加入phpmyadmin的网络栈
docker run -d --name mysql \
-e MYSQL_ROOT_PASSWORD='lee' \
--network container:mysqladmin \
mysql:5.7

效果:phpmyadmin 容器内可直接通过localhost:3306访问 mysql 数据库,无需端口暴露与网络互通配置。

6.4 容器内外网访问原理

6.4.1 容器访问外网
  • 容器通过 docker0 网桥的网关(默认 172.17.0.1)将流量转发到宿主机;
  • 宿主机通过 iptables/nftables 的MASQUERADE(地址伪装) 策略,将容器内网 IP 的流量转换为宿主机 IP,实现外网访问;
  • 可通过iptables -t nat -nL查看 nat 表中的地址伪装规则。
6.4.2 外网访问容器
  • 外网访问容器通过端口映射 实现,格式为-p 宿主机端口:容器端口
  • 底层实现两种机制:
    1. docker-proxy 进程:监听宿主机端口,将流量转发到容器内对应端口;
    2. DNAT 目标地址转换:通过 iptables nat 表的 DNAT 规则,将宿主机端口的流量直接转发到容器 IP 的对应端口;
  • 两种机制同时生效,系统会自动选择传输效率更高的路径。

6.5 Docker 跨主机网络

生产环境中容器分布在多台宿主机上,需要实现跨主机的容器通信,主流解决方案分为两类:

  1. Docker 原生方案:overlay 网络、macvlan 网络;
  2. 第三方网络方案:flannel、weave、calico(企业生产环境主流)。
6.5.1 CNM 容器网络模型

Docker 通过 CNM(Container Network Model)对容器网络进行抽象,实现了网络方案与 Docker 引擎的解耦,核心三大组件:

  • Sandbox:容器网络栈,包含容器网卡、DNS、路由表,对应 Linux 网络命名空间;
  • Endpoint:将 Sandbox 接入 Network,对应 veth pair 虚拟网卡对;
  • Network:包含一组 Endpoint,同一 Network 内的 Endpoint 可直接通信,对应 Linux 网桥、vxlan 隧道等。
6.5.2 macvlan 跨主机网络实现

macvlan 是 Linux 内核提供的网卡虚拟化技术,无需 Linux 网桥,直接让容器接口与物理网卡连接,性能极高,无需 NAT 和端口映射。实现步骤

两台 Docker 宿主机均添加一块网卡,开启混杂模式

复制代码
# 两台主机均执行
ip link set eth1 promisc on
ip link set up eth1

两台主机创建相同配置的 macvlan 网络

复制代码
docker network create \
-d macvlan \
--subnet 1.1.1.0/24 \
--gateway 1.1.1.1 \
-o parent=eth1 macvlan1

跨主机通信测试

复制代码
# 主机1启动容器,指定固定IP
docker run -it --name busybox --network macvlan1 --ip 1.1.1.100 --rm busybox

# 主机2启动容器,指定固定IP
docker run -it --name busybox --network macvlan1 --ip 1.1.1.200 --rm busybox

# 两个容器可直接ping通对方IP,实现跨主机通信

七、Docker 数据卷管理

Docker 数据卷是可供容器使用的特殊目录,绕过容器的分层文件系统,直接将数据存储在宿主机上,实现容器数据的持久化与共享。

7.1 数据卷核心价值

Docker 分层文件系统存在两大核心问题:

  1. 性能差:读写操作需要经过多层镜像叠加,远低于宿主机本地磁盘性能;
  2. 生命周期与容器绑定:容器删除后,容器内的所有数据会一并丢失。

数据卷完美解决了以上问题,核心价值:

  • 数据持久化:数据卷生命周期独立于容器,容器删除 / 重建,数据卷中的数据不会丢失;
  • 高性能:直接挂载宿主机文件系统,与宿主机磁盘性能一致;
  • 数据共享:多个容器可同时挂载同一个数据卷,实现数据共享与交互;
  • 配置解耦:将应用配置、业务数据与容器镜像解耦,镜像无需包含可变数据,提升可移植性。

Docker 提供了两种数据卷类型:bind mount(绑定挂载)docker managed volume(Docker 管理卷)

7.2 Bind Mount(绑定挂载)

将宿主机上的指定目录 / 文件,直接挂载到容器内的指定路径,是最直观、最常用的挂载方式。

  • 用法:-v 宿主机路径:容器内路径:权限,权限可选ro(只读)、rw(读写,默认);
  • 特点:挂载路径可任意指定,灵活性极高;若宿主机路径不存在,挂载时会自动创建。

实战示例

复制代码
docker run -it --rm \
# 读写挂载宿主机/tmp/data1到容器/data1
-v /tmp/data1:/data1 \
# 只读挂载宿主机/tmp/data1到容器/data2,容器内无法修改
-v /tmp/data1:/data2:ro \
# 只读挂载宿主机文件到容器内
-v /etc/passwd:/data/passwd:ro \
busybox

7.3 Docker Managed Volume(Docker 管理卷)

无需指定宿主机挂载源路径,Docker 自动在/var/lib/docker/volumes/目录下为容器创建数据卷目录,统一管理。

  • 核心优势:无需关注宿主机路径,移植性强,适合跨环境部署;
  • 关键特性:若挂载的容器内路径已有文件,Docker 会将原有文件复制到数据卷中,不会覆盖。

实战示例

手动创建管理卷

复制代码
# 创建自定义管理卷
docker volume create leevol1
# 查看所有管理卷
docker volume ls
# 查看卷的宿主机路径
docker volume inspect leevol1

容器使用管理卷

复制代码
# 启动nginx容器,将网站目录挂载到自定义管理卷
docker run -d --name web1 -p 80:80 -v leevol1:/usr/share/nginx/html nginx

# 宿主机直接修改卷内文件,容器内实时生效
cd /var/lib/docker/volumes/leevol1/_data
echo "hello docker volume" > index.html
# 测试访问
curl 127.0.0.1

匿名管理卷不指定卷名,仅指定容器内路径,Docker 自动创建匿名卷,示例:

复制代码
# 启动mysql容器,自动创建匿名卷挂载/var/lib/mysql
docker run -d --name mysql -e MYSQL_ROOT_PASSWORD='lee' mysql:5.7

清理未使用的管理卷

复制代码
# 清理所有未被容器挂载的管理卷(不可逆,需谨慎操作)
docker volume prune

7.4 数据卷容器与数据备份迁移

7.4.1 数据卷容器

数据卷容器是专门用于管理数据卷的容器,其他容器可通过--volumes-from继承其挂载配置,实现多个容器之间批量、统一的挂载管理,适用于多容器共享大量数据卷的场景。

实战示例

创建数据卷容器

复制代码
docker run -d --name datavol \
-v /tmp/data1:/data1:rw \
-v /tmp/data2:/data2:ro \
-v /etc/resolv.conf:/etc/hosts \
busybox

其他容器继承挂载配置

复制代码
docker run -it --name test --rm --volumes-from datavol busybox
# 进入容器后可看到所有继承的挂载点,与datavol容器完全一致
ls /
7.4.2 数据卷备份与迁移
复制代码
# 数据卷备份:将datavol容器的data1目录打包备份到宿主机当前目录
docker run --volumes-from datavol \
-v `pwd`:/backup busybox \
tar zcf /backup/data1.tar.gz /data1

# 数据卷恢复:将备份包解压到目标数据卷中
docker run -it --name test -v leevol1:/data1 -v `pwd`:/backup busybox /bin/sh -c "tar zxf /backup/data1.tar.gz -C /"

7.5 两种数据卷类型对比

对比维度 Bind Mount(绑定挂载) Docker Managed Volume(管理卷)
卷存储位置 可任意指定宿主机路径 固定在 /var/lib/docker/volumes/
移植性 与宿主机路径绑定,移植性弱 无需关注宿主机路径,移植性强
单个文件支持 支持挂载单个文件 仅支持挂载目录
已有目录影响 容器内挂载点原有内容会被宿主机目录覆盖 容器内挂载点原有内容会被复制到卷中
权限控制 支持读写 / 只读权限设置 无精细化权限控制,默认可读写
适用场景 宿主机与容器固定配置、代码共享、本地开发 生产环境数据持久化、容器间数据共享、无需关注宿主机路径的场景

八、Docker 安全与资源限制

Docker 容器的安全性核心依赖 Linux 系统自身的安全机制,同时 Docker 提供了丰富的资源限制与安全加固能力。

8.1 Docker 安全核心评估维度

  1. Linux 命名空间机制:提供容器的基础隔离,包括 PID、NET、MNT、UTS、IPC、USER 等命名空间,实现容器之间、容器与宿主机的进程、网络、文件系统隔离;
  2. Linux 控制组(Cgroups)机制:限制容器对 CPU、内存、磁盘 IO 等宿主机资源的使用,防止容器资源耗尽导致宿主机宕机,抵御 DDoS 攻击;
  3. Linux 内核能力机制(Capabilities):对容器 root 用户进行细粒度的权限控制,禁用非必需的 root 权限,降低权限逃逸风险;
  4. Docker 服务端防护:Docker daemon 守护进程需要 root 权限运行,需严格控制对 Docker 服务的访问权限,防止未授权访问;
  5. 其他安全增强机制:如 SELinux/AppArmor 强制访问控制、镜像安全扫描、签名校验等。

补充:RHEL 9 系统默认使用 cgroup-v2,不利于观察 Docker 资源限制,可切换为 cgroup-v1:

bash

运行

复制代码
grubby --update-kernel=/boot/vmlinuz-$(uname -r) \
--args="systemd.unified_cgroup_hierarchy=0 systemd.legacy_systemd_cgroup_controller"
# 重启系统生效
reboot

8.2 基于 Cgroups 的资源限制

Linux Cgroups(Control Group)可限制进程组的资源使用上限,Docker 通过 Cgroups 实现容器的资源配额管理,核心限制维度包括 CPU、内存、磁盘 IO。

8.2.1 CPU 资源限制

限制 CPU 使用率 通过--cpu-period--cpu-quota配合,限制容器在一个调度周期内可使用的 CPU 时间:

复制代码
# 限制容器最多使用20%的单核CPU
# cpu-period:CPU调度周期,默认100000微秒(100毫秒)
# cpu-quota:周期内可使用的CPU时间,20000即20%单核CPU
docker run -it --rm --name test \
--cpu-period 100000 \
--cpu-quota 20000 \
ubuntu

限制 CPU 优先级 通过--cpu-shares设置 CPU 权重,默认值 1024,值越大,CPU 资源争抢时优先级越高:

复制代码
# 设置容器CPU权重为100,优先级低于默认值
docker run -it --rm --cpu-shares 100 ubuntu
8.2.2 内存资源限制

通过--memory限制容器最大可使用的物理内存,--memory-swap限制内存 + 交换分区的总上限:

复制代码
# 限制容器最大使用200M物理内存,且禁用swap(swap=内存大小)
docker run -d --name test --memory 200M --memory-swap 200M nginx

# 查看容器内存限制配置
cat /sys/fs/cgroup/memory/docker/容器ID/memory.limit_in_bytes

关键注意事项:若不设置--memory-swap,容器默认可使用的 swap 大小为--memory值的 2 倍;若设置--memory-swap--memory值相同,则容器无法使用 swap。

8.2.3 磁盘 IO 资源限制

通过--device-write-bps/--device-read-bps限制容器对磁盘的读写速率,--device-write-iops/--device-read-iops限制读写 IOPS:

复制代码
# 限制容器对/dev/nvme0n1磁盘的写入速率不超过30MB/s
docker run -it --rm \
--device-write-bps /dev/nvme0n1:30M \
ubuntu

# 测试写入速率,direct模式跳过系统缓存,直接写入磁盘
dd if=/dev/zero of=bigfile bs=1M count=100 oflag=direct

8.3 Docker 安全加固方案

8.3.1 解决容器资源可见性问题

默认情况下,容器内freetop等命令会读取宿主机的资源信息,无法看到容器自身的资源限制,可通过 LXCFS 工具解决该问题。

LXCFS 可使容器内进程看到准确的 CPU、内存等资源使用信息,适配容器内应用的资源评估与监控需求。

部署与使用

安装 LXCFS

复制代码
dnf install lxcfs -y

后台运行 LXCFS

复制代码
lxcfs /var/lib/lxcfs &

启动容器挂载 LXCFS,实现资源可见性隔离

复制代码
docker run -it -m 256m \
-v /var/lib/lxcfs/proc/cpuinfo:/proc/cpuinfo:rw \
-v /var/lib/lxcfs/proc/diskstats:/proc/diskstats:rw \
-v /var/lib/lxcfs/proc/meminfo:/proc/meminfo:rw \
-v /var/lib/lxcfs/proc/stat:/proc/stat:rw \
-v /var/lib/lxcfs/proc/swaps:/proc/swaps:rw \
-v /var/lib/lxcfs/proc/uptime:/proc/uptime:rw \
ubuntu

# 容器内执行free -m,可看到内存上限为256M,与限制一致
free -m
8.3.2 容器权限管理
  1. 特权模式(--privileged) 默认情况下,容器内的 root 用户仅拥有有限的内核权限,无法修改网络配置、挂载磁盘、管理设备等敏感操作。开启--privileged=true后,容器将获得宿主机 root 的几乎所有权限。

    开启特权模式启动容器

    docker run --rm -it --privileged busybox

    容器内可正常修改网卡配置、查看磁盘分区等敏感操作

    ip a a 192.168.0.100/24 dev eth0
    fdisk -l

安全警告:特权模式极大提升了容器权限,存在严重的权限逃逸风险,生产环境禁止使用

  1. Capabilities 权限白名单 为避免特权模式的权限滥用,Docker 提供了--cap-add参数,仅为容器添加必需的最小权限,实现权限最小化。

常用权限示例:

复制代码
# 仅为容器添加网络管理权限,无需开启完整特权模式
docker run --rm -it --cap-add NET_ADMIN busybox
# 容器内可正常修改网络配置,其他敏感权限仍被禁用
ip a a 192.168.0.100/24 dev eth0

企业最佳实践:遵循最小权限原则,禁止使用特权模式,仅为容器添加业务必需的 Capabilities 权限。

九、Docker Compose 容器编排

Docker Compose 是 Docker 官方提供的多容器应用编排工具,通过 YAML 文件定义一组关联的容器服务,实现一键启动、停止、管理整个应用的所有容器,解决了多容器应用手动管理效率低、依赖关系复杂的问题。

9.1 Compose 核心概述

9.1.1 核心功能
  1. 服务定义:通过 YAML 配置文件定义应用的所有服务、镜像、端口、环境变量、挂载、网络等参数;
  2. 一键生命周期管理:通过单条命令完成整个应用的启动、停止、重启,无需逐个操作容器;
  3. 服务依赖编排:定义容器之间的启动依赖顺序,确保服务按正确的顺序启动(如数据库先启动,Web 服务后启动);
  4. 统一网络管理:自动为应用创建专属网络,服务之间可通过服务名直接通信,无需手动配置网络;
  5. 多环境配置管理:通过环境变量实现开发、测试、生产环境的配置隔离。
9.1.2 核心架构概念

Docker Compose 分为三层架构:

  1. 项目(Project) :由一组关联的应用容器组成的完整业务单元,对应一个docker-compose.yml文件;
  2. 服务(Service):一个应用的容器定义,一个服务可包含多个运行相同镜像的容器实例;
  3. 容器(Container):服务的具体运行实例,基于服务定义的镜像创建。
9.1.3 工作原理
  1. Docker Compose 读取并解析 YAML 配置文件;
  2. 调用 Docker Engine API,根据配置创建对应的网络、数据卷、容器;
  3. 监控容器状态,根据配置处理容器的启动顺序、故障重启、生命周期管理。

9.2 Compose 核心命令详解

Compose 命令通用格式:docker compose [选项] [命令],核心命令分类如下:

9.2.1 服务生命周期管理
命令 功能说明 常用示例
up 启动配置文件中定义的所有服务,自动创建网络、卷、容器 docker compose up -d(后台启动)docker compose -f ./test.yml up -d(指定配置文件)docker compose up --build(启动前重新构建镜像)
down 停止并删除 up 命令创建的所有容器、网络,默认不删除数据卷 docker compose down``docker compose down -v(同时删除数据卷)
start 启动已存在的服务,不创建新容器 docker compose start``docker compose start web(仅启动 web 服务)
stop 停止正在运行的服务,不删除容器 docker compose stop``docker compose stop db(仅停止 db 服务)
restart 重启配置文件中的所有服务 docker compose restart
9.2.2 服务状态查看
命令 功能说明 常用示例
ps 列出服务对应的容器、状态、端口映射等信息 docker compose ps
logs 查看服务的日志输出 docker compose logs db(查看 db 服务日志)docker compose logs -f web(实时刷新 web 服务日志)
9.2.3 镜像构建相关
命令 功能说明 常用示例
build 构建配置文件中定义的服务镜像 docker compose build``docker compose build test1(仅构建 test1 服务)
pull 拉取配置文件中定义的所有服务镜像 docker compose pull
9.2.4 其他常用命令
命令 功能说明 常用示例
exec 在运行中的服务容器内执行命令 docker compose exec web sh(进入 web 服务容器终端)
config 验证 YAML 配置文件语法,并输出解析后的完整配置 docker compose config``docker compose config -q(仅校验语法,无输出则配置正确)

9.3 Compose YAML 配置文件核心语法

Docker Compose 的 YAML 配置文件核心分为三大顶级配置块:services(服务定义)、networks(网络定义)、volumes(数据卷定义)。

基础配置示例:

复制代码
version: "3.8"
# 服务定义块:核心配置,定义应用的所有服务
services:
  # 服务名称:web
  web:
    # 服务使用的镜像
    image: nginx:latest
    # 容器名称
    container_name: webserver
    # 端口映射
    ports:
      - "80:80"
    # 重启策略:always表示容器退出时始终重启
    restart: always
    # 环境变量
    environment:
      - TZ=Asia/Shanghai
    # 数据卷挂载
    volumes:
      - ./html:/usr/share/nginx/html:ro
      - nginx_data:/var/log/nginx
    # 网络配置
    networks:
      - app_net

  # 服务名称:db
  db:
    image: mysql:5.7
    container_name: mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: "123456"
      TZ=Asia/Shanghai
    volumes:
      - mysql_data:/var/lib/mysql
    networks:
      - app_net
    # 暴露端口,仅对同网络服务可见,不映射到宿主机
    expose:
      - 3306

# 网络定义块:定义应用使用的网络
networks:
  # 自定义网络名称
  app_net:
    # 网络驱动,bridge为单主机网络,overlay为跨主机网络
    driver: bridge
    # 自定义子网与网关
    ipam:
      driver: default
      config:
        - subnet: 172.28.0.0/16
          gateway: 172.28.0.254

# 数据卷定义块:定义Docker管理卷
volumes:
  # 定义mysql数据卷
  mysql_data:
    name: mysql_data
  # 定义nginx日志数据卷
  nginx_data:
    name: nginx_data

核心配置项详解:

  1. services 核心配置

    • image:服务使用的 Docker 镜像,必填项(或通过 build 指定 Dockerfile 构建);

    • build:指定 Dockerfile 路径,基于 Dockerfile 构建镜像,示例:

      yaml

      复制代码
      build:
        context: ./app  # 构建上下文目录
        dockerfile: Dockerfile  # Dockerfile名称
    • ports:端口映射,格式为"宿主机端口:容器端口"

    • expose:声明容器暴露的端口,仅对同网络服务可见,不映射到宿主机;

    • environment:设置容器内环境变量,支持数组和键值对两种格式;

    • volumes:数据卷挂载,支持绑定挂载和 Docker 管理卷;

    • restart:容器重启策略,可选值:no(不重启,默认)、always(始终重启)、on-failure(异常退出时重启)、unless-stopped(除非手动停止,否则始终重启);

    • command:覆盖容器启动时默认执行的命令;

    • depends_on:定义服务启动依赖顺序,示例:depends_on: [db]表示 db 服务启动后再启动当前服务;

    • networks:指定服务加入的网络。

  2. networks 核心配置

    • driver:网络驱动,常用bridge(单主机)、overlay(Swarm 集群跨主机);
    • external:是否使用外部已存在的网络,true表示不创建新网络,使用已有网络;
    • ipam:自定义 IP 地址管理,可指定子网、网关。
  3. volumes 核心配置

    • name:指定管理卷的名称;
    • external:是否使用外部已存在的数据卷。

9.4 企业级实战示例

基于 Docker Compose 实现 HAProxy + Nginx 的负载均衡架构,2 台 Nginx 作为后端 Web 节点,HAProxy 作为负载均衡入口:

步骤 1:目录与配置文件准备
复制代码
# 创建目录结构
mkdir -p /docker/web/html1 /docker/web/html2 /docker/conf/haproxy
# 准备两个网站首页
echo "web1 server" > /docker/web/html1/index.html
echo "web2 server" > /docker/web/html2/index.html
# 编写haproxy配置文件
vim /docker/conf/haproxy/haproxy.cfg

haproxy.cfg 配置内容:

复制代码
global
    log 127.0.0.1 local0
    maxconn 4096
    chroot /usr/local/etc/haproxy
    user haproxy
    group haproxy
    daemon
    nbproc 1

defaults
    log global
    mode http
    option httplog
    option dontlognull
    retries 3
    option redispatch
    maxconn 2000
    timeout connect 5s
    timeout client 50s
    timeout server 50s

listen http_front
    bind 0.0.0.0:80
    stats uri /haproxy_stats
    mode http
    balance roundrobin
    server web1 web1:80 check inter 2000 rise 2 fall 3
    server web2 web2:80 check inter 2000 rise 2 fall 3
步骤 2:编写 docker-compose.yml 配置文件
复制代码
version: "3.8"

services:
  web1:
    image: nginx:latest
    container_name: web1
    restart: always
    networks:
      - app_net
    expose:
      - 80
    volumes:
      - /docker/web/html1:/usr/share/nginx/html

  web2:
    image: nginx:latest
    container_name: web2
    restart: always
    networks:
      - app_net
    expose:
      - 80
    volumes:
      - /docker/web/html2:/usr/share/nginx/html

  haproxy:
    image: haproxy:2.3
    container_name: haproxy
    restart: always
    networks:
      - app_net
    volumes:
      - /docker/conf/haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg
    ports:
      - "80:80"

networks:
  app_net:
    driver: bridge
步骤 3:一键启动整个应用
复制代码
# 进入配置文件目录,后台启动所有服务
docker compose up -d
# 查看服务运行状态
docker compose ps
步骤 4:效果验证
复制代码
# 多次访问,负载均衡会轮询转发到web1和web2节点
curl 127.0.0.1
# 访问HAProxy监控页面:http://宿主机IP/haproxy_stats
相关推荐
数据库小组10 小时前
10 分钟搞定!Docker 一键部署 NineData 社区版
数据库·docker·容器·database·数据库管理工具·ninedata·迁移工具
灰阳阳12 小时前
Docker镜像远程(离线)迁移教程
运维·docker·容器
KIHU快狐13 小时前
KIHU快狐|台式液晶监视器桌面摆放药店用药安全宣传小屏幕
容器
岁岁种桃花儿13 小时前
kubenetes从入门到上天系列第十四篇:Kubernetes的持久化存储
云原生·容器·kubernetes
糟糕喔14 小时前
harbor私有仓库搭建
运维·docker·云原生·容器·kubernetes
05大叔16 小时前
微服务,拆分原则,远程调用,服务治理,OpenFeign
微服务·云原生·架构
就叫飞六吧19 小时前
K8s 端口暴露:集群统一暴露 vs 单 Pod 暴露
云原生·容器·kubernetes
执笔为剑19 小时前
docker环境升级数据库
数据库·docker·容器
于眠牧北20 小时前
ubuntu22.04安装docker以及安装过程中报错解决方法
运维·docker·容器