一、一次版本不匹配引发的生产事故

上周,团队在CentOS 7上部署一个基于Docker 20.10开发的微服务应用时,遇到了一个严重问题。当我们将应用容器化部署到生产环境时,发现容器启动后频繁崩溃,查看日志提示"cgroup v2"配置错误。

问题定位:开发环境使用的是Docker 20.10+,支持cgroup v2,而生产环境的CentOS 7上安装的是Docker 1.13(通过yum install docker默认安装),只支持cgroup v1,导致容器运行时环境不兼容。

问题复现

# 在旧版Docker 1.13环境中运行现代应用
docker run -d myapp:latest
# 输出结果(报错):
# docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: 
# starting container process caused: process_linux.go:545: container init caused: 
# process_linux.go:508: setting cgroup config for procHooks process caused: 
# Failed to write 536870912: write /sys/fs/cgroup/memory/docker/xxxx/memory.limit_in_bytes: 
# invalid argument: unknown.

解决方案:我们需要在所有环境上统一安装Docker 24.0+,确保开发、测试、生产环境的一致性。本文将详细介绍如何在CentOS 7/8、Ubuntu 20.04/22.04、Windows 10/11上正确安装Docker 24.0+。

二、Docker安装部署:定义与价值

2.1 什么是Docker安装部署?

Docker安装部署指的是在目标操作系统上安装Docker引擎(Docker Engine)、配置相关参数,并确保Docker能够正常运行和管理容器化的应用程序。

核心组件

  • Docker Daemon(dockerd):后台服务,管理Docker对象
  • Docker Client(docker):命令行工具,用户与Docker交互
  • Docker Registry:镜像仓库(Docker Hub或私有仓库)
  • containerd:容器运行时,管理容器生命周期

2.2 Docker解决了什么问题?

问题类型传统方式Docker方式解决效果
环境不一致每台机器手工配置镜像统一环境100%环境一致性
依赖冲突系统库版本冲突容器隔离依赖无依赖冲突
部署复杂手动安装配置一键部署部署时间从小时级到分钟级
资源浪费每个应用独占VM共享OS内核资源利用率提升50-70%
迁移困难环境重建镜像迁移跨云、跨平台无缝迁移

2.3 应用场景

  1. 开发环境标准化

    # 新成员加入,只需执行
    git clone project
    docker-compose up -d
    # 开发环境就绪,无需手动安装任何依赖
    
  2. 微服务架构部署

    # 每个微服务独立容器
    docker run -d --name user-service user:1.0
    docker run -d --name order-service order:1.0
    docker run -d --name payment-service payment:1.0
    
  3. CI/CD流水线

    # Jenkins Pipeline中使用Docker
    stage('Build') {
        sh 'docker build -t app:$BUILD_NUMBER .'
    }
    stage('Test') {
        sh 'docker run app:$BUILD_NUMBER npm test'
    }
    
  4. 生产环境容器化

    # Kubernetes中使用Docker容器
    kubectl apply -f deployment.yaml
    

三、Docker架构深度解析

3.1 完整Docker架构图

┌─────────────────────────────────────────────────────────────────────┐
│                       Docker Client                                  │
│  ┌─────────────────────────────────────────────────────────────┐    │
│  │                     docker CLI                               │    │
│  │                     Docker Desktop                           │    │
│  │                     Docker SDK/API                           │    │
│  └─────────────────────────────────────────────────────────────┘    │
└──────────────────────────────┬───────────────────────────────────────┘
                               │ REST API (HTTP/HTTPS)
┌──────────────────────────────▼───────────────────────────────────────┐
│                        Docker Host                                   │
│  ┌──────────────────────────────────────────────────────────────┐   │
│  │                    Docker Daemon (dockerd)                   │   │
│  │  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐     │   │
│  │  │  Container   │  │  Container   │  │  Container   │     │   │
│  │  │   (Nginx)    │  │   (MySQL)    │  │   (Redis)    │     │   │
│  │  └──────┬───────┘  └──────┬───────┘  └──────┬───────┘     │   │
│  │         │                 │                 │              │   │
│  │  ┌──────▼─────────────────▼─────────────────▼──────┐      │   │
│  │  │             containerd (运行时)                  │      │   │
│  │  │  ┌──────────────────────────────────────────┐  │      │   │
│  │  │  │            runc (容器运行时)               │  │      │   │
│  │  │  └──────────────────────────────────────────┘  │      │   │
│  │  └─────────────────────────────────────────────────┘      │   │
│  └──────────────────────────────────────────────────────────────┘   │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐         │   │
│  │    Images     │  │   Networks    │  │   Volumes    │         │   │
│  │  (镜像存储)    │  │  (网络管理)   │  │  (数据管理)   │         │   │
│  └──────────────┘  └──────────────┘  └──────────────┘         │   │
└─────────────────────────────────────────────────────────────────────┘
                               │
