Docker 教程

0 阅读20分钟

Docker 教程

本文档系统介绍 Docker 容器技术的核心概念、安装配置、镜像构建、容器管理、数据持久化、网络配置、容器编排(Docker Compose)、监控日志及安全实践,帮助用户掌握容器化应用的完整开发运维流程。

本文档涵盖 Docker 基础概念、镜像与容器操作、Dockerfile 定制、数据卷与网络、Docker Compose 编排、监控告警、私有仓库搭建等完整知识体系。

📚 相关文档:


💡 创作不易,请点个收藏关注!


目录


一、Docker 简介

1.1、什么是 Docker

Docker 是一个开源的应用容器引擎,让开发者可以打包应用及其依赖到一个可移植的容器中,然后发布到任何流行的 Linux 或 Windows 机器上。容器使用沙箱机制,相互隔离且开销极低。

image.png

1.2、Docker 能做什么

应用场景说明
开发环境保持开发、测试、生产环境一致,消除"在我机器上运行正常"的问题
微服务架构轻量级、松耦合、可扩展的容器化服务部署
CI/CD持续集成和持续部署,提高开发和交付效率
云计算弹性、可扩展的云原生应用平台
多租户资源隔离,提高安全性和资源利用率

1.3、Docker vs 虚拟机

对比项Docker 容器传统虚拟机
资源利用率共享宿主机内核,轻量高效运行完整 OS,资源开销大
启动速度秒级启动分钟级启动
镜像大小MB 级(仅应用+依赖)GB 级(完整操作系统)
隔离性进程级隔离系统级强隔离
可移植性跨平台运行依赖特定虚拟化平台
Docker vs 虚拟机架构对比
graph TB
    subgraph VM["传统虚拟机架构"]
        VM_H["Hypervisor / 虚拟机管理器"]
        subgraph VM1["虚拟机 1"]
            VM1_OS["Guest OS (Linux/Windows)"]
            VM1_App1["App A"]
            VM1_App2["App B"]
        end
        subgraph VM2["虚拟机 2"]
            VM2_OS["Guest OS (Linux/Windows)"]
            VM2_App["App C"]
        end
        VM_H --> VM1_OS
        VM_H --> VM2_OS
        VM1_OS --> VM1_App1
        VM1_OS --> VM1_App2
        VM2_OS --> VM2_App
    end

    subgraph Docker["Docker 容器架构"]
        Docker_H["Docker Engine (守护进程)"]
        subgraph C1["容器 1 (nginx)"]
            C1_Lib["依赖库"]
            C1_App["nginx"]
        end
        subgraph C2["容器 2 (mysql)"]
            C2_Lib["依赖库"]
            C2_App["mysql"]
        end
        Docker_H --> C1
        Docker_H --> C2
    end

    Host["宿主机 (Linux/Windows)"]
    Host --> VM_H
    Host --> Docker_H

    style VM fill:#ffcccc
    style Docker fill:#ccffcc
    style Host fill:#cce5ff

核心区别:

  • 虚拟机:每个虚拟机运行完整的操作系统(Guest OS),需要独立的内核,占用大量资源
  • 容器:共享宿主机内核,容器内只包含应用和依赖库,更加轻量

1.4、Docker 架构

组件说明
Docker 引擎由守护进程(daemon)和客户端(CLI)组成,负责容器的创建、运行和管理
Docker 镜像只读模板,包含应用及其依赖,可分层构建和复用
Docker 容器镜像的运行实例,提供隔离的进程、网络和存储空间
Docker Registry镜像仓库服务,Docker Hub 是官方公共仓库
Docker 网络容器通信机制,支持 bridge/host/overlay 等网络模式
Docker 存储数据持久化机制,支持 volume/bind mount/tmpfs
Docker 核心架构图
graph TB
    subgraph Client["Docker 客户端 (CLI)"]
        CLI["docker CLI<br/>用户命令"]
    end

    subgraph Host["Docker 宿主机"]
        subgraph Engine["Docker Engine"]
            API["REST API<br/>接口层"]
            Daemon["Docker Daemon<br/>守护进程"]
            subgraph Components["核心组件"]
                Builder["Builder<br/>镜像构建"]
                Container["Containerd<br/>容器运行时"]
                Network["Network<br/>网络管理"]
                Volume["Volume<br/>存储管理"]
                Plugin["Plugin<br/>插件管理"]
            end
            API --> Daemon
            Daemon --> Components
        end

        subgraph Containers["运行的容器"]
            C1["容器 1"]
            C2["容器 2"]
            Cn["容器 N"]
        end

        subgraph Images["本地镜像"]
            I1["镜像层 1"]
            I2["镜像层 2"]
            I3["镜像层 3"]
        end

        Daemon -. "创建/管理" .-> Containers
        Daemon -. "读取" .-> Images
    end

    subgraph Registry["镜像仓库 (Registry)"]
        Hub["Docker Hub<br/>公共仓库"]
        Private["私有仓库<br/>Harbor/Registry"]
    end

    CLI -->|"命令"| API
    Images <-. "拉取/推送" .-> Hub
    Images <-. "拉取/推送" .-> Private

    style Client fill:#e3f2fd
    style Host fill:#fff3e0
    style Registry fill:#f3e5f5
    style Daemon fill:#ffcdd2

