Docker使用详解 什么是Docker 基本介绍 Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。Solomon Hykes 创立的dotCloud公司开发。
Docker使用操作系统级别的虚拟化技术,来将应用程序及其所有依赖项(包括代码、运行时环境、系统工具、系统库和设置)打包在一个称为容器的标准化单元中。
容器是完全使用沙箱机制,相互之间不会有任何接口,更重要的是容器性能开销极低。
原理与核心概念 实现原理 Docker 并非通过传统的 Hypervisor 来实现虚拟化(如 VMware, VirtualBox)。它直接运行在宿主机的操作系统之上,并利用了 Linux 内核的两大核心技术:
信息提示
Namespaces(命名空间):提供隔离性。
它能够将系统资源(如进程、网络、文件系统挂载点等)包装起来,使得对其中一个命名空间的修改不会影响其他命名空间。
例如:PID Namespace为每个容器提供了独立的进程树,容器内的进程 PID=1 在宿主机上可能是 PID=3000,且容器看不到宿主机上的其他进程。
Cgroups(控制组):提供资源限制与核算。
它能够限制和隔离一个进程组所使用的物理资源,如 CPU、内存、磁盘 I/O 和网络带宽。
例如:你可以为一个容器分配最多 1GB 的内存和 2 个 CPU 核心,确保它不会耗尽宿主机的所有资源。
正是这两项技术,使得 Docker 容器既能享受与原生应用接近的性能,又能拥有类似于虚拟机的隔离与安全。
基本概念 Docker 中有三个基本的核心概念:镜像、容器、仓库 。
镜像:
一个只读的模板,包含了运行应用所需的一切:代码、运行时、库、环境变量和配置文件。它轻量、可移植、是构建容器的蓝图。
容器:
镜像是静态的模板,而容器是镜像的一个运行实例。你可以创建、启动、停止、移动或删除容器。容器与容器之间,容器与宿主机之间是相互隔离的。
仓库:
容器用于存放和分发 Docker 镜像的地方。最大的公共仓库是 Docker Hub,你可以从中拉取(下载)成千上万的官方或社区镜像,也可以将自己的镜像推送(上传)上去。私有仓库如 Harbor 用于企业内部。
工作流关系: Dockerfile -> (构建) -> Image -> (运行) -> Container -> (推送/拉取) -> Registry
Docker安装 基本安装 使用官方脚本安装 1 2 3 4 5 6 7 # 下载并运行 Docker 安装脚本 curl -fsSL https://get.docker.com -o get-docker.sh sh get-docker.sh # 将当前用户加入 docker 组 usermod -aG docker $USER # 需要重新登录生效
使用包管理器安装 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 # =======================Ubuntu/Debian # 更新包索引 sudo apt update # 安装依赖 sudo apt install -y apt-transport-https ca-certificates curl software-properties-common # 添加 Docker 官方 GPG 密钥 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 # 安装 Docker sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io # =======================CentOS/RHEL # 安装依赖 sudo yum install -y yum-utils # 添加 Docker 仓库 sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo # 安装 Docker sudo yum install -y docker-ce docker-ce-cli containerd.io # 启动并启用 Docker sudo systemctl start docker sudo systemctl enable docker # =======================Fedora # 添加 Docker 仓库 sudo dnf -y install dnf-plugins-core sudo dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo # 安装 Docker sudo dnf install -y docker-ce docker-ce-cli containerd.io # 启动 Docker sudo systemctl start docker sudo systemctl enable docker
docker服务配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 # /etc/docker/daemon.json { "registry-mirrors" : [ "https://<your-mirror-id>.mirror.aliyuncs.com" , "https://docker.mirrors.ustc.edu.cn" ] , "insecure-registries" : [ "docker.bailv.space:5000" , "192.168.10.100:8081" ] , "proxies" : { "default" : { "httpProxy" : "http://proxy.corp.com:8080" , "httpsProxy" : "http://proxy.corp.com:8080" , "noProxy" : "localhost,127.0.0.1,.corp.com,192.168.0.0/16" } } , "data-root" : "/data/docker" , "log-driver" : "json-file" , "log-opts" : { "max-size" : "100m" , "max-file" : "3" } , "features" : { "buildkit" : true } , "default-address-pools" : [ { "base" : "10.200.0.0/16" , "size" : 24 } ] , "live-restore" : true , "max-concurrent-downloads" : 10 , "storage-driver" : "overlay2" }
Docker命令详解 Docker命令是与Docker引擎交互的主要方式。了解Docker命令的结构、功能和用法对于高效使用Docker至关重要。本章将详细介绍Docker命令的基本结构、常用命令及其使用场景。
Docker 命令结构详解:命令与参数的组织方式 Docker 的命令结构采用了一种层次化的设计,使得命令的使用既灵活又直观。理解 Docker 命令的结构化组织方式对于高效使用 Docker 至关重要。
Docker 命令遵循以下基本语法结构:
1 docker [全局选项] <命令> [子命令] [命令选项] [参数]
全局选项 (Global Options) 影响整个 Docker 客户端的设置,必须放在具体命令之前。
常用全局选项:
--config:指定配置文件位置
-D, --debug:启用调试模式
-H, --host:指定 Docker 守护进程地址
-l, --log-level:设置日志级别
--tls:启用 TLS 验证
示例:
1 docker -H tcp://192.168.1.100:2376 --tls ps
主命令 (Management Commands) Docker 1.13+ 引入了管理命令的概念,将相关功能分组到命名空间下。
基本结构: docker <管理命令> <子命令>
管理命令
功能描述
container
容器管理
image
镜像管理
network
网络管理
volume
卷管理
system
系统管理
plugin
插件管理
secret
密钥管理
config
配置管理
子命令 (Subcommands) 每个管理命令下有多个子命令,执行具体操作。
示例:
1 2 3 docker container ls docker image build docker network create
命令选项 (Command Options) 修改命令行为的参数,通常以 -- 开头。
常用类型:
布尔选项: --detach, --interactive
键值对选项: --memory=512m, --name=mycontainer
多值选项: --env VAR1=value1 --env VAR2=value2
参数 (Arguments) 命令操作的对象,通常是镜像名、容器名、文件路径等。
示例:
1 2 docker run ubuntu:20.04 docker build .
🧩 Docker 命令结构详解 容器管理命令结构 1 docker container [选项] <子命令> [子命令选项] [参数]
子命令
功能
常用选项
示例
run
创建并运行容器
-d, --name, -p, -v, -e
docker run -d -p 80:80 nginx
start
启动容器
-a, -i
docker start mycontainer
stop
停止容器
-t(超时时间)
docker stop mycontainer
ls
列出容器
-a, -q, --filter
docker container ls -a --filter "status=exited"
rm
删除容器
-f, -v
docker rm -f mycontainer
exec
在运行中容器执行命令
-it, -e, -w
docker exec -it mycontainer bash
logs
查看容器日志
-f, --tail, --since
docker logs -f --tail 100 mycontainer
inspect
查看容器详情
--format
docker inspect --format '{{.NetworkSettings.IPAddress}}' mycontainer
镜像管理命令结构 1 docker image [选项] <子命令> [子命令选项] [参数]
子命令
功能
常用选项
示例
build
构建镜像
-t, -f, --build-arg
docker build -t myapp:1.0 .
pull
拉取镜像
--platform, -a
docker pull nginx:latest
push
推送镜像
-
docker push myrepo/myapp:1.0
ls
列出镜像
-a, -q, --filter
docker image ls --filter "dangling=true"
rm
删除镜像
-f
docker image rm nginx:latest
prune
清理未使用镜像
-a, --filter
docker image prune -a
tag
标记镜像
-
docker tag myapp:1.0 myrepo/myapp:1.0
网络管理命令结构 1 docker network [选项] <子命令> [子命令选项] [网络名]
子命令
功能
常用选项
示例
create
创建网络
-d, --subnet, --gateway
docker network create --subnet=172.20.0.0/16 mynet
ls
列出网络
--filter, -q
docker network ls --filter "driver=bridge"
inspect
查看网络详情
--format
docker network inspect mynet
connect
连接容器到网络
--ip, --alias
docker connect --ip=172.20.0.100 mynet mycontainer
disconnect
从网络断开容器
-f
docker disconnect mynet mycontainer
prune
清理未使用网络
-
docker network prune
卷管理命令结构 1 docker volume [选项] <子命令> [卷名]
子命令
功能
常用选项
示例
create
创建卷
-d, --opt
docker volume create --name mydata
ls
列出卷
--filter, -q
docker volume ls --filter "name=my"
inspect
查看卷详情
--format
docker volume inspect mydata
rm
删除卷
-
docker volume rm mydata
prune
清理未使用卷
-
docker volume prune
🔄 新旧命令结构对比 Docker 1.13+ 引入了管理命令的概念,与旧命令形成对应关系:
旧命令
新命令
说明
docker ps
docker container ls
列出容器
docker run
docker container run
运行容器
docker build
docker image build
构建镜像
docker images
docker image ls
列出镜像
docker rmi
docker image rm
删除镜像
docker network ls
docker network ls
网络列表
docker volume create
docker volume create
创建卷
注意: 旧命令仍然可用,但推荐使用新命令结构,因为它更清晰、更有组织性。
🧠 理解命令选项的层次结构 Docker 命令选项有明确的层次结构:
全局选项: 影响整个 Docker 客户端
命令选项: 影响特定命令
子命令选项: 影响子命令的行为
示例分析:
1 2 3 4 5 6 7 docker --debug \ container \ run \ -d \ --name web \ -p 8080:80 \ nginx:latest
💡 高效使用 Docker 命令的技巧 命令自动补全 1 2 3 4 5 6 7 8 9 10 11 apt-get install -y bash-completion sudo curl -L https://raw.githubusercontent.com/docker/compose/1.29.2/contrib/completion/bash/docker-compose -o /etc/bash_completion.d/docker-compose yum install -y bash-completion sudo curl -L https://raw.githubusercontent.com/docker/compose/1.29.2/contrib/completion/bash/docker-compose -o /etc/bash_completion.d/docker-compose source /etc/bash_completion
使用命令别名 1 2 3 4 alias dk='docker' alias dkl='docker logs -f' alias dkps='docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Status}}"'
格式化输出 1 2 docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Status}}\t{{.Ports}}"
使用过滤器 1 2 3 4 5 docker ps -a --filter "status=exited" docker ps --filter "label=environment=production"
组合命令 1 2 3 4 5 docker stop $(docker ps -q) docker rm $(docker ps -aq -f "status=exited" )
🚀 高级命令结构模式 命令链式操作 1 2 3 4 docker build -t myapp . && \ docker tag myapp myrepo/myapp:latest && \ docker push myrepo/myapp:latest
使用配置文件 1 2 docker --config ~/.docker-prod container run ...
跨主机操作 1 2 3 4 docker -H tcp://user@remote-host:2375 ps docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H=remote-host:2376 ps
使用 Docker Context 1 2 3 4 5 docker context create remote --docker "host=ssh://user@remote-host" docker --context remote ps
📊 Docker 命令结构总结表
层级
类型
位置
示例
说明
1
全局选项
命令最前
--debug, -H
影响整个Docker客户端
2
管理命令
主命令
container, image
功能分组命名空间
3
子命令
管理命令后
run, ls, build
具体操作命令
4
命令选项
子命令后
-d, -p, -v
修改命令行为
5
参数
命令最后
nginx:latest, .
命令操作的对象
default-runtime : 默认容器运行时(推荐runc)
其他配置
live-restore : 守护进程重启时保持容器运行
shutdown-timeout : 关闭超时时间(秒)
debug : 是否启用调试模式(生产环境应关闭)
metrics-addr : Prometheus监控指标地址
exec-opts : 执行选项
native.cgroupdriver =systemd: 使用systemd作为cgroup驱动
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 { "registry-mirrors" : [ "https://docker.mirrors.ustc.edu.cn" , "https://hub-mirror.c.163.com" ] , "insecure-registries" : [ "my-private-registry.local:5000" , "192.168.1.100:5000" ] , "log-driver" : "json-file" , "log-opts" : { "max-size" : "100m" , "max-file" : "10" , "labels" : "production" , "env" : "prod" } , "storage-driver" : "overlay2" , "storage-opts" : [ "overlay2.override_kernel_check=true" , "overlay2.size=100G" ] , "data-root" : "/mnt/docker-data" , "bip" : "172.17.0.1/16" , "default-address-pools" : [ { "base" : "192.168.0.0/16" , "size" : 24 } , { "base" : "10.10.0.0/16" , "size" : 24 } ] , "dns" : [ "8.8.8.8" , "8.8.4.4" ] , "dns-opts" : [ "use-vc" ] , "dns-search" : [ "example.com" ] , "mtu" : 1500 , "max-concurrent-downloads" : 5 , "max-concurrent-uploads" : 3 , "experimental" : true , "features" : { "buildkit" : true } , "tlsverify" : true , "tlscacert" : "/etc/docker/ca.pem" , "tlscert" : "/etc/docker/cert.pem" , "tlskey" : "/etc/docker/key.pem" , "userns-remap" : "default" , "default-ulimits" : { "nofile" : { "Name" : "nofile" , "Hard" : 65535 , "Soft" : 32768 } , "nproc" : { "Name" : "nproc" , "Hard" : 10240 , "Soft" : 5120 } } , "runtimes" : { "nvidia" : { "path" : "/usr/bin/nvidia-container-runtime" , "runtimeArgs" : [ ] } } , "default-runtime" : "runc" , "live-restore" : true , "shutdown-timeout" : 30 , "debug" : false , "metrics-addr" : "0.0.0.0:9323" , "exec-opts" : [ "native.cgroupdriver=systemd" ] }
Docker 配置代理 1 2 3 4 5 6 7 8 9 10 sudo mkdir -p /etc/systemd/system/docker.service.d sudo touch /etc/systemd/system/docker.service.d/proxy.conf # 编辑文件 vim /etc/systemd/system/docker.service.d/proxy.conf # [Service] # Environment="HTTP_PROXY=http://proxy.example.com:8080/" # Environment="HTTPS_PROXY=http://proxy.example.com:8080/" # Environment="NO_PROXY=localhost,127.0.0.1,.example.com"
Docker镜像构建 🐳 使用Dockerfile构建(推荐) Dockerfile 是一个文本文件,包含了构建Docker镜像所需的所有指令。使用Dockerfile构建镜像具有可重复性、版本控制、自动化等优势,是生产环境的首选方式。
📝 Dockerfile基础语法 基本结构:
核心指令详解:
指令
功能
语法
示例
FROM
指定基础镜像
FROM <image>[:<tag>]
FROM ubuntu:20.04
LABEL
添加元数据标签
LABEL <key>=<value>
LABEL version="1.0"
RUN
执行命令并创建新层
RUN <command>
RUN apt-get update
COPY
复制文件到镜像
COPY <src> <dest>
COPY app.jar /app/
ADD
复制并解压文件
ADD <src> <dest>
ADD archive.tar.gz /app/
WORKDIR
设置工作目录
WORKDIR <path>
WORKDIR /app
ENV
设置环境变量
ENV <key>=<value>
ENV NODE_ENV=production
ARG
定义构建参数
ARG <name>[=<default>]
ARG VERSION=latest
EXPOSE
声明端口
EXPOSE <port>
EXPOSE 8080
VOLUME
创建挂载点
VOLUME ["<path>"]
VOLUME ["/data"]
USER
切换用户
USER <user>[:<group>]
USER nginx
CMD
默认启动命令
CMD ["executable"]
CMD ["nginx", "-g", "daemon off;"]
ENTRYPOINT
入口点
ENTRYPOINT ["executable"]
ENTRYPOINT ["java", "-jar"]
🎯 Dockerfile实战示例 示例1:Node.js应用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 FROM node:18 -alpine AS builderWORKDIR /app COPY package*.json ./ RUN npm ci --only=production COPY . . RUN npm run build FROM node:18 -alpine AS runnerRUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 nextjs WORKDIR /app COPY --from=builder --chown =nextjs:nodejs /app/.next ./.next COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/package.json ./package.json USER nextjsEXPOSE 3000 HEALTHCHECK --interval=30s --timeout =3s --start-period=5s --retries=3 \ CMD curl -f http://localhost:3000/api/health || exit 1 CMD ["npm" , "start" ]
示例2:Java Spring Boot应用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 FROM maven:3.8 .4 -openjdk-17 AS builderWORKDIR /app COPY pom.xml . RUN mvn dependency:go-offline -B COPY src ./src RUN mvn clean package -DskipTests FROM openjdk:17 -jre-slimRUN apt-get update && apt-get install -y \ curl \ && rm -rf /var/lib/apt/lists/* RUN groupadd -r spring && useradd -r -g spring spring WORKDIR /app COPY --from=builder /app/target/*.jar app.jar RUN chown spring:spring app.jar USER springENV JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0" EXPOSE 8080 HEALTHCHECK --interval=30s --timeout =3s --start-period=40s --retries=3 \ CMD curl -f http://localhost:8080/actuator/health || exit 1 CMD java $JAVA_OPTS -jar app.jar
示例3:Python Flask应用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 FROM python:3.11 -slimENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ PIP_NO_CACHE_DIR=1 \ PIP_DISABLE_PIP_VERSION_CHECK=1 RUN apt-get update && apt-get install -y \ gcc \ && rm -rf /var/lib/apt/lists/* RUN groupadd -r appuser && useradd -r -g appuser appuser WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . RUN chown -R appuser:appuser /app USER appuserEXPOSE 5000 CMD ["gunicorn" , "--bind" , "0.0.0.0:5000" , "app:app" ]
✨ Dockerfile最佳实践 1. 镜像层数优化
1 2 3 4 5 6 7 8 9 10 11 RUN apt-get update RUN apt-get install -y curl RUN apt-get install -y wget RUN rm -rf /var/lib/apt/lists/* RUN apt-get update && apt-get install -y \ curl \ wget \ && rm -rf /var/lib/apt/lists/*
2. 利用构建缓存
1 2 3 4 5 6 COPY package*.json ./ RUN npm install COPY . .
3. 使用.dockerignore
1 2 3 4 5 6 7 8 9 node_modules .git .gitignore README.md .env .nyc_output coverage .npm
4. 多阶段构建减小镜像大小
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 FROM node:18 AS builderWORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build FROM node:18 -alpineWORKDIR /app COPY --from=builder /app/dist ./dist COPY --from=builder /app/package*.json ./ RUN npm ci --only=production CMD ["npm" , "start" ]
5. 安全最佳实践
1 2 3 4 5 6 7 8 9 10 11 RUN groupadd -r appuser && useradd -r -g appuser appuser USER appuserRUN apt-get update && apt-get install -y --no-install-recommends \ package-name \ && rm -rf /var/lib/apt/lists/* VOLUME ["/tmp" ]
🔨 镜像构建命令详解 基础构建命令:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 docker build -t myapp:latest . docker build -f Dockerfile.prod -t myapp:prod . docker build --build-arg VERSION=1.0 -t myapp:1.0 . docker build --target production -t myapp:prod . docker build --no-cache -t myapp:latest .
高级构建选项:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 docker build --memory=1g -t myapp . docker build -t myapp https://github.com/user/repo.git docker build -t myapp - < Dockerfile docker build --squash -t myapp . docker build --progress=plain -t myapp .
BuildKit增强功能:
1 2 3 4 5 6 7 8 9 10 11 12 export DOCKER_BUILDKIT=1docker build --build-arg BUILDKIT_INLINE_CACHE=1 -t myapp . RUN --mount=type =cache,target=/var/cache/apt \ apt-get update && apt-get install -y curl wget RUN --mount=type =secret,id =mysecret cat /run/secrets/mysecret
⚡ 镜像优化技巧 镜像大小优化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 FROM alpine:latest FROM golang:1.19 AS builderWORKDIR /app COPY . . RUN go build -o main . FROM scratchCOPY --from=builder /app/main . COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ CMD ["./main" ] RUN apt-get update && apt-get install -y --no-install-recommends \ curl wget ca-certificates \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* \ && rm -rf /tmp/* RUN command1 && command2 && command3
性能优化:
1 2 3 4 5 6 7 8 9 10 COPY requirements.txt . RUN pip install -r requirements.txt COPY . . RUN make -j$(nproc )
📦 通过docker commit基于容器创建 docker commit 是一种基于现有容器状态创建新镜像的方法。虽然不如Dockerfile方式规范和可重复,但在某些场景下(如调试、快速原型)仍然有用。
🔄 基本使用方法 基础语法:
1 docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
常用选项:
选项
功能
示例
-a, --author
指定作者
-a "John Doe <john@example.com>"
-c, --change
应用Dockerfile指令
-c "EXPOSE 8080"
-m, --message
提交信息
-m "Added nginx configuration"
-p, --pause
提交时暂停容器
-p=false
📋 完整操作流程 步骤1:启动基础容器
1 2 docker run -it --name mycontainer ubuntu:20.04 /bin/bash
步骤2:在容器中进行修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 apt-get update apt-get install -y nginx echo "Hello Docker" > /var/www/html/index.htmlecho 'server { listen 80; server_name localhost; location / { root /var/www/html; index index.html; } }' > /etc/nginx/sites-available/defaultexit
步骤3:提交容器为镜像
1 2 3 4 5 6 7 8 9 10 docker commit mycontainer mynginx:1.0 docker commit \ -a "Your Name <your.email@example.com>" \ -m "Added nginx and custom index page" \ -c "EXPOSE 80" \ -c "CMD ['nginx', '-g', 'daemon off;']" \ mycontainer mynginx:1.0
步骤4:验证新镜像
1 2 3 4 5 6 7 8 docker images mynginx docker run -d -p 8080:80 --name test-nginx mynginx:1.0 curl http://localhost:8080
🔧 高级用法示例 示例1:数据库镜像定制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 docker run -d --name mysql-base \ -e MYSQL_ROOT_PASSWORD=password \ -v mysql-data:/var/lib/mysql \ mysql:8.0 sleep 30docker exec -i mysql-base mysql -uroot -ppassword << EOF CREATE DATABASE myapp; USE myapp; CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50), email VARCHAR(100) ); INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com'), ('Bob', 'bob@example.com'); # 创建应用用户并授予权限 CREATE USER 'appuser'@'%' IDENTIFIED BY 'apppassword'; GRANT ALL PRIVILEGES ON myapp.* TO 'appuser'@'%'; FLUSH PRIVILEGES; EOF docker exec -it mysql-base bash -c 'echo "[mysqld]\nmax_connections=1000\ninnodb_buffer_pool_size=256M" >> /etc/mysql/conf.d/custom.cnf' docker commit mysql-base mysql-with-data:1.0
示例2:开发环境镜像
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 docker run -it --name dev-env ubuntu:20.04 apt-get update && apt-get install -y \ curl \ git \ vim \ nodejs \ npm \ python3 \ python3-pip npm install -g yarn typescript pip3 install requests flask echo 'alias ll="ls -la"' >> ~/.bashrcecho 'export PATH=$PATH:/usr/local/bin' >> ~/.bashrcexit docker commit dev-env my-dev-env:latest
⚖️ commit vs Dockerfile 对比
特性
docker commit
Dockerfile
可重复性
❌ 低
✅ 高
版本控制
❌ 困难
✅ 容易
自动化
❌ 不支持
✅ 完全支持
透明度
❌ 黑盒操作
✅ 步骤明确
调试能力
✅ 容易
❌ 需重新构建
学习成本
✅ 低
❌ 相对较高
生产环境
❌ 不推荐
✅ 推荐
快速原型
✅ 适合
❌ 相对繁琐
💡 commit最佳实践 1. 适用场景
2. 操作建议
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 docker exec mycontainer bash -c ' apt-get clean rm -rf /var/lib/apt/lists/* rm -rf /tmp/* history -c ' docker commit \ -a "Developer Name <dev@company.com>" \ -m "Detailed description of changes made" \ mycontainer myimage:tag docker commit \ -c "LABEL version=1.0" \ -c "LABEL description='Custom nginx with app'" \ -c "EXPOSE 80" \ -c "WORKDIR /app" \ mycontainer myimage:1.0
3. 镜像验证
1 2 3 4 5 6 7 8 docker inspect myimage:1.0 docker history myimage:1.0 docker run --rm -p 8080:80 myimage:1.0
🔄 从commit迁移到Dockerfile 当你使用commit创建了有用的镜像后,建议将其转换为Dockerfile以便维护:
步骤1:分析镜像层
1 2 3 4 5 docker history myimage:1.0 docker inspect myimage:1.0
步骤2:重建Dockerfile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 FROM ubuntu:20.04 RUN apt-get update && apt-get install -y \ nginx \ && rm -rf /var/lib/apt/lists/* COPY nginx.conf /etc/nginx/sites-available/default COPY index.html /var/www/html/ RUN chown -R www-data:www-data /var/www/html EXPOSE 80 CMD ["nginx" , "-g" , "daemon off;" ]
步骤3:验证一致性
1 2 3 4 5 6 7 8 9 10 docker build -t myimage:dockerfile . docker run -d --name test1 myimage:1.0 docker run -d --name test2 myimage:dockerfile curl http://localhost:8080 curl http://localhost:8081
容器编排 容器编排是管理多个容器应用的关键技术,它能够自动化容器的部署、扩展、网络配置和生命周期管理。本章将详细介绍两种主要的容器编排解决方案:Docker Compose(适用于单机环境)和Kubernetes(适用于生产级分布式环境)。
🎼 Docker Compose编排 Docker Compose 是 Docker 官方的容器编排工具,通过 YAML 文件定义多容器应用的配置,简化了复杂应用的部署和管理。它特别适合开发环境、测试环境以及小型生产环境。
📋 Docker Compose 基础 核心概念:
服务(Service) :容器的逻辑单元,一个服务可以运行多个相同的容器实例
网络(Network) :服务之间的通信网络
卷(Volume) :数据持久化和共享存储
配置(Config) :应用程序配置管理
密钥(Secret) :敏感信息管理
文件结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 version: '3.8' services: service1: service2: networks: network1: volumes: volume1: configs: config1: secrets: secret1:
🔧 Compose 文件语法详解 服务配置选项:
配置项
功能描述
示例
image
指定镜像
image: nginx:latest
build
构建配置
build: . 或 build: {context: ., dockerfile: Dockerfile.prod}
container_name
容器名称
container_name: web-server
ports
端口映射
ports: ["8080:80", "443:443"]
environment
环境变量
environment: {NODE_ENV: production}
env_file
环境文件
env_file: [.env, .env.local]
volumes
卷挂载
volumes: ["./data:/app/data", "logs:/var/log"]
networks
网络配置
networks: [frontend, backend]
depends_on
依赖关系
depends_on: [db, redis]
restart
重启策略
restart: unless-stopped
healthcheck
健康检查
healthcheck: {test: ["CMD", "curl", "-f", "http://localhost"]}
deploy
部署配置
deploy: {replicas: 3, resources: {limits: {memory: 512M}}}
🎯 实战示例 示例1:简单Web应用栈
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 version: '3.8' services: web: image: nginx:alpine container_name: web-server ports: - "80:80" - "443:443" volumes: - ./html:/usr/share/nginx/html - ./config/nginx.conf:/etc/nginx/nginx.conf depends_on: - app networks: - webnet restart: unless-stopped app: build: . container_name: app-server environment: - NODE_ENV=production - DB_HOST=database - REDIS_HOST=cache depends_on: - database - cache networks: - webnet - dbnet restart: unless-stopped database: image: mysql:8.0 container_name: mysql-db environment: MYSQL_ROOT_PASSWORD: rootpass MYSQL_DATABASE: myapp MYSQL_USER: appuser MYSQL_PASSWORD: apppass volumes: - db_data:/var/lib/mysql - ./mysql-init:/docker-entrypoint-initdb.d networks: - dbnet restart: unless-stopped healthcheck: test: ["CMD" , "mysqladmin" , "ping" , "-h" , "localhost" ] interval: 30s timeout: 10s retries: 5 cache: image: redis:alpine container_name: redis-cache command: redis-server --appendonly yes volumes: - redis_data:/data networks: - dbnet restart: unless-stopped networks: webnet: driver: bridge dbnet: driver: bridge volumes: db_data: redis_data:
示例2:微服务架构栈
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 version: '3.8' services: api-gateway: build: ./api-gateway ports: - "3000:3000" environment: - USER_SERVICE=http://user-service:3001 - ORDER_SERVICE=http://order-service:3002 depends_on: - user-service - order-service networks: - microservices user-service: build: ./user-service environment: - DB_HOST=user-db - REDIS_HOST=redis depends_on: - user-db - redis networks: - microservices - user-network order-service: build: ./order-service environment: - DB_HOST=order-db - MESSAGE_QUEUE=rabbitmq depends_on: - order-db - rabbitmq networks: - microservices - order-network user-db: image: postgres:13 environment: POSTGRES_DB: users POSTGRES_USER: user POSTGRES_PASSWORD: password volumes: - user_db_data:/var/lib/postgresql/data networks: - user-network order-db: image: postgres:13 environment: POSTGRES_DB: orders POSTGRES_USER: user POSTGRES_PASSWORD: password volumes: - order_db_data:/var/lib/postgresql/data networks: - order-network redis: image: redis:alpine networks: - microservices rabbitmq: image: rabbitmq:3-management ports: - "15672:15672" networks: - microservices networks: microservices: user-network: order-network: volumes: user_db_data: order_db_data:
⚡ Docker Compose 命令详解 基础命令:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 docker-compose up docker-compose up -d docker-compose up web db docker-compose ps docker-compose stop docker-compose down docker-compose logs -f
高级命令:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 docker-compose -f production.yml up -d docker-compose up -d --scale web=3 docker-compose up -d --build docker-compose exec web bash docker-compose run --rm web npm test
💡 Docker Compose 最佳实践 1. 环境分离
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 version: '3.8' services: web: build: . ports: - "${WEB_PORT:-3000}:3000" environment: - NODE_ENV=${NODE_ENV:-development} version: '3.8' services: web: volumes: - .:/app command: npm run dev version: '3.8' services: web: image: myapp:latest deploy: replicas: 3 resources: limits: memory: 512M
2. 健康检查
1 2 3 4 5 6 7 8 9 services: web: image: nginx healthcheck: test: ["CMD" , "curl" , "-f" , "http://localhost" ] interval: 30s timeout: 10s retries: 3 start_period: 60s
3. 资源限制
1 2 3 4 5 6 7 8 9 10 11 services: app: image: myapp deploy: resources: limits: memory: 1G cpus: '0.5' reservations: memory: 512M cpus: '0.25'
☸️ Kubernetes (K8s) 编排 Kubernetes 是Google开源的容器编排平台,提供了生产级的容器管理、自动扩展、服务发现、负载均衡等功能。它是目前最流行的容器编排解决方案,适用于大规模分布式应用。
🏗️ Kubernetes 架构概述 控制平面(Control Plane)组件:
组件
功能描述
API Server
集群的统一入口,处理所有REST操作
etcd
分布式键值存储,保存集群状态
Controller Manager
运行各种控制器,维护集群状态
Scheduler
负责Pod调度到合适的Node
节点(Node)组件:
组件
功能描述
kubelet
在每个节点运行,管理Pod生命周期
kube-proxy
网络代理,实现Service的网络规则
Container Runtime
容器运行时(Docker、containerd等)
📦 核心资源对象
资源类型
功能描述
使用场景
Pod
最小部署单元,包含一个或多个容器
运行应用容器
Deployment
管理Pod的部署和更新
无状态应用部署
StatefulSet
管理有状态应用的部署
数据库、有状态服务
Service
提供稳定的网络端点
服务发现和负载均衡
Ingress
管理外部访问
HTTP/HTTPS路由
ConfigMap
配置数据管理
应用配置
Secret
敏感信息管理
密码、证书、密钥
PersistentVolume
持久化存储
数据持久化
Namespace
资源隔离
多租户、环境隔离
📝 Kubernetes YAML 配置实例 示例1:简单Web应用部署
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 apiVersion: v1 kind: Namespace metadata: name: webapp labels: name: webapp --- apiVersion: apps/v1 kind: Deployment metadata: name: webapp-deployment namespace: webapp labels: app: webapp spec: replicas: 3 selector: matchLabels: app: webapp template: metadata: labels: app: webapp spec: containers: - name: webapp image: nginx:latest ports: - containerPort: 80 resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m" livenessProbe: httpGet: path: / port: 80 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: / port: 80 initialDelaySeconds: 5 periodSeconds: 5 --- apiVersion: v1 kind: Service metadata: name: webapp-service namespace: webapp spec: selector: app: webapp ports: - protocol: TCP port: 80 targetPort: 80 type: ClusterIP --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: webapp-ingress namespace: webapp annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: webapp.example.com http: paths: - path: / pathType: Prefix backend: service: name: webapp-service port: number: 80
示例2:带数据库的应用栈
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 apiVersion: v1 kind: ConfigMap metadata: name: app-config namespace: webapp data: database_url: "postgresql://postgres:5432/myapp" redis_url: "redis://redis:6379" app.properties: | server.port=8080 logging.level.root=INFO --- apiVersion: v1 kind: Secret metadata: name: app-secrets namespace: webapp type: Opaque data: db-password: cGFzc3dvcmQxMjM= redis-password: cmVkaXNwYXNzCg== --- apiVersion: apps/v1 kind: StatefulSet metadata: name: postgres namespace: webapp spec: serviceName: postgres-headless replicas: 1 selector: matchLabels: app: postgres template: metadata: labels: app: postgres spec: containers: - name: postgres image: postgres:13 ports: - containerPort: 5432 env: - name: POSTGRES_DB value: myapp - name: POSTGRES_USER value: postgres - name: POSTGRES_PASSWORD valueFrom: secretKeyRef: name: app-secrets key: db-password volumeMounts: - name: postgres-storage mountPath: /var/lib/postgresql/data resources: requests: memory: "256Mi" cpu: "250m" limits: memory: "512Mi" cpu: "500m" volumeClaimTemplates: - metadata: name: postgres-storage spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 1Gi --- apiVersion: v1 kind: Service metadata: name: postgres-headless namespace: webapp spec: clusterIP: None selector: app: postgres ports: - port: 5432 targetPort: 5432
⚙️ Kubernetes 命令详解 基础命令:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 kubectl apply -f deployment.yaml kubectl get pods -n webapp kubectl get services -n webapp kubectl describe pod <pod-name> -n webapp kubectl logs -f <pod-name> -n webapp kubectl exec -it <pod-name> -n webapp -- /bin/bash kubectl delete -f deployment.yaml
高级命令:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 kubectl scale deployment webapp-deployment --replicas=5 -n webapp kubectl set image deployment/webapp-deployment webapp=nginx:1.20 -n webapp kubectl rollout status deployment/webapp-deployment -n webapp kubectl rollout undo deployment/webapp-deployment -n webapp kubectl port-forward service/webapp-service 8080:80 -n webapp kubectl top nodes kubectl top pods -n webapp
📊 监控和日志 Prometheus + Grafana 监控栈
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 apiVersion: apps/v1 kind: Deployment metadata: name: prometheus namespace: monitoring spec: replicas: 1 selector: matchLabels: app: prometheus template: metadata: labels: app: prometheus spec: containers: - name: prometheus image: prom/prometheus:latest ports: - containerPort: 9090 volumeMounts: - name: config mountPath: /etc/prometheus - name: storage mountPath: /prometheus volumes: - name: config configMap: name: prometheus-config - name: storage emptyDir: {} --- apiVersion: v1 kind: Service metadata: name: prometheus namespace: monitoring spec: selector: app: prometheus ports: - port: 9090 targetPort: 9090 type: ClusterIP
💯 Kubernetes 最佳实践 1. 资源限制
1 2 3 4 5 6 7 resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m"
资源类型说明:
memory (内存) : 单位可以是 Mi (mebibytes), Gi (gibibytes), M (megabytes), G (gigabytes)
cpu (CPU) : 单位可以是 cores 或 millicores (1 core = 1000m)
注意事项:
资源请求(Requests)影响Pod的调度决策
资源限制(Limits)防止单个容器消耗过多集群资源
没有设置内存限制的容器可能导致节点内存不足
CPU限制会影响容器的CPU使用率上限,而不是绝对限制
2. 健康检查
1 2 3 4 5 6 7 8 9 10 11 12 13 livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: /ready port: 8080 initialDelaySeconds: 5 periodSeconds: 5
3. 安全配置
1 2 3 4 5 6 7 8 securityContext: runAsNonRoot: true runAsUser: 1000 allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: - ALL
4. 标签和注释
1 2 3 4 5 6 7 8 9 metadata: labels: app: webapp version: v1.0.0 environment: production team: backend annotations: deployment.kubernetes.io/revision: "1" description: "Web application frontend"
⚖️ Docker Compose vs Kubernetes 对比
特性
Docker Compose
Kubernetes
复杂度
简单,容易上手
复杂,学习曲线陡峻
适用场景
开发/测试环境,单机部署
生产环境,大规模集群部署
高可用性
有限支持,需手动配置
原生支持,自动恢复
自动扩展
支持简单的水平扩展
支持复杂的自动扩缩容策略
负载均衡
提供基础的负载均衡
提供高级负载均衡和会话亲和性
服务发现
内置DNS服务发现
强大的服务发现机制
配置管理
环境变量、外部文件挂载
ConfigMap/Secret等多种配置管理方式
监控
基础监控,需第三方集成
丰富的监控生态系统
部署策略
支持基本的部署策略
支持滚动更新、蓝绿部署、金丝雀发布等高级策略
多主机
通过Swarm模式支持多主机
原生支持多主机集群
资源管理
基础资源限制
高级资源管理和配额
选择建议:
使用 Docker Compose :开发环境、小型项目、快速原型、学习和测试
使用 Kubernetes :生产环境、大规模应用、需要高可用性和自动扩展