┌──────────────────────────────▼───────────────────────────────────────┐
│                     Docker Registry                                 │
│  ┌──────────────────────────────────────────────────────────────┐  │
│  │                   Docker Hub (公共)                           │  │
│  │  ┌────────────────────────────────────────────────────────┐  │  │
│  │  │                Private Registry (私有)                  │  │  │
│  │  └────────────────────────────────────────────────────────┘  │  │
│  └──────────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────────┘

3.2 安装部署操作流程图

开始安装
    │
    ▼
检查系统要求
    │
    ▼
卸载旧版本 ←─┐
    │        │
    ▼        │
添加Docker仓库 │
    │        │
    ▼        │
安装Docker 24.0+ │
    │        │
    ▼        │
配置Docker Daemon │
    │        │
    ▼        │
启动Docker服务 │
    │        │
    ▼        │
验证安装结果 │
    │        │
    └────────┘
    │
    ▼
加入docker用户组
    │
    ▼
配置镜像加速器
    │
    ▼
安装完成

3.3 镜像分层结构原理

┌─────────────────────────────────────────────┐
│           Container Layer (容器层)           │
│          ├─────────────────────────────     │
│          │ 可读写层 (R/W)                   │
│          │ 存储容器运行时变化               │
│          │ 如:日志文件、临时文件           │
│          └─────────────────────────────     │
├─────────────────────────────────────────────┤
│           Image Layer 3 (镜像层3)           │
│          ├─────────────────────────────     │
│          │ 只读层 (Read-Only)               │
│          │ 应用层:应用代码                 │
│          └─────────────────────────────     │
├─────────────────────────────────────────────┤
│           Image Layer 2 (镜像层2)           │
│          ├─────────────────────────────     │
│          │ 只读层 (Read-Only)               │
│          │ 依赖层:系统依赖包               │
│          └─────────────────────────────     │
├─────────────────────────────────────────────┤
│           Image Layer 1 (镜像层1)           │
│          ├─────────────────────────────     │
│          │ 只读层 (Read-Only)               │
│          │ 系统层:操作系统文件             │
│          └─────────────────────────────     │
├─────────────────────────────────────────────┤
│           Base Image (基础镜像)             │
│          ├─────────────────────────────     │
│          │ 如:alpine:3.18                 │
│          │     ubuntu:22.04                │
│          └─────────────────────────────     │
└─────────────────────────────────────────────┘

分层优势

  • 节省存储:多个镜像共享基础层
  • 加速构建:已存在的层不需要重新下载
  • 快速部署:只需拉取变化的层

四、CentOS 7安装Docker 24.0+(完整步骤)

4.1 系统要求检查

# 1. 检查CentOS版本
cat /etc/redhat-release
# 输出结果:
# CentOS Linux release 7.9.2009 (Core)
# 注意:CentOS 7.6+ 支持Docker 24.0+

# 2. 检查内核版本
uname -r
# 输出结果:
# 3.10.0-1160.88.1.el7.x86_64
# 注意:内核3.10+支持Docker,但推荐4.0+以获得overlay2等新特性

# 3. 检查系统架构
arch
# 输出结果:
# x86_64
# Docker支持x86_64、arm64等架构

4.2 卸载旧版本Docker

# 停止Docker服务
sudo systemctl stop docker
# 输出结果:无输出表示成功停止

# 卸载旧版本Docker及相关包
sudo yum remove -y docker \
    docker-client \
    docker-client-latest \
    docker-common \
    docker-latest \
    docker-latest-logrotate \
    docker-logrotate \
    docker-engine
# 输出结果:
# Complete! (表示卸载完成)

# 删除旧Docker数据(谨慎操作,会删除所有容器和镜像)
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd

4.3 安装依赖包

# 安装yum工具和存储驱动依赖
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# 输出结果:
# Package yum-utils-1.1.31-54.el7_8.noarch already installed
# Package device-mapper-persistent-data-0.8.5-3.el7_9.2.x86_64 already installed
# Package lvm2-7:2.02.187-6.el7_9.5.x86_64 already installed
# Complete!

4.4 添加Docker官方仓库

# 设置稳定的仓库
sudo yum-config-manager --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
# 输出结果:
# 正在加载插件:fastestmirror
# adding repo from: https://download.docker.com/linux/centos/docker-ce.repo
# grabbing file https://download.docker.com/linux/centos/docker-ce.repo
# repo saved to /etc/yum.repos.d/docker-ce.repo

# 查看可用的Docker版本
yum list docker-ce --showduplicates | sort -r
# 输出结果(部分):
# docker-ce.x86_64            3:24.0.0-1.el7             docker-ce-stable
# docker-ce.x86_64            3:23.0.0-1.el7             docker-ce-stable
# docker-ce.x86_64            3:20.10.24-3.el7           docker-ce-stable
# 注意:我们选择24.0.0及以上版本

4.5 安装Docker 24.0+