工作流程:

  1. 用户通过 CLI 发送命令(如 docker run
  2. CLI 通过 REST API 与 Daemon 通信
  3. Daemon 调用 Containerd 管理容器生命周期
  4. 如本地无镜像,从 Registry 拉取
  5. 容器运行时创建隔离的进程、网络、存储空间

二、Docker 安装

2.1、Ubuntu 安装

Docker 支持 Linux、Windows 和 macOS。以下是在 Ubuntu 上安装的步骤:

  1. 更新系统软件包列表:
sudo apt-get update
  1. 安装Docker的依赖包:
sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg \
    lsb-release
  1. 添加Docker的APT仓库:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
"deb [arch=amd64 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
  1. 更新APT仓库:
sudo apt-get update
  1. 安装Docker Engine:
sudo apt-get install docker-ce docker-ce-cli containerd.io
  1. 验证Docker是否安装成功:
sudo docker run hello-world
  1. 启动Docker服务:
sudo systemctl start docker
  1. 设置Docker开机自启动:
sudo systemctl enable docker
  1. 配置Docker镜像加速器(可选):
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
    {
    "registry-mirrors": ["https://<your-mirror-url>"]
    }
    EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
  1. 添加Docker用户组(可选):
sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker

2.2、镜像加速配置

国内用户建议配置镜像加速器以提高下载速度:

镜像源地址
阿里云https://<your-id>.mirror.aliyuncs.com
网易云https://hub-mirror.c.163.com
腾讯云https://mirror.ccs.tencentyun.com
DaoCloudhttps://docker.m.daocloud.io
中科大https://docker.mirrors.ustc.edu.cn

配置方法(以阿里云为例):

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://<your-id>.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

2.3、免 sudo 配置

将用户加入 docker 组,避免每次执行 docker 命令都需要 sudo:

sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker  # 重新加载组权限
docker run hello-world  # 验证

三、Docker 基础命令

3.1、镜像管理

命令说明示例
docker pull拉取镜像docker pull nginx:latest
docker images列出本地镜像docker images
docker rmi删除镜像docker rmi nginx:latest
docker build构建镜像docker build -t myapp:1.0 .
docker tag标记镜像docker tag nginx myregistry/nginx:v1
docker push推送镜像docker push myregistry/nginx:v1

3.2、容器管理

命令说明示例
docker run创建并启动容器docker run -d -p 80:80 nginx
docker ps列出运行中容器docker ps -a
docker start/stop/restart启停容器docker stop container_id
docker rm删除容器docker rm -f container_id
docker exec执行容器内命令docker exec -it container_id bash
docker logs查看容器日志docker logs -f container_id
docker inspect查看容器详情docker inspect container_id

3.3、常用命令速查

# 清理无用资源
docker system prune          # 清理未使用的数据
docker volume prune          # 清理未使用的卷
docker image prune           # 清理未使用的镜像

# 查看资源占用
docker system df             # 磁盘使用情况
docker stats                 # 实时资源监控

# 容器操作技巧
docker cp container:/path/to/file .   # 复制文件到本地
docker top container_id               # 查看容器进程
docker port container_id              # 查看端口映射

四、Dockerfile 镜像定制

Dockerfile 工作流程
graph LR
    subgraph Build["镜像构建过程"]
        DF["Dockerfile<br/>构建文件"] -->|"docker build"| Layer["镜像层<br/>Layer 1, 2, 3..."]
        Layer -->|"叠加"| Image["最终镜像<br/>Image"]
    end

    subgraph Dockerfile["Dockerfile 指令顺序"]
        A["FROM<br/>基础镜像"] --> B["MAINTAINER<br/>维护者"]
        B --> C["RUN<br/>执行命令"]
        C --> D["COPY/ADD<br/>复制文件"]
        D --> E["ENV<br/>环境变量"]
        E --> F["EXPOSE<br/>端口声明"]
        F --> G["VOLUME<br/>数据卷"]
        G --> H["WORKDIR<br/>工作目录"]
        H --> I["USER<br/>用户"]
        I --> J["CMD/ENTRYPOINT<br/>启动命令"]
    end

    subgraph Lifecycle["镜像与容器"]
        Image -->|"docker run"| Container["容器<br/>Container"]
        Container -->|"docker commit"| Image2["新镜像"]
    end

    style Build fill:#e8f5e9
    style Dockerfile fill:#fff3e0
    style Lifecycle fill:#e3f2fd

Dockerfile 指令执行顺序说明:

  • 指令按从上到下顺序执行
  • 每条指令创建一个新的镜像层
  • 前面的层会被后面的层覆盖
  • 频繁变化的指令(如 COPY、RUN)放在后面,优化构建缓存

4.1、Dockerfile 指令

Dockerfile是一个文本文件,其中包含了用于构建Docker镜像的指令。以下是一些常用的Dockerfile指令:

  • FROM:指定基础镜像。

    • 作用:基于某个镜像构建新的镜像,即指定基础镜像。
    • 格式:FROM <image>[:<tag>],其中<image>是镜像名称,<tag>是镜像标签。
  • MAINTAINER:指定维护者信息。

    • 作用:指定镜像的维护者信息。
    • 格式:MAINTAINER <name> <email>,其中<name>是维护者名称,<email>是维护者邮箱。
  • RUN:执行命令。

    • 作用:在构建镜像时执行命令。
    • 格式:RUN <command>,其中<command>是要执行的shell命令。
  • CMD:容器启动时执行的命令。

    • 作用:指定容器启动时执行的命令。
    • 格式:CMD ["executable","param1","param2"],其中executable是要执行的命令,param1param2是命令的参数。
  • ENTRYPOINT:容器启动时执行的命令。

    • 作用:指定容器启动时执行的主命令。
    • 格式:ENTRYPOINT ["executable","param1","param2"],其中executable是要执行的命令,param1param2是命令的参数。
  • COPY:复制文件到镜像中。

    • 作用:将本地文件或目录复制到镜像中。
    • 格式:COPY <src> <dst>,其中<src>是本地文件或目录的路径,<dst>是镜像中的目标路径。
  • ADD:复制文件到镜像中,并自动处理URL和解压tar文件。

    • 作用:将本地文件或目录复制到镜像中,并自动处理URL和解压tar文件。
    • 格式:ADD <src> <dst>,其中<src>是本地文件或目录的路径,<dst>是镜像中的目标路径。
  • ENV:设置环境变量。

    • 作用:设置环境变量。
    • 格式:ENV <key>=<value>,其中<key>是环境变量的名称,<value>是环境变量的值。
  • EXPOSE:声明容器监听的端口。

    • 作用:声明容器监听的端口。
    • 格式:EXPOSE <port> [<port>/<protocol>...],其中<port>是端口号,<protocol>是协议(如tcp、udp)。
  • VOLUME:声明容器挂载的卷。

    • 作用:声明容器挂载的卷。
    • 格式:VOLUME ["/data"],其中/data是卷的路径。
  • WORKDIR:设置工作目录。

    • 作用:设置工作目录。
    • 格式:WORKDIR /path/to/workdir,其中/path/to/workdir是工作目录的路径。后续指令(如 COPY、RUN)在此目录下执行。
  • USER:设置运行命令的用户。

    • 作用:设置运行命令的用户。
    • 格式:USER <user>[:<group>],其中<user>是用户名,<group>是组名。
  • ONBUILD:为镜像添加触发器。

    • 作用:为镜像添加触发器,当该镜像作为其他镜像的基础镜像时,触发器会被执行。
    • 格式:ONBUILD <INSTRUCTION>,其中<INSTRUCTION>是要执行的指令。
  • ARG:定义构建时的变量,构建时通过 --build-arg 传递。

    • 作用:定义构建时的变量,构建时通过 --build-arg 传递。
    • 格式:ARG <name>[=<default>],其中<name>是变量名,<default>是默认值。

4.2、镜像构建流程

镜像定制是指通过修改基础镜像,添加自定义的配置、软件包、环境变量等,生成新的镜像。

定制镜像的步骤如下:

  1. 创建一个Dockerfile文件,其中包含定制镜像所需的指令。
  2. 使用docker build命令构建镜像,指定Dockerfile文件和构建上下文路径。
  3. 使用docker images命令查看生成的镜像。
  4. 使用docker run命令运行镜像,启动容器。
  5. 使用docker commit命令将容器保存为新的镜像。
  6. 使用docker push命令将镜像推送到Docker Hub或其他镜像仓库。
  7. 使用docker pull命令从镜像仓库拉取镜像。

4.3、实战案例:Redis 镜像

4.3.1、编写 Dockerfile

以下是一个简单的Redis镜像定制的Dockerfile示例:

# 使用官方的Redis镜像作为基础镜像
FROM redis
# 设置环境变量
ENV REDIS_PASSWORD=mysecret
# 复制自定义的配置文件到镜像中
COPY redis.conf /usr/local/etc/redis/redis.conf
# 暴露Redis默认端口
EXPOSE 6379
# 容器启动时执行的命令
CMD ["redis-server", "/usr/local/etc/redis/redis.conf"]
4.3.2、构建镜像

使用以下命令构建镜像:

docker build -t my-redis .

其中,-t参数指定镜像的名称和标签,.表示构建上下文路径。


五、数据管理与网络

5.1、数据卷(Volume)

Docker提供了两种数据管理方式:数据卷(Volumes)和绑定挂载(Bind mounts)。

Docker 存储类型对比
graph TB
    subgraph Volumes["数据卷 (Volume)"]
        V1["Docker 管理<br/>/var/lib/docker/volumes/"]
        V2["容器 A"]
        V3["容器 B"]
        V4["持久化数据<br/>独立于容器生命周期"]
        V1 --> V2
        V1 --> V3
        V2 -. "共享访问".-> V1
        V3 -. "共享访问".-> V1
        V1 --> V4
    end

    subgraph BindMount["绑定挂载 (Bind Mount)"]
        B1["宿主机目录<br/>/home/user/data"]
        B2["容器内目录<br/>/app/data"]
        B1 --> B2
        B3["直接访问宿主机文件"]
    end

    subgraph Tmpfs["tmpfs (内存存储)"]
        T1["内存<br/>/dev/shm"]
        T2["容器内目录<br/>/app/secrets"]
        T1 --> T2
        T3["数据不持久化<br/>高性能敏感数据"]
    end

    Host["宿主机文件系统"]

    style Volumes fill:#e8f5e9
    style BindMount fill:#fff3e0
    style Tmpfs fill:#fce4ec
存储类型存储位置生命周期性能适用场景
VolumeDocker 管理目录独立于容器,可持久化生产环境数据持久化
Bind Mount宿主机任意路径依赖宿主机开发调试,访问宿主机文件
tmpfs内存中随容器删除最高敏感数据,临时缓存
5.1.1、创建和管理数据卷

数据卷是Docker中的一种特殊类型的存储,它可以在容器之间共享,并且在容器停止后仍然存在。数据卷可以用于存储持久化数据,也可以用于在容器之间共享数据。

  1. 创建数据卷:
docker volume create my_volume
  1. 查看数据卷:
docker volume ls
  1. 在容器中操作数据卷:
docker run -v my_volume:/data my_image
  1. 删除数据卷:
docker volume rm my_volume
5.1.2、绑定挂载(Bind Mount)

绑定挂载是将宿主机上的文件或目录挂载到容器中,类似于Linux中的mount命令。绑定挂载可以用于在容器中访问宿主机上的文件或目录,也可以用于在容器中存储数据。

  1. 在容器中操作绑定挂载:
docker run -v /path/on/host:/path/in/container my_image

其中,/path/on/host是宿主机上的路径,/path/in/container是容器中的路径。

  1. 删除绑定挂载:
docker rm -v my_container

5.2、数据备份与迁移

5.2.1、备份数据

可以使用docker export命令将容器的文件系统导出为tar文件,从而实现数据的备份。

docker export my_container > my_container_backup.tar
5.2.2、恢复数据

可以使用docker import命令将tar文件导入为新的镜像,从而实现数据的恢复。

docker import my_container_backup.tar my_image
5.2.3、迁移数据

可以使用docker save命令将镜像保存为tar文件,从而实现数据的迁移。

docker save my_image > my_image.tar

可以使用docker load命令将tar文件加载为镜像,从而实现数据的迁移。

docker load < my_image.tar

5.3、Docker 网络

Docker提供了多种网络模式,包括bridge、host、overlay等。默认情况下,Docker使用bridge网络模式,每个容器都会分配一个独立的IP地址。

  1. 查看网络列表:
docker network ls
  1. 创建自定义网络:
docker network create my_network
  1. 在容器中使用自定义网络:
docker run --network=my_network my_image
  1. 删除网络:
docker network rm my_network
5.3.1、同一宿主机容器通信

在同一宿主机上的容器之间,可以通过容器的IP地址或容器名进行通信。例如,如果容器A的IP地址是172.17.0.2,容器B的IP地址是172.17.0.3,那么容器A可以通过172.17.0.3containerB与容器B进行通信。

默认桥接网络(Bridge) Docker 默认创建名为 bridge 的网络,所有容器自动加入该网络,但只能通过 IP 地址通信。容器无法通过名称通信。

操作步骤:

# 运行两个容器(自动加入默认桥接网络)
docker run -d --name web nginx
docker run -it --name client alpine

# 进入 client 容器测试通信
docker exec -it client sh
ping 172.17.0.2  # 替换为 web 容器的实际IP
curl http://172.17.0.2

自定义网络 创建自定义网络,并指定容器加入该网络,可以解决容器间通过容器名通信的问题。

优势:

  • 容器可以通过容器名进行通信,无需知道对方的IP地址。
  • 容器可以加入多个网络,实现更复杂的网络拓扑。
  • 自动DNS解析,容器可以通过容器名进行通信。

操作步骤:

# 1. 创建自定义网络
docker network create my_network

# 2. 将容器加入同一网络
docker run -d --name web --network my_network nginx
docker run -it --name client --network my_network alpine

# 3. 测试名称解析
docker exec -it client ping web  # 直接使用容器名
curl http://web

容器直连(--link) 通过 --link 参数建立单向通信(已过时,仅适用于旧版 Docker),被链接容器需先启动。仅适用于默认桥接网络。

操作步骤:

docker run -d --name mysql mysql:5.7
docker run --link mysql:db --name app myapp

# 在 app 容器中可通过别名访问
ping db
curl http://db

共享网络命名空间(--network=container) 将容器加入另一个容器的网络命名空间,实现容器间共享网络栈。Sidecar 模式(日志收集/监控代理)。需要零延迟通信的场景。

操作步骤:

# 1. 启动主容器
docker run -d --name web nginx

# 2. 启动副容器共享其网络
docker run -it --network container:web --name monitor alpine

# 在 monitor 容器中访问 web 服务
curl http://localhost

Host网络(--network=host) 将容器加入宿主机的网络命名空间,容器与宿主机共享网络栈。容器没有独立的网络栈,无法与其他容器通信。容器内服务监听端口与宿主机端口相同。

操作步骤:

# 容器1 暴露端口
docker run -d --network host --name web nginx

# 容器2 访问服务
docker run --network host --name client curl http://localhost

端口映射穿透(-p参数) 将宿主机的端口映射到容器的端口,实现容器与宿主机之间的通信。容器内服务监听端口与宿主机端口不同。

操作步骤:

# 容器暴露端口
docker run -d -p 8080:80 --name web nginx

# 其他容器通过宿主机IP访问
curl http://宿主机IP:8080

选择建议:

场景网络模式特点
临时测试默认桥接网络快速启动,无需配置
多容器通信自定义网络容器名通信,可加入多个网络
单向通信--link参数已过时,仅适用于旧版 Docker
监控/日志代理共享网络命名空间 --network=containerSidecar 模式,零延迟通信
高性能需求Host 网络模式 --network=host无NAT损耗,但牺牲安全性
Docker 网络模式对比图
graph TB
    subgraph Host["宿主机 (Host)"]
        subgraph Bridge["Bridge 网络"]
            C1["容器 1<br/>nginx"]
            C2["容器 2<br/>mysql"]
        end

        subgraph Host_Network["Host 网络"]
            C3["容器 3<br/>直接使用宿主机网络"]
        end

        subgraph Custom["自定义网络"]
            C4["容器 4"]
            C5["容器 5"]
            C4 <--> C5
        end

        subgraph Container_Network["共享网络 (container:)"]
            C6["主容器<br/>web"]
            C7["副容器<br/>monitor<br/>共享网络栈"]
        end
    end

    External["外部网络"]
    Internet["互联网"]

    External -->|"NAT"| Bridge
    External -->|"直接访问"| Host_Network
    C1 <-->|"Docker DNS"| C2

    style Bridge fill:#e3f2fd
    style Host_Network fill:#fff3e0
    style Custom fill:#e8f5e9
    style Container_Network fill:#fce4ec
5.3.2、跨主机容器通信

我需要考虑不同跨主机通信的技术方案。常见的包括Overlay网络(如Docker Swarm)、第三方网络插件(如Calico、Flannel)、VPN隧道、云服务商的内网方案以及API网关或服务网格。每种方案都有其特定的使用场景和配置步骤。

对于每个方案,我需要解释其工作原理,例如Overlay网络如何通过VXLAN封装数据包实现跨主机通信,或者Calico如何利用BGP协议进行路由。然后提供具体的操作步骤,比如如何创建Docker Swarm集群,或如何安装和配置Calico。同时,要指出各个方案的优缺点,例如Overlay网络可能简单易用但性能有损耗,而Calico适合大规模集群但配置复杂。

此外,用户可能关心实际应用中的选择建议,因此需要在最后给出一个对比表格,列出不同方案的特点和适用场景,帮助用户根据具体需求做出决策。例如,小规模部署可能适合Overlay网络或云服务内网,而大规模企业环境可能需要Calico或服务网格。

Overlay网络(如Docker Swarm原生方案) Docker Swarm原生支持Overlay网络,通过VXLAN封装数据包实现跨主机通信,实现跨主机虚拟网络。适用于小规模部署。

操作步骤:

  1. 创建Swarm集群
# 主机1(Manager节点)
docker swarm init --advertise-addr <主机1_IP>

# 主机2(Worker节点)
docker swarm join --token <SWARM_TOKEN> <主机1_IP>:2377
  1. 创建Overlay网络
docker network create --driver overlay my_overlay
  1. 启动容器加入网络
docker service create --network my_overlay --name web nginx

优点: Docker 原生支持,无需第三方工具。

缺点: 适用于中小规模集群,性能有隧道开销。

Calico + BGP 路由(企业级方案) Calico 是一款开源的网络和网络策略解决方案,适用于大规模集群。通过BGP协议实现跨主机路由,性能优异。

操作步骤:

  1. 安装Calico
# 所有主机安装 Calico
curl -O -L https://github.com/projectcalico/calico/releases/download/v3.24.5/calicoctl-linux-amd64
chmod +x calicoctl
sudo mv calicoctl /usr/local/bin/
  1. 配置BGP路由
# 创建Calico配置文件 calico-config.yaml
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
    name: default-ipv4-ippool
spec:
  logSeverityScreen: Info
  nodeToNodeMeshEnabled: true
  1. 创建 Calico IP 池
calicoctl apply -f calico-config.yaml
  1. 启动容器加入网络
docker network create --driver calico --config-only my_calico
docker run -it --network my_calico --name client alpine
  1. 配置网络策略(可选)
# 创建网络策略
calicoctl apply -f network-policy.yaml

优点: 性能优异,适用于大规模集群,支持网络策略。

缺点: 配置复杂,需要额外安装Calico工具。

API 网关/Nginx 反向代理(微服务架构) 适用于微服务架构,通过API网关或Nginx反向代理实现跨主机通信。

操作步骤:

  1. 部署API网关/Nginx
# 部署API网关或Nginx
docker run -d --name api-gateway nginx
  1. 配置路由规则
# Nginx 配置(位于独立主机)  
server {
listen 80;
server_name api.example.com;

    location / {
        proxy_pass http://<容器主机1_IP>:8080;
    }

    location /v2/ {
        proxy_pass http://<容器主机2_IP>:3000;
    }
}

优点: 灵活,适用于微服务架构。 缺点: 需要额外部署API网关/Nginx,配置复杂。


六、Docker Compose 容器编排

6.1、Docker Compose 简介[/kəmˈpoʊz/]

Docker Compose 是一个用于定义和运行多容器Docker应用程序的工具。通过一个YAML文件,可以定义多个容器及其配置,然后使用一条命令即可启动所有容器。

Docker Compose 工作原理
graph TB
    subgraph YAML["docker-compose.yml<br/>配置文件"]
        Y1["services:<br/>定义服务"]
        Y2["networks:<br/>定义网络"]
        Y3["volumes:<br/>定义数据卷"]
    end

    subgraph Compose["Docker Compose<br/>编排工具"]
        C1["docker-compose up"]
        C2["解析 YAML"]
        C3["创建网络"]
        C4["创建数据卷"]
        C5["拉取/构建镜像"]
        C6["启动容器"]
    end

    subgraph Result["最终结果"]
        R1["Web 服务<br/>nginx:80"]
        R2["API 服务<br/>nodejs:3000"]
        R3["数据库<br/>mysql:3306"]
        R4["Redis<br/>redis:6379"]
        R1 <-->|"app_network"| R2
        R2 <--> R3
        R2 <--> R4
    end

    YAML --> C1
    C1 --> C2
    C2 --> C3
    C2 --> C4
    C2 --> C5
    C2 --> C6
    C3 --> Result
    C4 --> Result
    C5 --> Result
    C6 --> Result

    style YAML fill:#fff3e0
    style Compose fill:#e3f2fd
    style Result fill:#e8f5e9

Compose 核心价值:

  • 声明式配置:用 YAML 定义整个应用栈
  • 一键启停docker-compose up/down 管理全部服务
  • 服务发现:自动配置容器间网络通信
  • 环境隔离:通过 docker-compose.override.yml 覆盖配置
6.1.1、安装 Compose

Linux安装

# 安装 Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

Windows安装 在 Windows 上使用 Docker Desktop: 同样,Docker Desktop 包含 Docker Compose,安装后即可使用。

Mac安装 在 Mac 上使用 Docker Desktop: 同样,Docker Desktop 包含 Docker Compose,安装后即可使用。

验证安装

docker-compose --version
6.1.2、基础使用
  1. 创建一个 docker-compose.yml 文件,定义服务:
version: '3'
services:
  web:
    image: nginx
    ports:
        - "80:80"
  db:
    image: mysql
    environment:
      - MYSQL_ROOT_PASSWORD=my-secret-pw
networks:
    app_network:
      driver: bridge

配置说明:

  • version: '3':指定 Compose 文件格式版本,版本 3 是目前最常用的版本
  • services:定义需要运行的服务容器
    • web:自定义服务名称
    • image: nginx:使用的镜像(无则拉取,有则使用)
    • ports:端口映射,格式为 "主机端口:容器端口"
    • environment:环境变量,用于配置容器内部参数(如 MySQL 密码)
  • networks:自定义网络配置,bridge 为桥接模式
  1. 启动服务:
docker-compose up
# docker-compose up -d # 后台运行
  1. 查看运行状态:
docker-compose ps
  1. 停止服务:
docker-compose down
# docker-compose down -v # 删除网络、卷等资源
  1. 重建服务:
docker-compose up --build
6.1.3、环境变量

可以在 docker-compose.yml 文件中使用环境变量,或者创建一个 .env 文件来存储变量,避免在 YAML 文件中硬编码敏感信息。例如:

version: '3'
services:
  web:
    image: nginx
    environment:
      - ENV_VAR=value
      - ANOTHER_ENV_VAR=another_value
      # 使用文件中的环境变量
      - $(ENV_FILE_PATH)
      # 使用环境变量文件
      - ./env_file
      # 使用环境变量文件中的变量
      - $(ENV_FILE_PATH:default_value)
6.1.4、服务依赖

Docker Compose 会自动处理服务之间的依赖关系。例如,如果您定义了一个服务依赖于另一个服务,Compose 会确保先启动依赖的服务。

6.1.5、网络配置

在上面的例子中,我们定义了一个桥接网络 app_network,使得 web 和 db 服务可以在同一个网络中通信。您可以通过服务名称来访问其他服务,而无需知道具体的 IP 地址。

6.1.6、服务扩展

Docker Compose 支持通过 deploy 部分定义服务的扩展策略,例如副本数量、资源限制等。这对于在开发和测试环境中模拟生产负载非常有用。

version: '3'
services:
  web:
    image: nginx
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: '0.50'
          memory: 256M

replicas: 3 表示启动 3 个 web 服务副本。
resources: 限制每个副本使用的 CPU 和内存资源。

6.1.7、构建配置

Docker Compose 支持使用 Dockerfile 构建镜像。您可以在 docker-compose.yml 文件中定义构建上下文,例如:

version: '3'
services:
  web:
    build:
      context: .
      # Dockerfile 文件路径
      dockerfile: Dockerfile
      # 构建参数
      args:
        - VERSION=1.0.0
        # 镜像标签
        - TAG=latest
        # 镜像名称
        - NAME=myapp
6.1.8、监控和日志

Docker Compose 提供了 docker-compose logs 命令来查看服务的日志。您可以使用 -f 选项来实时查看日志输出。

docker-compose logs -f
6.1.9、更新和回滚

Docker Compose 支持服务的更新和回滚。您可以使用 docker-compose up 命令来更新服务,并使用 docker-compose down 命令来回滚到先前的配置。

docker-compose up --build

docker-compose up --force-recreate --no-deps --build

--force-recreate:强制重新创建容器。
--no-deps:不重新创建依赖的服务。

6.1.10、CI/CD 集成

Docker Compose 可以与 CI/CD 工具集成,例如 Jenkins、GitLab CI/CD 和 GitHub Actions。您可以在 CI/CD 流程中使用 Docker Compose 来构建、测试和部署应用程序。

# 在流水线中执行
docker-compose build
docker-compose up -d
docker-compose run --rm tests
docker-compose down

七、容器监控与日志

7.1、资源监控

Docker 提供了 docker stats 命令,可以实时查看容器的资源使用情况,包括 CPU、内存、网络和磁盘 I/O。

7.2、Prometheus + Grafana(普若-米-西-厄斯) + Grafana(格若-发-呐)

7.2.1、Prometheus 配置

Prometheus 是一个开源的监控和警报工具,用于收集和存储时间序列数据。Prometheus 可以与 Docker 容器一起使用,以收集容器的资源使用情况。

7.2.2、Grafana 可视化

Grafana 是一个开源的监控仪表板工具,用于可视化 Prometheus 收集的数据。Grafana 可以与 Docker 容器一起使用,以展示容器的资源使用情况。

7.2.3、典型工作流程
  1. 安装 Prometheus 和 Grafana。
# 安装 node-exporter,虚拟机监控的exporter,包括虚拟机cpu、内存使用情况等。
docker run -d --name node-exporter -p 9100:9100  prom/node-exporter
# 用于收集和存储时间序列数据
docker run  -d --name prometheus  -p 9090:9090 -v /Volumes/czx/dev_tool/docker/prometheus/conf/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus:latest
# 用于展示 Prometheus 收集的数据
docker run -d --name grafana -p 3000:3000 --name=grafana -v /Volumes/czx/dev_tool/docker/grafana/data:/var/lib/grafana grafana/grafana
# 安装 cadvisor,用于收集 Docker 容器的资源使用情况。
docker run -v /:/rootfs:ro -v /var/run:/var/run:rw -v /sys:/sys:ro -v /var/lib/docker/:/var/lib/docker:ro -v /dev/disk/:/dev/disk:ro -p 8080:8080 -d --name=cadvisor google/cadvisor:latest

prometheus.yml 文件中配置了要监控的目标。

global:
    scrape_interval:     60s      # 全局默认抓取间隔(60秒抓取一次数据)
    evaluation_interval: 60s      # 规则评估间隔(60秒评估一次告警规则)

scrape_configs:                       # 抓取配置列表

    - job_name: prometheus             # 任务名称:监控 Prometheus 自身
      static_configs:
        - targets: ['localhost:9090']  # 监控目标地址(Prometheus 的 Web UI)
          labels:
            instance: prometheus      # 自定义标签,标识实例名称

    - job_name: linux                  # 任务名称:监控 Linux 系统指标(通过 node-exporter)
      static_configs:
        - targets: ['172.17.0.3:9100'] # node-exporter 暴露的指标接口地址
          labels:
            instance: localhost       # 标签:标识为本地服务器
    - job_name: cadvisor               # 任务名称:监控 Docker 容器指标
      static_configs:
        - targets: ['172.17.0.3:8080'] # cadvisor 暴露的指标接口地址
          labels:
              instance: cadvisor      # 标签:标识为容器监控服务

配置说明:

  • global:全局配置,对所有任务生效
    • scrape_interval:数据抓取间隔,决定监控数据的采集频率
    • evaluation_interval:规则评估间隔,用于计算告警规则
  • scrape_configs:抓取配置列表,可定义多个监控任务
    • job_name:任务名称,具有唯一性
    • static_configs:静态配置方式,targets 定义监控目标地址
    • labels:为监控目标添加自定义标签,便于分类和筛选
  1. 访问prometheus,http://ip:9090/targets 可以看到我们起来的几个exporter:

image.png 3. 访问node-exporter, http://ip:9100/metrics 可以看到node-exporter收集的指标:

image.png

  1. 访问Grafana,http://ip:3000,配置prometheus数据源:

image.png

  1. 创建仪表板以展示容器的资源使用情况。

image.png

具体参照:www.jb51.net/server/3375…

7.2、日志管理

7.2.1、docker logs 命令
命令说明示例
docker logs查看容器日志docker logs container_id
docker logs -f实时跟踪日志docker logs -f container_id
docker logs --tail查看最后N行docker logs --tail 100 container_id
docker logs -t显示时间戳docker logs -t container_id
7.2.2、日志驱动配置

Docker 支持多种日志驱动:

驱动说明适用场景
json-file默认驱动,JSON 格式写入文件开发测试
syslog发送到系统 syslog传统环境
journald发送到 systemd journalsystemd 系统
fluentd发送到 Fluentd 收集器集中日志收集
awslogs发送到 AWS CloudWatchAWS 云环境

配置示例:

docker run --log-driver fluentd --log-opt fluentd-address=localhost:24224 nginx
7.2.3、ELK Stack 集成

ELK Stack(Elasticsearch + Logstash + Kibana)是 Docker 日志收集、存储和可视化的完整方案。

ELK 日志收集架构
flowchart LR
    subgraph Collect["日志采集层"]
        C1["Docker 容器"]
        C2["应用日志<br/>/var/lib/docker/containers/"]
    end

    subgraph Transport["日志传输层"]
        T1["Filebeat<br/>轻量级采集器"]
        T2["Fluentd<br/>统一日志层"]
        T3["Logstash<br/>日志处理"]
    end

    subgraph Storage["日志存储层"]
        S1["Elasticsearch<br/>全文搜索引擎"]
        S2["索引存储<br/>logs-YYYY.MM.DD"]
    end

    subgraph Visualize["日志可视化层"]
        V1["Kibana<br/>可视化界面"]
        V2["Dashboard<br/>仪表盘"]
        V3["搜索查询<br/>DSL"]
    end

    C1 --> C2
    C2 --> T1
    C2 --> T2
    T1 --> T3
    T2 --> T3
    T3 --> S1
    S1 --> V1
    V1 --> V2
    V1 --> V3

    style Collect fill:#e3f2fd
    style Transport fill:#fff3e0
    style Storage fill:#e8f5e9
    style Visualize fill:#fce4ec

ELK 各组件职责:

  • Filebeat:轻量级日志采集器,监控日志文件变化,发送到 Logstash 或 Elasticsearch
  • Logstash:日志处理管道,进行解析、过滤、转换
  • Elasticsearch:分布式搜索引擎,存储和索引日志,支持高速查询
  • Kibana:Web 可视化界面,提供搜索、图表分析、仪表盘功能

八、私有镜像仓库

8.1、Docker Registry

Docker Registry 是一个用于存储和分发Docker镜像的服务。可以使用Docker Registry搭建私有镜像仓库。

镜像仓库工作流程
flowchart LR
    subgraph Push["镜像推送 (Push)"]
        Build["docker build<br/>构建镜像"]
        Tag["docker tag<br/>打标签"]
        PushAct["docker push<br/>推送到仓库"]
        Build --> Tag --> PushAct
    end

    subgraph Registry["镜像仓库 (Registry)"]
        R1["index.json<br/>索引"]
        R2["manifests<br/>清单"]
        R3["layers<br/>镜像层"]
    end

    subgraph Pull["镜像拉取 (Pull)"]
        PullCmd["docker pull<br/>拉取镜像"]
        Run["docker run<br/>运行容器"]
        PullCmd --> Run
    end

    PushAct -. "HTTP/HTTPS".-> Registry
    Registry -. "HTTP/HTTPS".-> PullCmd

    style Push fill:#e8f5e9
    style Registry fill:#fff3e0
    style Pull fill:#e3f2fd
仓库类型说明特点
Docker Hub官方公共仓库镜像丰富,但访问慢,有速率限制
阿里云镜像国内镜像加速访问快,需登录,有配额限制
私有 Registry自建 Registry完全可控,需自行维护
Harbor企业级镜像仓库权限管理、镜像扫描、高可用

8.2、Harbor

Harbor 是一个开源的容器镜像仓库,提供了安全、高效和可扩展的镜像管理功能。Harbor 可以与Docker Registry无缝集成,提供更高级的功能,如镜像扫描、镜像复制和镜像同步。


九、容器安全

9.1、安全基础

Docker 提供了一些安全功能,如命名空间隔离、安全选项和镜像扫描。用户可以使用这些功能来提高容器的安全性。

Docker 安全多层防护体系
%%{init: {'theme':'base'}}%%
graph TB
    subgraph App[应用层]
        A1[应用代码]
        A2[非 root 用户运行]
    end

    subgraph Container[容器层]
        C1[只读镜像]
        C2[最小镜像<br/>distroless/alpine]
        C3[资源限制<br/>CPU/内存]
        C4[Capabilities 控制]
    end

    subgraph Namespace[命名空间层]
        N1[PID 命名空间<br/>进程隔离]
        N2[Network 命名空间<br/>网络隔离]
        N3[Mount 命名空间<br/>文件系统隔离]
        N4[User 命名空间<br/>用户隔离]
    end

    subgraph Kernel[内核层]
        K1[Cgroups<br/>资源配额]
        K2[Seccomp<br/>系统调用过滤]
        K3[AppArmor/SELinux<br/>强制访问控制]
        K4[Linux Capabilities<br/>特权控制]
    end

    subgraph Scan[扫描层]
        S1[Trivy/Clair<br/>漏洞扫描]
        S2[镜像签名<br/>Notary]
    end

    A1 --> C1
    A2 --> C1
    C1 --> C2
    C2 --> C3
    C2 --> C4
    C3 --> N1
    C3 --> N2
    C3 --> N3
    C3 --> N4
    N1 --> K1
    N2 --> K2
    N3 --> K3
    N4 --> K4
    C2 -. 安全扫描 .-> S1
    C2 -. 内容信任 .-> S2

    style App fill:#e8f5e9,stroke:#333,stroke-width:2px
    style Container fill:#e3f2fd,stroke:#333,stroke-width:2px
    style Namespace fill:#fff3e0,stroke:#333,stroke-width:2px
    style Kernel fill:#fce4ec,stroke:#333,stroke-width:2px
    style Scan fill:#f3e5f5,stroke:#333,stroke-width:2px

9.2、安全最佳实践

在容器化应用时,应遵循以下安全最佳实践:

  1. 使用最小权限原则运行容器。
  2. 使用非root用户运行容器。
  3. 使用安全镜像。
  4. 限制容器对主机的访问权限。
  5. 定期更新和升级容器镜像。

十、Docker 进阶特性

10.1、多阶段构建(Multi-stage Builds)

多阶段构建是 Docker 17.05 引入的特性,允许在单个 Dockerfile 中使用多个 FROM 指令,每个阶段可以基于不同的基础镜像,最终只保留最后一个阶段的产物,大幅减小镜像体积。

10.1.1、传统构建的问题
# 传统方式:构建环境和运行环境混在一起
FROM golang:1.21
WORKDIR /app
COPY . .
RUN go build -o myapp
CMD ["./myapp"]

问题

  • 镜像包含 Go 编译器(>800MB)
  • 包含源代码和构建缓存
  • 最终镜像体积巨大
10.1.2、多阶段构建优化
# 第一阶段:构建
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o myapp

# 第二阶段:运行(使用最小镜像)
FROM alpine:latest
WORKDIR /root/
# 从构建阶段复制产物
COPY --from=builder /app/myapp .
CMD ["./myapp"]
多阶段构建原理图
graph TB
    subgraph Stage1["阶段 1:构建环境 (builder)"]
        S1_Base["golang:1.21-alpine<br/>~800MB"]
        S1_Deps["go mod download<br/>依赖包"]
        S1_Src["复制源代码"]
        S1_Binary["编译二进制文件<br/>myapp (~10MB)"]
        S1_Base --> S1_Deps --> S1_Src --> S1_Binary
    end

    subgraph Stage2["阶段 2:运行环境"]
        S2_Base["alpine:latest<br/>~5MB"]
        S2_Copy["COPY --from=builder"]
        S2_Final["最终镜像<br/>~15MB"]
        S2_Base --> S2_Copy --> S2_Final
    end

    S1_Binary -. "只复制二进制".-> S2_Copy

    Discard["丢弃 (构建工具、源码、依赖)"]
    S1_Base -. "丢弃".-> Discard
    S1_Deps -. "丢弃".-> Discard
    S1_Src -. "丢弃".-> Discard

    style Stage1 fill:#fff3e0
    style Stage2 fill:#e8f5e9
    style Discard fill:#ffcdd2

优化效果

  • 最终镜像从 800MB+ 降至 15MB
  • 只包含二进制文件,无编译工具
  • 攻击面更小,更安全
10.1.3、多阶段构建常用技巧
技巧说明示例
命名阶段使用 AS 命名便于引用FROM node:18 AS builder
复制产物从前阶段复制文件COPY --from=builder /app/dist .
多阶段依赖多个构建阶段相互依赖COPY --from=builder1 ...
使用缓存分离依赖安装和代码复制先 COPY go.mod,再 COPY 源码
10.1.4、实战案例:前端应用构建
# 构建阶段
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

# 生产阶段
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
10.1.5、Java 多阶段构建示例
# 构建阶段
FROM maven:3.9-eclipse-temurin-17-alpine AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package -DskipTests

# 运行阶段
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

10.2、Healthcheck 健康检查

10.2.1、HEALTHCHECK 指令
FROM nginx:alpine
# 每30秒检查一次,超时3秒,连续2次失败视为不健康
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=2 \
  CMD curl -f http://localhost:80/ || exit 1
参数说明默认值
--interval检查间隔30s
--timeout超时时间30s
--start-period启动宽限期0s
--retries重试次数3
10.2.2、常见健康检查命令
应用类型健康检查命令
Web 服务curl -f http://localhost:8080/health
数据库pg_isready -U postgres
Redisredis-cli ping | grep PONG
自定义wget --quiet --tries=1 --spider http://localhost/ || exit 1
10.2.3、查看健康状态
# 查看容器健康状态
docker ps
# STATUS 列显示 (healthy) 或 (unhealthy)

# 查看健康检查日志
docker inspect --format='{{.State.Health}}' container_id

# 禁用容器健康检查
docker run --no-healthcheck nginx

10.3、BuildKit 构建加速器

10.3.1、启用 BuildKit
# 临时启用(单次构建)
DOCKER_BUILDKIT=1 docker build -t myapp .

# 永久启用(写入配置文件)
echo '{"features":{"buildkit":true}}' > ~/.docker/daemon.json
10.3.2、BuildKit 特性
特性说明
并行构建多层同时构建
缓存导出支持远程缓存(S3、 registry)
秘密挂载安全传递构建密钥
SSH 转发构建时使用 SSH 密钥
10.3.3、秘密挂载(Secret Mount)
# syntax=docker/dockerfile:1.2
FROM node:18
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc \
    npm ci
# 构建时传递秘密
docker build --secret id=npmrc,src=$HOME/.npmrc -t myapp .
10.3.4、缓存挂载(Cache Mount)
# syntax=docker/dockerfile:1.2
FROM python:3.11
RUN --mount=type=cache,target=/root/.cache/pip \
    pip install -r requirements.txt

十一、Docker Swarm 集群编排

11.1、Swarm 简介

Docker Swarm 是 Docker 原生的集群管理工具,将多个 Docker 主机虚拟成一个虚拟主机,提供容器编排能力。

Docker Swarm 集群架构
graph TB
    subgraph Manager["管理节点 (Manager)"]
        M1["API Server"]
        M2["Scheduler<br/>调度器"]
        M3["Orchestrator<br/>编排器"]
        M4["Dispatcher<br/>分发器"]
        M1 --> M2
        M1 --> M3
        M1 --> M4
    end

    subgraph Workers["工作节点 (Workers)"]
        subgraph W1["Worker 1"]
            WC1["容器 1"]
            WC2["容器 2"]
        end
        subgraph W2["Worker 2"]
            WC3["容器 3"]
            WC4["容器 4"]
        end
        subgraph W3["Worker 3"]
            WC5["容器 5"]
        end
    end

    subgraph Overlay_Network["Overlay 网络 (VXLAN)"]
        O1["Service A<br/>负载均衡"]
        O2["Service B<br/>负载均衡"]
        O1 -. "跨主机通信".-> WC1
        O1 -.-> WC3
        O1 -.-> WC5
    end

    User["用户请求"]
    LB["Ingress<br/>负载均衡"]
    Registry["镜像仓库"]

    User --> LB
    LB --> Manager
    Manager --> W1
    Manager --> W2
    Manager --> W3
    Registry -. "拉取镜像".-> Workers

    style Manager fill:#fff3e0
    style Workers fill:#e3f2fd
    style Overlay_Network fill:#e8f5e9

与 Docker Compose 对比

特性Docker ComposeDocker Swarm
部署范围单机多机集群
高可用
负载均衡
滚动更新
服务发现容器名内置 DNS
使用场景开发测试生产环境

11.2、Swarm 集群搭建

11.2.1、初始化管理节点
# 在管理节点上执行
docker swarm init --advertise-addr 192.168.1.10

# 输出示例:
# Swarm initialized: current node (xxx) is now a manager.
# To add a worker to this swarm, run the following command:
#   docker swarm join --token SWMTKN-1-xxx 192.168.1.10:2377
11.2.2、添加工作节点
# 在工作节点上执行(使用上面输出的命令)
docker swarm join --token SWMTKN-1-xxx 192.168.1.10:2377

# 验证节点加入成功
docker node ls
11.2.3、常用节点管理命令
命令说明
docker swarm leave离开集群
docker swarm leave --force强制离开
docker node ls列出节点
docker node rm node_id删除节点
docker node promote node_id提升为管理节点
docker node demote node_id降级为工作节点

11.3、Service 服务管理

Service(服务) 是 Swarm 集群中管理的最小调度单位,定义了一个镜像在集群中的运行方式。与单个容器不同,Service 可以横向扩展为多个副本(Replica),自动分配到不同的节点上运行,实现高可用和负载均衡。

核心概念:

  • Service 是 Docker Swarm 中的高级抽象,将应用封装为可管理的单元
  • 一个 Service 对应一个镜像,但可以运行多个容器副本
  • Swarm 自动处理副本的调度、故障恢复和负载分配
11.3.1、创建服务
# 创建 Nginx 服务,3 个副本
docker service create --name nginx --replicas 3 -p 80:80 nginx:alpine

# 创建带挂载的服务
docker service create \
  --name mysql \
  --replicas 1 \
  --mount type=volume,source=mysql_data,target=/var/lib/mysql \
  -e MYSQL_ROOT_PASSWORD=secret \
  mysql:8.0
11.3.2、服务扩缩容
# 扩展服务到 10 个副本
docker service scale nginx=10

# 缩减到 2 个副本
docker service scale nginx=2
11.3.3、服务更新与回滚
# 滚动更新镜像版本
docker service update --image nginx:1.25 nginx

# 配置滚动更新策略
docker service update \
  --update-parallelism 2 \
  --update-delay 10s \
  --update-failure-action rollback \
  nginx

# 回滚到上一个版本
docker service rollback nginx
更新参数说明默认值
--update-parallelism每次更新容器数1
--update-delay更新间隔0s
--update-failure-action更新失败动作(pause/continue/rollback)pause

11.4、Stack 部署

Stack(栈) 是 Docker Swarm 中管理多个 Service 的方式,通过一个 docker-compose.yml 文件定义一组相关联的服务、网络、卷等资源,实现一键部署完整的分布式应用。

核心概念:

  • Stack 是多个 Service 的集合,类似于 Docker Compose 的概念,但运行在集群环境中
  • 一条命令即可部署整个应用栈,自动创建所有依赖的服务和网络
  • Stack 提供了比单个 Service 更高层次的应用管理
11.4.1、docker-compose.yml 适配 Swarm
version: '3.8'                       # Compose 文件版本

services:
  web:                                # 服务名称:前端 Web 服务
    image: nginx:alpine               # 使用的镜像
    ports:
      - "80:80"                       # 端口映射
    deploy:                            # Swarm 部署配置(Compose v3 特有)
      replicas: 3                      # 运行 3 个副本实例
      update_config:                  # 滚动更新策略
        parallelism: 1                 # 每次更新 1 个容器
        delay: 10s                    # 更新间隔 10 秒
        failure_action: rollback      # 失败时回滚
      restart_policy:                 # 重启策略
        condition: on-failure          # 容器异常退出时重启
        delay: 5s                     # 重启延迟 5 秒
        max_attempts: 3               # 最大重试 3 次
      placement:                      # 调度约束
        constraints:                   # 部署约束条件
          - node.role == worker       # 必须部署到 worker 节点

  db:                                 # 服务名称:数据库服务
    image: postgres:15                # 使用的镜像
    environment:
      POSTGRES_PASSWORD: secret       # 环境变量(数据库密码)
    volumes:
      - db_data:/var/lib/postgresql/data   # 持久化卷挂载
    deploy:
      replicas: 1                      # 单副本(数据库通常用单实例)
      placement:
        constraints:
          - node.labels.storage == ssd # 部署到带有 ssd 标签的节点

volumes:                              # 定义持久化卷
  db_data:
    driver: local                      # 使用本地存储驱动

networks:                             # 定义网络
  default:
    driver: overlay                   # 使用 overlay 网络(集群内跨主机通信)

配置说明:

  • deploy:Swarm 特有的部署配置,在单机 Docker Compose 中不使用
    • replicas:副本数量,决定运行多少个容器实例
    • update_config:滚动更新时的并行数、间隔和失败处理
    • restart_policy:容器异常退出后的重启策略
    • placement.constraints:限制服务部署到满足特定条件的节点
  • volumes:声明持久化存储,数据卷独立于容器生命周期
  • networks:overlay 网络用于集群中服务间的跨主机通信
11.4.2、部署 Stack
# 部署 stack
docker stack deploy -c docker-compose.yml myapp

# 查看 stack 服务
docker stack ls
docker stack ps myapp
docker stack services myapp

# 删除 stack
docker stack rm myapp

11.5、Swarm 网络与存储

11.5.1、Overlay 网络
# 创建 overlay 网络
docker network create --driver overlay --attachable my_network

# 使用 attachable 允许独立容器加入
docker run --network my_network nginx
11.5.2、存储配置
存储类型用途配置
volume持久化数据type=volume,source=vol,target=/data
bind绑定挂载type=bind,source=/host,target=/container
tmpfs临时存储type=tmpfs,target=/tmp

十二、镜像优化与安全扫描

12.1、镜像优化最佳实践

12.1.1、减小镜像体积的技巧
技巧方法效果
使用精简基础镜像alpinedistrolessscratch减小 50-90%
多阶段构建分离构建和运行环境减小 80%+
合并 RUN 指令使用 && 连接命令减少层数
清理缓存apt-get cleanrm -rf /var/cache移除临时文件
.dockerignore排除不必要的文件减小构建上下文
12.1.2、.dockerignore 配置
# Git
.git
.gitignore

# 依赖(构建时会重新安装)
node_modules
vendor
__pycache__

# 构建产物(构建时会重新生成)
dist
build
target

# IDE
.idea
.vscode
*.iml

# 测试文件
*.test.js
__tests__
coverage

# 文档
README.md
CHANGELOG.md
docs/

# 其他
*.log
.env
.env.local
.DS_Store
12.1.3、镜像分层优化
# ❌ 差的实践:每次代码变更都重新安装依赖
COPY . /app
RUN npm install

# ✅ 好的实践:利用缓存层
COPY package*.json /app/
RUN npm ci --only=production
COPY . /app

12.2、镜像安全扫描

12.2.1、Docker Scout(官方)
# 启用 Docker Scout
docker scout quickview nginx:latest

# 详细漏洞扫描
docker scout cves nginx:latest

# 比较两个镜像
docker scout compare nginx:1.24 nginx:1.25
12.2.2、Trivy(开源)
# 安装 Trivy
brew install trivy

# 扫描镜像
trivy image nginx:latest

# 扫描并过滤高危漏洞
trivy image --severity HIGH,CRITICAL nginx:latest

# 导出报告
trivy image --format json -o report.json nginx:latest
12.2.3、Clair(集成 Harbor)
# 在 Harbor UI 中启用扫描
# 配置 > 漏洞 > 启用 Clair/Anchore 扫描

# 通过 API 触发扫描
curl -X POST "https://harbor.example.com/api/v2.0/projects/library/repositories/nginx/artifacts/latest/scan"

12.3、Distroless 镜像

12.3.1、什么是 Distroless

Google 提供的无发行版镜像,只包含应用及其运行时依赖,没有包管理器、shell 等工具。

# 使用 distroless 基础镜像
FROM gcr.io/distroless/java17-debian12
COPY target/app.jar /app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
12.3.2、Distroless 镜像类型
镜像适用场景
gcr.io/distroless/static静态编译的 Go/C++ 应用
gcr.io/distroless/base动态链接的 C/C++ 应用
gcr.io/distroless/java17Java 17 应用
gcr.io/distroless/nodejs18Node.js 18 应用
gcr.io/distroless/python3Python 3 应用
12.3.3、调试 Distroless 容器
# 多阶段构建,包含调试版本
FROM gcr.io/distroless/java17-debian12:debug AS debug
# 调试版本包含 busybox shell

十三、CI/CD 集成

CI/CD(持续集成/持续部署) 是现代软件开发的核心实践,通过自动化流程实现代码的构建、测试、部署。Docker 与 CI/CD 的结合,使得应用可以在隔离的容器环境中完成整个交付流程,确保环境一致性和快速部署。

CI/CD 流水线核心流程:

  1. Build(构建):拉取代码,编译打包成 Docker 镜像
  2. Test(测试):在容器中运行单元测试和集成测试
  3. Security Scan(安全扫描):使用工具(如 Trivy)扫描镜像漏洞
  4. Push(推送):将镜像推送到私有仓库
  5. Deploy(部署):从仓库拉取镜像,完成服务部署
主流 CI/CD 工具对比
工具配置文件特点适用场景
JenkinsJenkinsfile插件生态丰富,灵活性高,需自建服务器大型企业,复杂流水线
GitLab CI.gitlab-ci.ymlGitLab 内置,配置简单,与代码库紧密集成使用 GitLab 的团队
GitHub Actions.github/workflows/*.yml社区 Actions 丰富,事件驱动,托管式开源项目,GitHub 团队
流水线架构图
flowchart LR
    subgraph CI["持续集成 (CI)"]
        A1[代码提交] --> B1[构建镜像]
        B1 --> C1[运行测试]
        C1 --> D1[安全扫描]
    end

    subgraph CD["持续部署 (CD)"]
        D1 --> E1[推送镜像]
        E1 --> F1[部署服务]
    end

    subgraph Tools["工具实现"]
        G1[Jenkins<br/>Jenkinsfile]
        G2[GitLab CI<br/>.gitlab-ci.yml]
        G3[GitHub Actions<br/>workflows/*.yml]
    end

    CI --> Tools
    CD --> Tools

    style CI fill:#e1f5fe
    style CD fill:#f3e5f5
    style Tools fill:#fff3e0
sequenceDiagram
    participant Dev as 开发者
    participant VCS as 代码仓库
    participant CI as CI/CD 系统
    participant Registry as 镜像仓库
    participant Server as 生产服务器

    Dev->>VCS: 提交代码 (git push)
    VCS->>CI: 触发流水线
    CI->>CI: 1. Build 构建镜像
    CI->>CI: 2. Test 运行测试
    CI->>CI: 3. Scan 安全扫描
    CI->>Registry: 4. Push 推送镜像
    Registry-->>CI: 镜像地址
    CI->>Server: 5. Deploy SSH部署
    Server-->>CI: 部署完成
    CI-->>Dev: 通知结果

13.1、Docker + Jenkins 流水线

Jenkins 是最流行的 CI/CD 工具之一,通过 Jenkinsfile 定义流水线逻辑,docker.pipeline 插件提供了与 Docker 的深度集成。

13.1.1、Jenkinsfile 示例
pipeline {
    agent any                              // 在任意可用代理节点执行

    environment {                          // 定义环境变量
        DOCKER_REGISTRY = 'registry.example.com'   // 私有镜像仓库地址
        IMAGE_NAME = 'myapp'              // 镜像名称
        IMAGE_TAG = "${BUILD_NUMBER}"     // 使用构建编号作为镜像标签(便于追溯)
    }

    stages {                               // 定义流水线阶段
        stage('Build') {                   // 阶段1:构建镜像
            steps {
                script {
                    // 执行 Docker 多阶段构建
                    docker.build("${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}", ".")
                }
            }
        }

        stage('Test') {                    // 阶段2:运行测试
            steps {
                script {
                    // 在构建的镜像内部执行测试命令
                    docker.image("${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}").inside {
                        sh 'npm test'
                    }
                }
            }
        }

        stage('Security Scan') {           // 阶段3:安全扫描
            steps {
                // 使用 Trivy 扫描镜像漏洞
                sh "trivy image ${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}"
            }
        }

        stage('Push') {                    // 阶段4:推送到仓库
            when {
                branch 'main'              // 仅在 main 分支执行
            }
            steps {
                script {
                    // 使用凭证认证到私有仓库
                    docker.withRegistry("https://${DOCKER_REGISTRY}", 'registry-credentials') {
                        // 推送带版本标签的镜像
                        docker.image("${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}").push()
                        // 同时推送 latest 标签
                        docker.image("${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}").push('latest')
                    }
                }
            }
        }

        stage('Deploy') {                  // 阶段5:部署到生产环境
            when {
                branch 'main'              // 仅在 main 分支执行
            }
            steps {
                // SSH 远程连接到生产服务器执行部署命令
                sh """
                    ssh deploy@prod-server '
                        docker pull ${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} &&
                        docker-compose -f /opt/app/docker-compose.yml up -d
                    '
                """
            }
        }
    }
}

Jenkinsfile 核心概念:

  • agent any:在任意可用节点执行流水线
  • environment:定义全局环境变量,用于配置和敏感信息
  • stages:流水线阶段,每个阶段执行特定任务
  • when { branch 'main' }:条件执行,仅指定分支触发
  • docker.withRegistry:认证到私有镜像仓库

13.2、GitLab CI 集成

GitLab CI 是 GitLab 自带的 CI/CD 功能,通过 .gitlab-ci.yml 文件定义流水线,配置文件放在项目根目录。

13.2.1、.gitlab-ci.yml 示例
stages:                                 # 定义流水线阶段(按顺序执行)
  - build                               # 构建阶段
  - test                                # 测试阶段
  - security                            # 安全扫描阶段
  - push                                # 推送阶段
  - deploy                              # 部署阶段

variables:                              # 全局环境变量
  DOCKER_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA   # GitLab 内置变量构建镜像名

build:                                  # 作业1:构建
  stage: build                          # 属于 build 阶段
  image: docker:latest                  # 使用 Docker 镜像作为运行环境
  services:                             # 附加服务(Docker in Docker)
    - docker:dind                       # Docker daemon 服务
  script:                               # 执行脚本
    - docker build -t $DOCKER_IMAGE .   # 构建镜像
    - docker save $DOCKER_IMAGE > image.tar   # 导出镜像为 tar 文件
  artifacts:                            # 产物配置(传递给后续阶段)
    paths:
      - image.tar                       # 保存镜像文件供后续作业使用

test:                                   # 作业2:测试
  stage: test                           # 属于 test 阶段
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker load < image.tar            # 加载上一阶段保存的镜像
    - docker run --rm $DOCKER_IMAGE npm test    # 运行测试

security:                               # 作业3:安全扫描
  stage: security                       # 属于 security 阶段
  image: aquasec/trivy:latest           # 使用 Trivy 专用镜像
  script:
    - docker load < image.tar            # 加载镜像
    - trivy image --exit-code 1 --severity HIGH,CRITICAL $DOCKER_IMAGE   # 扫描高危漏洞

push:                                   # 作业4:推送到仓库
  stage: push
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker load < image.tar            # 加载镜像
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY  # 登录仓库
    - docker push $DOCKER_IMAGE         # 推送镜像(使用 commit SHA 作为标签)
    - docker tag $DOCKER_IMAGE $CI_REGISTRY_IMAGE:latest   # 打 latest 标签
    - docker push $CI_REGISTRY_IMAGE:latest                 # 推送 latest
  only:
    - main                               # 仅在 main 分支触发

deploy:                                 # 作业5:部署(使用 Helm)
  stage: deploy
  image: alpine/helm:latest              # 使用 Helm 镜像
  script:
    - helm upgrade --install myapp ./chart --set image.tag=$CI_COMMIT_SHA   # 升级/安装应用
  only:
    - main                               # 仅在 main 分支触发

GitLab CI 核心概念:

  • stages:定义全局阶段顺序,所有作业按阶段分组执行
  • image:作业使用的 Docker 镜像(运行时环境)
  • services:附加服务,docker:dind 启用 Docker-in-Docker 支持
  • artifacts:作业产物,用于在同流水线内共享文件
  • $CI_REGISTRY_IMAGE$CI_COMMIT_SHA:GitLab 内置预定义变量
  • only:限制作业触发的分支

13.3、GitHub Actions 集成

GitHub Actions 是 GitHub 提供的 CI/CD 功能,配置文件放在 .github/workflows/ 目录下,支持丰富的社区 Actions 生态。

13.3.1、.github/workflows/docker.yml
name: Docker Build and Push              # 工作流名称

on:                                      # 触发条件
  push:                                  # 代码推送时触发
    branches: [main]                     # 仅 main 分支
  pull_request:                          # PR 时也触发
    branches: [main]

jobs:                                    # 定义作业
  build:                                 # 作业名称
    runs-on: ubuntu-latest               # 运行在 Ubuntu 最新版虚拟机
    steps:                               # 步骤列表
      - uses: actions/checkout@v4       # 步骤1:拉取代码

      - name: Set up Docker Buildx       # 步骤2:设置 Docker Buildx(支持多平台构建)
        uses: docker/setup-buildx-action@v3

      - name: Build image                # 步骤3:构建镜像
        uses: docker/build-push-action@v5
        with:
          context: .                     # 构建上下文为当前目录
          load: true                     # 加载镜像到本地(不推送)
          tags: myapp:test               # 镜像标签

      - name: Run tests                  # 步骤4:运行测试
        run: |
          docker run --rm myapp:test npm test

      - name: Run Trivy scanner          # 步骤5:安全扫描
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: 'myapp:test'         # 扫描的镜像
          format: 'sarif'                 # 输出格式(可用于 GitHub 安全告警)
          output: 'trivy-results.sarif'

      - name: Login to Registry          # 步骤6:登录镜像仓库
        if: github.ref == 'refs/heads/main'   # 仅 main 分支执行
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_USERNAME }}   # GitHub Secrets 中的用户名
          password: ${{ secrets.DOCKER_PASSWORD }}    # GitHub Secrets 中的密码

      - name: Push image                 # 步骤7:推送镜像
        if: github.ref == 'refs/heads/main'   # 仅 main 分支执行
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true                     # 推送到仓库
          tags: |                        # 多标签推送
            ${{ secrets.DOCKER_USERNAME }}/myapp:${{ github.sha }}   # commit SHA 标签
            ${{ secrets.DOCKER_USERNAME }}/myapp:latest               # latest 标签
          cache-from: type=gha           # 使用 GitHub Actions 缓存加速构建
          cache-to: type=gha,mode=max

GitHub Actions 核心概念:

  • name:工作流名称,显示在 GitHub Actions 页面
  • on:触发条件,支持 push、pull_request、schedule(定时)等
  • jobs:作业定义,可以有多个作业并行执行
  • runs-on:运行环境的虚拟机镜像
  • steps:步骤列表,按顺序执行
  • uses:使用社区维护的 Action(复用他人的工作流)
  • run:执行 Shell 命令
  • with:传递给 Action 或 step 的参数
  • if:条件执行,控制是否运行该步骤
  • secrets:加密存储的敏感信息,在 Settings -> Secrets 中配置

十四、调试与排障

容器问题排查流程图
flowchart TD
    A["容器无法正常工作"] --> B{"docker ps -a<br/>容器存在?"}

    B -->|否| C["容器未创建成功"]
    C --> C1["检查镜像是否存在<br/>docker images"]
    C1 --> C2["docker pull 拉取镜像"]
    C2 --> C3["重新创建容器<br/>docker run"]

    B -->|是| D{"容器状态?"}
    D -->|Exited| E["容器已退出"]
    E --> E1["查看退出码<br/>docker inspect"]
    E1 --> E2["查看日志<br/>docker logs"]
    E2 --> E3{"错误类型?"}
    E3 -->|端口占用| E4["docker port 查看<br/>更改端口映射"]
    E3 -->|权限不足| E5["添加 --privileged<br/>或调整用户权限"]
    E3 -->|找不到文件| E6["检查路径挂载<br/>-v 参数"]
    E3 -->|配置错误| E7["检查环境变量<br/>-e 参数"]

    D -->|Running| F["容器在运行"]
    F --> F1["检查服务是否正常"]
    F1 --> F2["docker logs 查看日志"]
    F2 --> F3["docker exec 进入容器<br/>进一步排查"]

    D -->|Restarting| G["容器反复重启"]
    G --> G1["OOM?<br/>检查内存限制"]
    G1 --> G2["健康检查失败?<br/>检查 HEALTHCHECK"]
    G2 --> G3["调整资源限制"]

    style A fill:#ffcdd2
    style E fill:#fff3e0
    style F fill:#e8f5e9
    style G fill:#fce4ec

14.1、容器启动问题排查

14.1.1、查看容器日志
# 实时查看日志
docker logs -f container_id

# 查看最近 100 行
docker logs --tail 100 container_id

# 查看特定时间范围
docker logs --since 2024-01-01T00:00:00 container_id

# 显示时间戳
docker logs -t container_id
14.1.2、检查容器状态
# 查看容器详细信息
docker inspect container_id

# 查看容器资源使用
docker stats container_id

# 查看容器进程
docker top container_id

# 查看容器端口映射
docker port container_id

# 查看容器退出码
docker inspect --format='{{.State.ExitCode}}' container_id
退出码含义
0正常退出
1一般错误
137 (128+9)被 SIGKILL 强制终止
143 (128+15)被 SIGTERM 终止
255未知错误

14.2、网络问题排查

14.2.1、容器网络诊断
# 进入容器执行网络诊断
docker exec -it container_id sh

# 或无需进入容器直接执行
docker exec container_id ping -c 3 google.com
docker exec container_id nslookup db
docker exec container_id netstat -tlnp
14.2.2、网络连通性测试
# 测试容器间通信
docker run --rm --network my_network busybox ping -c 3 other_container

# 查看网络详情
docker network inspect bridge
docker network inspect my_network

14.3、使用 nsenter 进入容器命名空间

当容器没有 shell 时,使用 nsenter 进入:

# 获取容器 PID
PID=$(docker inspect --format='{{.State.Pid}}' container_id)

# 进入容器网络命名空间
sudo nsenter -t $PID -n ip addr

# 进入所有命名空间
sudo nsenter -t $PID -m -u -i -n -p /bin/sh

14.4、常见问题排查清单

问题排查步骤
容器无法启动查看 docker logs → 检查 ExitCode → 验证配置
端口无法访问docker portdocker ps → 检查防火墙 → 验证端口映射
连接被拒绝docker network lsdocker network inspect → 测试连通性
权限不足检查用户/组 → 查看 SELinux/AppArmor → 检查 volume 权限
OOM 被杀死docker inspect 查看 OOMKilled → 增加内存限制
磁盘空间不足docker system dfdocker system prune

14.5、Docker 系统维护

# 查看磁盘使用
docker system df

# 清理未使用资源
docker system prune           # 删除停止的容器、未使用的网络、悬挂镜像
docker system prune -a        # 删除所有未使用的镜像(不只是悬挂)
docker system prune --volumes # 同时清理卷

# 清理特定资源
docker volume prune           # 未使用的卷
docker image prune            # 悬挂镜像
docker container prune        # 停止的容器
docker network prune          # 未使用的网络

十五、Kubernetes(K8s)

15.1、Kubernetes 简介

Kubernetes 是一个开源的容器编排平台,用于自动化容器化应用程序的部署、扩展和管理。Kubernetes 提供了丰富的功能,如服务发现、负载均衡、自动扩展、滚动更新和回滚等。

Kubernetes 架构图
%%{init: {'theme':'base'}}%%
graph TB
    subgraph CP[Control Plane 控制平面]
        API[API Server<br/>统一入口]
        ETCD[etcd<br/>分布式存储]
        Scheduler[Scheduler<br/>调度器]
        Controller[Controller Manager<br/>控制器]
    end

    subgraph Node2[Node 2 工作节点]
        N2_Kubelet[Kubelet]
        N2_Proxy[Kube-Proxy]
        N2_Pod3[Pod 3]
    end

    subgraph Node1[Node 1 工作节点]
        N1_Kubelet[Kubelet]
        N1_Proxy[Kube-Proxy]
        N1_Pod1[Pod 1]
        N1_Pod2[Pod 2]
    end

    User[用户] --> API
    Scheduler -->|调度| N1_Pod1
    Scheduler --> N2_Pod3

    style CP fill:#fff3e0,stroke:#333,stroke-width:2px
    style Node1 fill:#e3f2fd,stroke:#333,stroke-width:2px
    style Node2 fill:#e3f2fd,stroke:#333,stroke-width:2px

架构说明:

  • Control Plane:集群的大脑,负责整个集群的管理
    • API Server:提供 REST API,是集群的统一入口
    • etcd:高可用键值存储,保存集群所有数据
    • Scheduler:监控未调度 Pod,分配到合适节点
    • Controller Manager:运行控制器,维护集群期望状态
  • Node:实际运行 Pod 的工作节点
    • Kubelet:节点代理,确保容器在 Pod 中运行
    • Kube-Proxy:维护网络规则,实现服务通信

在 1.20 版本之前,Control Plane 称为 Master(主节点),Node 称为 Worker Node(工作节点)。

15.2、核心概念

Kubernetes 的核心概念包括:

  1. Pod:最小的部署单元,可以包含一个或多个容器。

    • 每个 Pod 都有一个唯一的 IP 地址,容器之间可以通过 localhost 进行通信。
    • 示例:一个Pod运行Nginx主容器和一个定期同步数据的辅助容器。
  2. Deployment:用于管理 Pod 的副本集,可以自动扩缩容。

    • Deployment 可以自动扩缩容,并支持滚动更新和回滚。
    • 示例:一个 Deployment 运行 3 个 Nginx Pod 副本。
  3. Service:用于定义 Pod 的网络访问策略,可以提供负载均衡和 DNS 解析。

    • Service 可以提供负载均衡和 DNS 解析,使得外部流量可以访问 Pod。
    • 示例:一个 Service 将流量路由到 3 个 Nginx Pod 副本。
  4. Volume:用于持久化存储,可以在 Pod 之间共享数据。

    • Volume 支持多种存储类型,如本地存储、网络存储和云存储。
    • 示例:一个 Volume 用于存储 Nginx Pod 的静态文件。
  5. Namespace:用于隔离资源,可以在不同的命名空间中运行不同的应用程序。

    • Namespace 可以限制资源的可见性和访问权限,并支持多租户环境。
    • 示例:开发环境 Namespace 和生产环境 Namespace。
  6. ConfigMap:用于存储配置数据,可以在 Pod 之间共享配置。

    • ConfigMap 可以在 Pod 之间共享配置,并支持热更新。
    • 示例:一个 ConfigMap 用于存储 Nginx Pod 的配置文件。
  7. Secret:用于存储敏感数据,例如密码和密钥。

    • Secret 可以在 Pod 之间共享,并支持加密存储。
    • 示例:一个 Secret 用于存储数据库的密码。

15.3、典型工作流程

  1. 定义 Kubernetes 资源文件(YAML 格式)。
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 3
  template:
    spec:
      containers:
      - name: nginx
        image: nginx:1.25
        ports:
        - containerPort: 80

配置说明:

  • apiVersion:API 版本
  • kind:资源类型(Deployment、Service 等)
  • metadata.name:资源名称
  • spec.replicas:Pod 副本数量
  • spec.template.spec.containers:容器配置
  1. 使用 kubectl apply 命令部署资源。
kubectl apply -f web-app-deployment.yaml
  1. 查看资源状态。
kubectl get deployments
kubectl get pods
kubectl get services
  1. 暴露服务以供外部访问。
kubectl expose deployment web-app --type=LoadBalancer --port=80 --target-port=80
  1. 扩展或缩减资源。
# 手动扩缩容
kubectl scale deployment web-app --replicas=5

# 自动扩缩容(基于 CPU)
kubectl autoscale deployment web-app --cpu-percent=50 --min=3 --max=10

15.4、快速上手环境

工具特点适用场景
Minikube单节点集群,本地运行学习和测试
KindDocker 容器运行 K8s本地多节点测试
kubeadm官方集群搭建工具生产环境
# Minikube 快速启动
minikube start --driver=docker

# Kind 创建多节点集群
kind create cluster --config kind-config.yaml

15.5、学习路径建议

1. 基础阶段

  • 掌握 kubectl 核心命令(get、describe、logs、exec)
  • 了解 Pod、Deployment、Service 等核心资源
  • 实践滚动更新、水平扩展、服务暴露、配置管理

2. 进阶阶段

  • 持久化存储:PersistentVolume(PV)、PersistentVolumeClaim(PVC)
  • 调度策略:nodeSelector、affinity、tains、tolerations
  • 网络策略:Calico/Flannel
  • 配置管理:ConfigMap、Secret、Helm

3. 高级阶段

  • 监控:Prometheus、Grafana
  • 日志:ELK Stack
  • CI/CD:Jenkins、ArgoCD(GitOps)