Docker 24.0+ 安装部署:全平台CentOS 7/8、Ubuntu 20.04/22.04、Windows 10/11
一、一次版本不匹配引发的生产事故
上周,团队在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 应用场景
-
开发环境标准化
# 新成员加入,只需执行 git clone project docker-compose up -d # 开发环境就绪,无需手动安装任何依赖 -
微服务架构部署
# 每个微服务独立容器 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 -
CI/CD流水线
# Jenkins Pipeline中使用Docker stage('Build') { sh 'docker build -t app:$BUILD_NUMBER .' } stage('Test') { sh 'docker run app:$BUILD_NUMBER npm test' } -
生产环境容器化
# 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 系统要求检查
- Windows 10/11 64位:专业版、企业版或教育版
- 开启Hyper-V和容器功能(Windows功能)
- 开启WSL2(Windows Subsystem for Linux 2)
- 至少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配置
-
Settings → General:
- 启用
Start Docker Desktop when you log in - 启用
Use Docker Compose V2
- 启用
-
Settings → Resources:
- CPU:推荐4核+
- Memory:推荐8GB+
- Swap:推荐1GB
-
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-root | Docker数据存储路径 | /var/lib/docker | 大容量磁盘分区 |
log-driver | 日志驱动 | json-file | json-file |
log-opts.max-size | 单日志文件最大大小 | -1(无限制) | 10m(生产环境) |
storage-driver | 存储驱动 | 自动选择 | overlay2 |
registry-mirrors | 镜像加速器 | 无 | 国内镜像源 |
live-restore | 守护进程重启保持容器 | false | true(生产) |
max-concurrent-downloads | 最大并发下载数 | 3 | 3-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 镜像规范
- 使用官方镜像:优先使用Docker官方镜像
- 固定版本标签:不使用latest标签
- 定期更新:定期更新基础镜像
- 多阶段构建:减小镜像体积
16.2 容器规范
- 资源限制:所有容器必须设置资源限制
- 健康检查:必须配置健康检查
- 日志管理:配置日志轮转
- 重启策略:生产环境使用always
16.3 安全规范
- 非root运行:容器内使用非root用户
- 只读文件系统:尽可能使用只读挂载
- 网络隔离:使用自定义网络
- 密钥管理:使用Docker Secrets管理密钥
16.4 运维规范
- 监控告警:监控容器资源使用
- 日志收集:集中收集容器日志
- 备份策略:定期备份数据卷
- 灾难恢复:制定容器恢复预案
十七、总结
总结概览:
- Docker 24.0+ 在 CentOS 7/8、Ubuntu 20.04/22.04、Windows 10/11 上的完整安装步骤
- 企业级配置:daemon.json详细配置与优化
- 实战部署:从单容器到多容器编排
- 故障排查:常见错误分析与解决方法
- 最佳实践:安全、性能、运维规范
核心要点:
- 始终使用官方仓库安装最新稳定版
- 生产环境必须配置资源限制和健康检查
- 遵循最小权限和安全原则
- 使用数据卷持久化重要数据
Docker安装部署是容器化之旅的第一步,正确的安装和配置是后续所有工作的基础。
更多推荐
所有评论(0)