# 安装Docker CE、CLI、containerd、buildx插件、compose插件
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# 输出结果:
# Installing:
#  docker-ce                 x86_64 3:24.0.0-1.el7    docker-ce-stable  87 M
#  docker-ce-cli            x86_64 3:24.0.0-1.el7    docker-ce-stable  28 M
#  containerd.io            x86_64 1.6.21-3.1.el7    docker-ce-stable  33 M
#  docker-buildx-plugin     x86_64 0.10.4-1.el7      docker-ce-stable  12 M
#  docker-compose-plugin    x86_64 2.18.1-1.el7      docker-ce-stable  12 M
# Complete!

4.6 启动Docker服务

# 启动Docker服务
sudo systemctl start docker
# 输出结果:无输出表示启动成功

# 设置开机自启
sudo systemctl enable docker
# 输出结果:
# Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.

# 查看Docker服务状态
sudo systemctl status docker
# 输出结果(部分):
# ● docker.service - Docker Application Container Engine
#    Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
#    Active: active (running) since Tue 2023-10-10 10:00:00 CST; 10s ago
#      Docs: https://docs.docker.com
#  Main PID: 1234 (dockerd)
#    CGroup: /system.slice/docker.service

4.7 验证安装

# 查看Docker版本
docker --version
# 输出结果:
# Docker version 24.0.0, build 98fdcd7

# 查看详细版本信息
docker version
# 输出结果:
# Client: Docker Engine - Community
#  Version:           24.0.0
#  API version:       1.43
#  Go version:        go1.20.4
#  Git commit:        98fdcd7
#  Built:             Tue Jun 20 15:34:17 2023
#  OS/Arch:           linux/amd64
#  Context:           default
# 
# Server: Docker Engine - Community
#  Engine:
#   Version:          24.0.0
#   API version:      1.43 (minimum version 1.12)
#   Go version:       go1.20.4
#   Git commit:       4ffc614
#   Built:            Tue Jun 20 15:33:16 2023
#   OS/Arch:          linux/amd64
#   Experimental:     false
#  containerd:
#   Version:          1.6.21
#   GitCommit:        3dce8eb055cbb6872793272b4f20ed16117344f8
#  runc:
#   Version:          1.1.7
#   GitCommit:        v1.1.7-0-g860f061
#  docker-init:
#   Version:          0.19.0
#   GitCommit:        de40ad0

# 运行测试容器
docker run hello-world
# 输出结果:
# Hello from Docker!
# This message shows that your installation appears to be working correctly.

4.8 配置非root用户使用Docker

# 创建docker用户组(通常安装时已自动创建)
sudo groupadd docker
# 输出结果:groupadd: group 'docker' already exists

# 将当前用户加入docker组
sudo usermod -aG docker $USER
# 输出结果:无输出表示成功

# 重新登录使组权限生效
# 或者执行以下命令立即生效
newgrp docker
# 输出结果:无输出

# 验证非root用户权限
docker ps
# 输出结果:
# CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
# 空列表表示当前没有运行容器

五、CentOS 8安装Docker 24.0+

5.1 CentOS 8与CentOS 7的区别

# 1. 检查系统版本
cat /etc/redhat-release
# 输出结果:
# CentOS Linux release 8.5.2111

# 2. 注意:CentOS 8默认使用podman,需要先禁用
sudo dnf remove -y podman buildah
# 输出结果:Removed podman-1.6.4-32.module_el8.5.0+1004+63aaf052.x86_64

5.2 安装步骤

# 1. 卸载旧版本
sudo dnf remove -y docker \
    docker-client \
    docker-client-latest \
    docker-common \
    docker-latest \
    docker-latest-logrotate \
    docker-logrotate \
    docker-engine

# 2. 安装依赖
sudo dnf install -y yum-utils device-mapper-persistent-data lvm2

# 3. 添加仓库
sudo yum-config-manager --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

# 4. 禁用CentOS官方仓库中的Docker模块
sudo dnf config-manager --disable docker-ce
sudo dnf config-manager --enable docker-ce-stable

# 5. 安装Docker
sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# 输出结果:Complete!

# 6. 启动服务
sudo systemctl start docker
sudo systemctl enable docker

六、Ubuntu 20.04/22.04安装Docker 24.0+

6.1 Ubuntu 20.04安装步骤

# 1. 更新apt包索引
sudo apt update
# 输出结果:
# Hit:1 http://archive.ubuntu.com/ubuntu focal InRelease
# Get:2 http://archive.ubuntu.com/ubuntu focal-updates InRelease [114 kB]
# ... 更新完成

# 2. 安装依赖包
sudo apt install -y \
    ca-certificates \
    curl \
    gnupg \
    lsb-release
# 输出结果:
# Setting up ca-certificates (20211016) ...
# Setting up curl (7.68.0-1ubuntu2.18) ...
# Setting up gnupg (2.2.19-3ubuntu2.2) ...
# Setting up lsb-release (11.1.0ubuntu2) ...
# Processing triggers for man-db (2.9.1-1) ...

# 3. 添加Docker官方GPG密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# 输出结果:无输出表示成功

# 4. 设置稳定版仓库
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 输出结果:无输出

# 5. 更新apt包索引
sudo apt update
# 输出结果:包含docker-ce-stable仓库信息

# 6. 安装Docker
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# 输出结果:
# Setting up docker-ce (5:24.0.0-1~ubuntu.20.04~focal) ...
# Setting up docker-ce-cli (5:24.0.0-1~ubuntu.20.04~focal) ...
# Setting up containerd.io (1.6.21-1) ...
# Setting up docker-buildx-plugin (0.10.4-1~ubuntu.20.04~focal) ...
# Setting up docker-compose-plugin (2.18.1-1~ubuntu.20.04~focal) ...

# 7. 启动服务
sudo systemctl start docker
sudo systemctl enable docker

6.2 Ubuntu 22.04特定配置

# Ubuntu 22.04需要额外配置cgroup驱动
# 创建daemon.json配置文件
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
EOF

# 重启Docker
sudo systemctl restart docker

七、Windows 10/11安装Docker Desktop

7.1 系统要求检查

  1. Windows 10/11 64位:专业版、企业版或教育版
  2. 开启Hyper-V和容器功能(Windows功能)
  3. 开启WSL2(Windows Subsystem for Linux 2)
  4. 至少4GB RAM

7.2 安装步骤

# 1. 以管理员身份打开PowerShell
# 2. 启用WSL2功能
wsl --install
# 输出结果:
# 正在安装: 虚拟机平台
# 已安装 虚拟机平台
# 正在安装: Windows 子系统 for Linux
# 已安装 Windows 子系统 for Linux
# 正在安装: WSL 内核
# 已安装 WSL 内核
# 正在下载: WSLg
# 已安装 WSLg
# 正在下载: Ubuntu
# 已安装 Ubuntu
# 操作成功完成。需要重启系统才能应用更改。

# 3. 下载Docker Desktop安装包
# https://desktop.docker.com/win/main/amd64/Docker%20Desktop%20Installer.exe

# 4. 安装后验证
docker --version
# 输出结果:
# Docker version 24.0.2, build cb74dfc

7.3 Docker Desktop配置

  1. Settings → General

    • 启用Start Docker Desktop when you log in
    • 启用Use Docker Compose V2
  2. Settings → Resources

    • CPU:推荐4核+
    • Memory:推荐8GB+
    • Swap:推荐1GB
  3. Settings → Docker Engine

{
  "registry-mirrors": [
    "https://docker.mirrors.ustc.edu.cn"
  ],
  "experimental": true
}

八、Docker配置详解(daemon.json)

8.1 完整配置文件示例

{
  "authorization-plugins": [],
  "data-root": "/var/lib/docker",
  "exec-opts": ["native.cgroupdriver=systemd"],
  "dns": ["8.8.8.8", "114.114.114.114"],
  "dns-opts": [],
  "dns-search": ["example.com"],
  "hosts": [
    "unix:///var/run/docker.sock",
    "tcp://0.0.0.0:2376"
  ],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m",
    "max-file": "3",
    "labels": "production_status",
    "env": "os,customer"
  },
  "storage-driver": "overlay2",
  "storage-opts": [
    "overlay2.override_kernel_check=true"
  ],
  "labels": ["env=production"],
  "live-restore": true,
  "max-concurrent-downloads": 3,
  "max-concurrent-uploads": 5,
  "default-shm-size": "64m",
  "shutdown-timeout": 15,
  "debug": false,
  "experimental": false,
  "features": {
    "buildkit": true
  },
  "registry-mirrors": [
    "https://docker.mirrors.ustc.edu.cn",
    "https://hub-mirror.c.163.com",
    "https://mirror.baidubce.com"
  ],
  "insecure-registries": [
    "192.168.1.100:5000"
  ],
  "runtimes": {
    "nvidia": {
      "path": "/usr/bin/nvidia-container-runtime",
      "runtimeArgs": []
    }
  },
  "default-ulimits": {
    "nofile": {
      "Name": "nofile",
      "Hard": 65536,
      "Soft": 65536
    },
    "nproc": {
      "Name": "nproc",
      "Hard": 65536,
      "Soft": 65536
    }
  },
  "log-level": "info",
  "iptables": true,
  "ip-forward": true,
  "ip-masq": true,
  "userland-proxy": true,
  "userland-proxy-path": "/usr/libexec/docker-proxy",
  "ip": "0.0.0.0",
  "bridge": "",
  "bip": "",
  "fixed-cidr": "",
  "fixed-cidr-v6": "",
  "mtu": 0,
  "default-gateway": "",
  "default-gateway-v6": "",
  "raw-logs": false,
  "allow-nondistributable-artifacts": [],
  "registry-configs": {},
  "service-cluster-ip-range": "10.96.0.0/12",
  "default-address-pools": [
    {
      "base": "172.80.0.0/16",
      "size": 24
    },
    {
      "base": "172.90.0.0/16",
      "size": 24
    }
  ]
}

8.2 关键配置项说明

配置项作用默认值推荐值
data-rootDocker数据存储路径/var/lib/docker大容量磁盘分区
log-driver日志驱动json-filejson-file
log-opts.max-size单日志文件最大大小-1(无限制)10m(生产环境)
storage-driver存储驱动自动选择overlay2
registry-mirrors镜像加速器国内镜像源
live-restore守护进程重启保持容器falsetrue(生产)
max-concurrent-downloads最大并发下载数33-5
experimental实验性功能false开发环境true

8.3 配置生效

# 重新加载配置
sudo systemctl daemon-reload
# 输出结果:无输出

# 重启Docker服务
sudo systemctl restart docker
# 输出结果:无输出

# 查看配置是否生效
docker info | grep -A 5 "Docker Root Dir"
# 输出结果:
# Docker Root Dir: /var/lib/docker
# Debug Mode: false

九、Docker命令详解

9.1 基本语法

# 基本语法
docker [OPTIONS] COMMAND [ARG...]

# 查看所有命令
docker --help
# 输出结果:
# Commands:
#   run         Create and run a new container from an image
#   start       Start one or more stopped containers
#   stop        Stop one or more running containers
#   build       Build an image from a Dockerfile
#   pull        Download an image from a registry
#   push        Upload an image to a registry
#   ... 更多命令

9.2 常用参数说明

# 运行容器参数示例
docker run \
  -d \                    # 后台运行
  -it \                   # 交互式终端
  --name myapp \         # 容器名称
  -p 8080:80 \           # 端口映射
  -v /data:/app \        # 数据卷挂载
  -e NODE_ENV=production \ # 环境变量
  --network mynet \      # 网络
  --restart=always \     # 重启策略
  --memory="512m" \      # 内存限制
  --cpus="1.0" \         # CPU限制
  nginx:latest           # 镜像

9.3 命令分类详解

9.3.1 镜像管理命令
# 搜索镜像
docker search nginx
# 输出结果:
# NAME        DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
# nginx       Official build of Nginx.                        18000     [OK]       
# nginx/unit  NGINX Unit                                      158       [OK]       
# bitnami/nginx  Bitnami nginx Docker Image                   132       [OK]       

# 拉取镜像
docker pull nginx:1.23.0-alpine
# 输出结果:
# 1.23.0-alpine: Pulling from library/nginx
# 7264a8db6415: Pull complete 
# Digest: sha256:683e901c7a5e3f9e2a8b4d4b5d5e5f5e5f5e5f5e5f5e5f5e5f5e5f5e5f5e5f5
# Status: Downloaded newer image for nginx:1.23.0-alpine

# 查看本地镜像
docker images
# 输出结果:
# REPOSITORY   TAG              IMAGE ID       CREATED       SIZE
# nginx        1.23.0-alpine    abc123def456   2 weeks ago   23.5MB
# ubuntu       22.04            def456ghi789   3 weeks ago   77.8MB

# 删除镜像
docker rmi ubuntu:22.04
# 输出结果:
# Untagged: ubuntu:22.04
# Deleted: sha256:def456ghi789abcdef456ghi789abcdef456ghi789abcdef456ghi789
9.3.2 容器管理命令
# 运行容器
docker run -d --name web -p 80:80 nginx:alpine
# 输出结果:
# 1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef

# 查看运行中的容器
docker ps
# 输出结果:
# CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS         PORTS                NAMES
# 1234567890ab   nginx:alpine   "/docker-entrypoint.…"   5 seconds ago   Up 4 seconds   0.0.0.0:80->80/tcp   web

# 查看所有容器(包括已停止)
docker ps -a
# 输出结果:
# CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS                     PORTS     NAMES
# 1234567890ab   nginx:alpine   "/docker-entrypoint.…"   2 minutes ago   Up 2 minutes               0.0.0.0:80->80/tcp   web
# abcdef123456   ubuntu:22.04   "/bin/bash"              5 days ago      Exited (0) 5 days ago                test

# 查看容器日志
docker logs web
# 输出结果:
# 2023/10/10 10:00:00 [notice] 1#1: start worker processes
# 2023/10/10 10:00:00 [notice] 1#1: start worker process 2
# 2023/10/10 10:00:00 [notice] 1#1: start worker process 3

# 进入容器
docker exec -it web /bin/sh
# 进入容器后执行:
/ # nginx -v
# 输出结果:
# nginx version: nginx/1.23.0
# 按Ctrl+P+Q退出容器而不停止

# 停止容器
docker stop web
# 输出结果:web

# 启动已停止的容器
docker start web
# 输出结果:web

# 删除容器
docker rm web
# 输出结果:web
9.3.3 系统管理命令
# 查看Docker系统信息
docker info
# 输出结果:
# Containers: 1
#  Running: 1
#  Paused: 0
#  Stopped: 0
# Images: 5
# Server Version: 24.0.0
# Storage Driver: overlay2
#  Backing Filesystem: xfs
#  Supports d_type: true
#  Native Overlay Diff: true
#  userxattr: false
# Logging Driver: json-file
# Cgroup Driver: systemd
# ...

# 查看磁盘使用情况
docker system df
# 输出结果:
# TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
# Images          5         3         1.2GB     600MB (50%)
# Containers      3         2         120MB     0B (0%)
# Local Volumes   2         1         200MB     100MB (50%)
# Build Cache     0         0         0B        0B

# 清理无用资源
docker system prune -a
# 输出结果:
# WARNING! This will remove:
#   - all stopped containers
#   - all networks not used by at least one container
#   - all dangling images
#   - all build cache
# Total reclaimed space: 450MB

十、企业级实战案例

10.1 场景1:基础运行Web应用

# 运行Nginx容器
docker run -d \
  --name nginx-prod \
  -p 80:80 \
  -p 443:443 \
  -v /data/nginx/html:/usr/share/nginx/html:ro \
  -v /data/nginx/logs:/var/log/nginx \
  -v /data/nginx/conf.d:/etc/nginx/conf.d:ro \
  --restart=always \
  --memory="512m" \
  --cpus="1.0" \
  nginx:1.23.0-alpine
# 输出结果:
# 容器ID: 1234567890abcdef1234567890abcdef

# 验证运行状态
curl -I http://localhost
# 输出结果:
# HTTP/1.1 200 OK
# Server: nginx/1.23.0
# Date: Tue, 10 Oct 2023 10:00:00 GMT
# Content-Type: text/html

10.2 场景2:数据库容器部署

# 创建数据卷
docker volume create mysql-data
# 输出结果:mysql-data

# 运行MySQL容器
docker run -d \
  --name mysql-prod \
  -p 3306:3306 \
  -v mysql-data:/var/lib/mysql \
  -v /data/mysql/conf.d:/etc/mysql/conf.d:ro \
  -e MYSQL_ROOT_PASSWORD=your_secure_password \
  -e MYSQL_DATABASE=appdb \
  -e MYSQL_USER=appuser \
  -e MYSQL_PASSWORD=apppassword \
  --restart=always \
  --memory="1g" \
  --cpus="2.0" \
  mysql:8.0
# 输出结果:
# 容器ID: abcdef1234567890abcdef1234567890

# 连接测试
docker exec -it mysql-prod mysql -u root -p
# 输入密码后进入MySQL
# mysql> SHOW DATABASES;
# 输出结果:
# +--------------------+
# | Database           |
# +--------------------+
# | appdb              |
# | information_schema |
# | mysql              |
# | performance_schema |
# | sys                |
# +--------------------+

10.3 场景3:多容器编排部署

# 创建自定义网络
docker network create app-network
# 输出结果:app-network

# 运行Redis容器
docker run -d \
  --name redis \
  --network app-network \
  -v redis-data:/data \
  -e REDIS_PASSWORD=redispass \
  --memory="256m" \
  redis:7-alpine redis-server --requirepass redispass

# 运行应用容器
docker run -d \
  --name app \
  --network app-network \
  -p 8080:8080 \
  -e REDIS_HOST=redis \
  -e REDIS_PASSWORD=redispass \
  --restart=always \
  --memory="512m" \
  myapp:1.0.0

10.4 场景4:生产环境监控

# 部署Prometheus监控
docker run -d \
  --name prometheus \
  -p 9090:9090 \
  -v /data/prometheus:/prometheus \
  -v /data/prometheus.yml:/etc/prometheus/prometheus.yml:ro \
  --restart=always \
  prom/prometheus:latest

# 部署Grafana可视化
docker run -d \
  --name grafana \
  -p 3000:3000 \
  -v grafana-data:/var/lib/grafana \
  -e GF_SECURITY_ADMIN_PASSWORD=admin123 \
  --restart=always \
  grafana/grafana:latest

十一、Dockerfile示例

11.1 基础Dockerfile

# 使用Alpine Linux基础镜像
FROM alpine:3.18

# 设置维护者信息
LABEL maintainer="devops@example.com"
LABEL version="1.0"
LABEL description="Nginx web server"

# 设置环境变量
ENV NGINX_VERSION=1.23.0 \
    NGINX_HOME=/usr/share/nginx

# 设置工作目录
WORKDIR /usr/share/nginx/html

# 安装Nginx
RUN apk add --no-cache nginx && \
    mkdir -p /run/nginx && \
    chown -R nginx:nginx /var/lib/nginx && \
    rm -rf /var/cache/apk/*

# 复制配置文件
COPY nginx.conf /etc/nginx/nginx.conf
COPY default.conf /etc/nginx/conf.d/default.conf

# 复制静态文件
COPY html/ ./

# 暴露端口
EXPOSE 80
EXPOSE 443

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD wget --quiet --tries=1 --spider http://localhost/ || exit 1

# 切换非root用户运行
USER nginx

# 启动命令
CMD ["nginx", "-g", "daemon off;"]

11.2 构建镜像

# 构建镜像
docker build -t my-nginx:1.0 .
# 输出结果:
# Sending build context to Docker daemon  5.632kB
# Step 1/12 : FROM alpine:3.18
#  ---> 7e01a0d0a1dc
# Step 2/12 : LABEL maintainer="devops@example.com"
#  ---> Running in abc123def456
# Removing intermediate container abc123def456
#  ---> 1234567890ab
# ... 构建完成
# Successfully built abc123def456
# Successfully tagged my-nginx:1.0

十二、Docker-Compose示例

12.1 完整docker-compose.yml

version: '3.8'

services:
  # Nginx Web服务
  nginx:
    image: nginx:1.23.0-alpine
    container_name: nginx-prod
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/html:/usr/share/nginx/html:ro
      - ./nginx/logs:/var/log/nginx
      - ./nginx/conf.d:/etc/nginx/conf.d:ro
    environment:
      - NGINX_PORT=80
      - TZ=Asia/Shanghai
    networks:
      - frontend
    depends_on:
      - app
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 256M
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

  # 应用服务
  app:
    build: 
      context: .
      dockerfile: Dockerfile
      args:
        NODE_ENV: production
    image: myapp:1.0.0
    container_name: app-prod
    restart: unless-stopped
    expose:
      - "3000"
    volumes:
      - app-data:/app/data
      - /etc/localtime:/etc/localtime:ro
    environment:
      - DATABASE_URL=postgresql://user:pass@db:5432/mydb
      - REDIS_URL=redis://redis:6379/0
      - NODE_ENV=production
    networks:
      - frontend
      - backend
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 5s
      retries: 3
    env_file:
      - .env.production

  # 数据库服务
  db:
    image: postgres:15-alpine
    container_name: postgres-prod
    restart: unless-stopped
    environment:
      POSTGRES_USER: admin
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_DB: mydb
    volumes:
      - postgres-data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    networks:
      - backend
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U admin"]
      interval: 10s
      timeout: 5s
      retries: 5
    ports:
      - "5432:5432"

  # Redis缓存
  redis:
    image: redis:7-alpine
    container_name: redis-prod
    command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
    volumes:
      - redis-data:/data
    networks:
      - backend
    ports:
      - "6379:6379"

networks:
  frontend:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/16
  backend:
    driver: bridge

volumes:
  app-data:
    driver: local
  postgres-data:
    driver: local
  redis-data:
    driver: local

12.2 Compose操作命令

# 启动服务
docker-compose up -d
# 输出结果:
# Creating network "project_frontend" with driver "bridge"
# Creating network "project_backend" with driver "bridge"
# Creating volume "project_app-data" with driver "local"
# Creating volume "project_postgres-data" with driver "local"
# Creating volume "project_redis-data" with driver "local"
# Creating redis-prod  ... done
# Creating postgres-prod ... done
# Creating app-prod    ... done
# Creating nginx-prod  ... done

# 查看服务状态
docker-compose ps
# 输出结果:
#     Name                Command              State                    Ports
# ------------------------------------------------------------------------------------
# app-prod       docker-entrypoint.sh node ...  Up      3000/tcp
# nginx-prod     /docker-entrypoint.sh ngin ... Up      0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
# postgres-prod  docker-entrypoint.sh postgres  Up      0.0.0.0:5432->5432/tcp
# redis-prod     docker-entrypoint.sh redis ... Up      0.0.0.0:6379->6379/tcp

# 查看日志
docker-compose logs -f nginx
# 输出结果(实时日志):
# nginx-prod  | 2023/10/10 10:00:00 [notice] 1#1: start worker processes
# nginx-prod  | 2023/10/10 10:00:00 [notice] 1#1: start worker process 2

# 停止服务
docker-compose stop
# 输出结果:
# Stopping nginx-prod  ... done
# Stopping app-prod    ... done
# Stopping postgres-prod ... done
# Stopping redis-prod  ... done

# 停止并删除所有资源
docker-compose down
# 输出结果:
# Stopping nginx-prod  ... done
# Removing nginx-prod  ... done
# Removing app-prod    ... done
# Removing postgres-prod ... done
# Removing redis-prod  ... done
# Removing network project_frontend
# Removing network project_backend
# Removing volume project_app-data
# Removing volume project_postgres-data
# Removing volume project_redis-data

十三、常见错误与避坑指南

13.1 错误1:命令执行失败

错误现象

docker docker
# 输出结果:
# docker: 'docker' is not a docker command.
# See 'docker --help'

错误原因:命令语法错误,重复了"docker"关键字

正确做法

docker run nginx
# 或者查看帮助
docker --help

13.2 错误2:权限问题

错误现象

docker ps
# 输出结果:
# Got permission denied while trying to connect to the Docker daemon socket

错误原因:当前用户没有docker组权限

解决方法

# 将用户加入docker组
sudo usermod -aG docker $USER
# 输出结果:无输出

# 重新登录或刷新组权限
newgrp docker
# 输出结果:无输出

# 验证权限
docker ps
# 输出结果:
# CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

13.3 错误3:端口冲突

错误现象

docker run -p 80:80 nginx
# 输出结果:
# docker: Error response from daemon: driver failed programming external connectivity on endpoint: 
# Bind for 0.0.0.0:80 failed: port is already allocated.

错误原因:端口80已被占用

解决方法

# 查看占用端口的进程
sudo lsof -i :80
# 输出结果:
# COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
# nginx   1234 root    6u  IPv4  12345      0t0  TCP *:http (LISTEN)

# 修改端口映射
docker run -p 8080:80 nginx
# 输出结果:容器ID

13.4 错误4:数据丢失

错误现象

docker run --name test redis
# 容器删除后数据丢失
docker rm test
docker run --name test2 redis
# 新容器没有之前的数据

错误原因:没有使用数据卷持久化

解决方法

# 创建数据卷
docker volume create redis-data
# 输出结果:redis-data

# 使用数据卷
docker run -d \
  --name redis \
  -v redis-data:/data \
  redis:alpine
# 输出结果:容器ID

13.5 错误5:镜像拉取失败

错误现象

docker pull nginx:latest
# 输出结果:
# Error response from daemon: Get "https://registry-1.docker.io/v2/": 
# net/http: request canceled while waiting for connection

错误原因:网络问题或镜像不存在

解决方法

# 1. 配置镜像加速器
# 编辑/etc/docker/daemon.json
{
  "registry-mirrors": [
    "https://docker.mirrors.ustc.edu.cn"
  ]
}

# 2. 重启Docker
sudo systemctl restart docker

# 3. 重新拉取
docker pull nginx:latest

十四、性能优化指南

14.1 镜像优化

# 多阶段构建示例
# 构建阶段
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

# 运行时阶段
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY . .

# 优化前镜像大小:约1.2GB
# 优化后镜像大小:约300MB

14.2 容器资源限制

# 运行容器时设置资源限制
docker run -d \
  --name optimized-app \
  --memory="512m" \
  --memory-swap="1g" \
  --cpus="1.5" \
  --cpu-quota=150000 \
  --cpu-period=100000 \
  --blkio-weight=500 \
  --pids-limit=100 \
  nginx:alpine

14.3 存储驱动优化

# 检查当前存储驱动
docker info | grep "Storage Driver"
# 输出结果:
# Storage Driver: overlay2
#  Backing Filesystem: xfs
#  Supports d_type: true
#  Native Overlay Diff: true

# 推荐使用overlay2 + xfs文件系统
# 创建xfs文件系统
mkfs.xfs -f /dev/sdb1
# 挂载
mount /dev/sdb1 /var/lib/docker

十五、安全最佳实践

15.1 最小权限原则

# Dockerfile中创建非root用户
RUN addgroup -g 1000 -S appuser && \
    adduser -S -D -H -u 1000 -h /app -s /sbin/nologin -G appuser appuser
USER appuser

15.2 容器安全配置

# 运行容器时增加安全限制
docker run -d \
  --read-only \
  --tmpfs /tmp \
  --cap-drop=ALL \
  --cap-add=NET_BIND_SERVICE \
  --security-opt=no-new-privileges \
  nginx:alpine

15.3 镜像安全扫描

# 使用Docker Scan扫描镜像
docker scan nginx:latest
# 输出结果:
# ✗ High severity vulnerability found in apt/libapt-pkg6.0
# Description: Buffer Overflow
# Info: https://snyk.io/vuln/SNYK-DEBIAN11-APT-1916438

十六、企业级最佳实践

16.1 镜像规范

  1. 使用官方镜像:优先使用Docker官方镜像
  2. 固定版本标签:不使用latest标签
  3. 定期更新:定期更新基础镜像
  4. 多阶段构建:减小镜像体积

16.2 容器规范

  1. 资源限制:所有容器必须设置资源限制
  2. 健康检查:必须配置健康检查
  3. 日志管理:配置日志轮转
  4. 重启策略:生产环境使用always

16.3 安全规范

  1. 非root运行:容器内使用非root用户
  2. 只读文件系统:尽可能使用只读挂载
  3. 网络隔离:使用自定义网络
  4. 密钥管理:使用Docker Secrets管理密钥

16.4 运维规范

  1. 监控告警:监控容器资源使用
  2. 日志收集:集中收集容器日志
  3. 备份策略:定期备份数据卷
  4. 灾难恢复:制定容器恢复预案

十七、总结

总结概览

  1. Docker 24.0+CentOS 7/8、Ubuntu 20.04/22.04、Windows 10/11 上的完整安装步骤
  2. 企业级配置:daemon.json详细配置与优化
  3. 实战部署:从单容器到多容器编排
  4. 故障排查:常见错误分析与解决方法
  5. 最佳实践:安全、性能、运维规范

核心要点

  • 始终使用官方仓库安装最新稳定版
  • 生产环境必须配置资源限制和健康检查
  • 遵循最小权限和安全原则
  • 使用数据卷持久化重要数据

Docker安装部署是容器化之旅的第一步,正确的安装和配置是后续所有工作的基础。

更多推荐