Docker (一)

Docker (一)

1. Docker 是什么

  • Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口。它是目前最流行的 Linux 容器解决方案。
  • Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样

Docker主要解决的问题

  • 保证程序运行环境的一致性;
  • 降低配置开发环境、生产环境的复杂度和成本;
  • 实现程序的快速部署和分发。

2.Linux 容器

inux 容器不是模拟一个完整的操作系统,而是对进程进行隔离。或者说,在正常进程的外面套了一个保护层。对于容器里面的进程来说,它接触到的各种资源都是虚拟的,从而实现与底层系统的隔离

特点

  • 启动快
  • 资源占用少
  • 体积小

核心内核技术

1.命名空间

  • 作用:隔离进程的视图,使每个容器拥有独立的系统资源标识。

2.控制组

  • 作用:限制和分配容器的物理资源(CPU、内存、磁盘 I/O、网络带宽等)。

3.容器文件系统

  • 联合文件系统:通过分层存储实现镜像的轻量共享。
  • 写时复制:容器启动时仅复制修改的文件,减少镜像体积。

3.docker和KVM

  • 启动时间

    • Docker秒级启动
    • KVM分钟级启动
  • 轻量级 容器镜像通常以M为单位,虚拟机以G为单位,容器资源占用小,要比虚拟要部署更快速

    • 容器共享宿主机内核,系统级虚拟化,占用资源少,容器性能基本接近物理机
    • 虚拟机需要虚拟化一些设备,具有完整的OS,虚拟机开销大,因而降低性能,没有容器性能好
  • 安全性

    • 由于共享宿主机内核,只是进程隔离,因此隔离性和稳定性不如虚拟机,容器具有一定权限访问宿主机内核,存在一下安全隐患
  • 使用要求

    • KVM基于硬件的完全虚拟化,需要硬件CPU虚拟化技术支持
    • 容器共享宿主机内核,可运行在主机的Linux的发行版,不用考虑CPU是否支持虚拟化技术

4. Docker 体系结构

4.1Docker 架构图

  • containerd 是一个守护进程,使用runc管理容器,向Docker Engine提供接口
  • shim 只负责管理一个容器
  • runC是一个轻量级工具,只用来运行容器
lua 复制代码
+------------------+       +-------------------+       +-------------------+
|                  |       |                   |       |                   |
|   Docker Client  | <---> | Docker Daemon   | <---> | Docker Registry   |
| (CLI, API)       |       | (dockerd + runc)  |       | (Docker Hub, etc) |
+------------------+       +---------+---------+       +---------+---------+
                                                      |       |
                                                      |       v
                                                      | +-------------------+
                                                      | | Docker Images     |
                                                      | +---------+---------+
                                                      |           |
                                                      |           v
                                                      | +---------+---------+
                                                      | | Containers        |
                                                      | +---------+---------+
                                                      |           |
                                                      |           v
                                                      | +---------+---------+
                                                      | | Docker Engine     |
                                                      | | (containerd, runc,Shim)|
                                                      +-------------------+

4.2核心组件详解

1. Docker 客户端(Docker Client)
  • 功能:用户与 Docker 交互的入口(CLI 或 API)。
  • 工具docker 命令行工具。
  • 交互 :向 Docker Daemon 发送指令(如 docker rundocker build)。
2. Docker 守护进程(Docker Daemon)
  • 功能:后台服务,负责容器生命周期管理。

  • 组成:

    • dockerd:主守护进程,监听客户端请求,调用底层工具。
    • containerd:OCI 标准的容器运行时,管理容器的完整生命周期(创建、启动、停止)。
    • runc:轻量级 OCI 运行时,直接与 Linux 内核交互(创建 Namespaces、Cgroups 等)。
  • 交互:从 Registry 拉取镜像,构建容器文件系统,通过 containerd 启动容器。

3. Docker 镜像(Docker Image)
  • 功能:只读模板,包含应用代码、依赖和配置。
  • 存储 :基于 UnionFS 的分层结构(如 OverlayFS),支持复用和共享。
  • 示例ubuntu:20.04 镜像包含 Ubuntu 系统的基础环境。
4. Docker 容器(Docker Container)
  • 功能:镜像的运行实例,具有可写层(读写隔离)。
  • 隔离机制:通过 Namespaces(进程、网络、文件系统等)和 Cgroups 实现资源隔离。
  • 生命周期 :由 docker run 创建,依赖 containerd 和 runc 启动。
5. Docker Registry
  • 功能:镜像仓库,用于存储和分发镜像。

  • 类型:

    • 公有仓库:Docker Hub、GitHub Container Registry。
    • 私有仓库:Harbor、AWS ECR、阿里云 ACR。

6.Docker底层使用的技术

  • Docker使用Go语言实现。

  • Docker利用linux内核的几个特性来实现功能:

    • 利用linux的命名空间(Namespaces)

    • 利用linux控制组(Control Groups)

    • 利用linux的联合文件系统(Union File Systems)

      这也就意味着Docker只能在linux上运行。

      在windows、MacOS上运行Docker,其实本质上是借助了虚拟化技术,然后在linux虚拟机上运行的Docker程序。

  • 容器格式( Container Format ):

    • Docker Engine将namespace、cgroups、UnionFS进行组合后的一个package,就是一个容器格式(Container Format)。Docker通过对这个package中的namespace、cgroups、UnionFS进行管理控制实现容器的创建和生命周期管理。
    • 容器格式(Container Format)有多种,其中Docker目前使用的容器格式被称为libcontainer。
  • Namespaces(命名空间):为Docker容器提供操作系统层面的隔离

    • 进程号隔离:每一个容器内运行的第一个进程,进程号总是从1开始起算
    • 网络隔离:容器的网络与宿主机或其他容器的网络是隔离的、分开的,也就是相当于两个网络
    • 进程间通隔离:容器中的进程与宿主机或其他容器中的进程是互相不可见的,通信需要借助网络
    • 内核以及系统版本号隔离:容器查看内核版本号或者系统版本号时,查看的是容器的,而非宿主机的
    • 文件系统挂载隔离: 容器拥有自己单独的工作目录
  • Control Groups(控制组-cgroups):为Docker容器提供硬件层面的隔离

  • Union File Systems(联合文件系统--UnionFS):利用分层(layer)思想管理镜像和容器

7.docker安装

1 .Linux安装

kotlin 复制代码
// 安装依赖和存储驱动相关包
yum install -y yum-utils device-mapper-persistent-data lvm2

作用:安装 Docker 所需的依赖包和存储驱动支持。

  • yum-utils :提供 yum-config-manager 等工具,用于管理 YUM 仓库。
  • device-mapper-persistent-datalvm2 : 这些是 ​设备映射器(Device Mapper)​ 存储驱动的依赖项。Docker 默认使用 overlay2 存储驱动,但如果系统不支持 overlay2(例如旧版内核),可能会回退到 devicemapper
arduino 复制代码
// 添加 Docker 阿里云 官方仓库
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
  • 作用:将 Docker 的官方软件仓库添加到 CentOS 的 YUM 源列表中。

    • 此仓库包含 Docker CE(社区版)、Docker CLI 和容器运行时 containerd.io 的 RPM 包。
    • --add-repo :直接通过 URL 添加仓库,无需手动下载 .repo 文件。
python 复制代码
# 清除缓存并重试安装
sudo yum clean all
sudo yum makecache
sudo yum install -y docker-ce
  • 作用:从已添加的 Docker 官方仓库中安装以下组件:

    • docker-ce:Docker 社区版引擎(核心组件,负责容器管理)。

    2.启动

    bash 复制代码
    systemctl start docker
    systemctl enable docker  # 开机自启

    3. 查看docker版本

    复制代码
    docker version
    docker info

    4. docker 镜像加速器

    1. 配置国内镜像源
    bash 复制代码
    # 创建配置文件(若不存在)
    sudo tee /etc/docker/daemon.json <<-'EOF'
    {
      "registry-mirrors": [
        "https://mirrors.tencent.com",
        "https://image.cloudlayer.icu",
         "https://hub.fast360.xyz",
         "https://docker-0.unsee.tech"
         
      ]
    }
    EOF
    2. 重启服务并验证
    perl 复制代码
    sudo systemctl daemon-reload
    sudo systemctl restart docker
    docker info | grep -A5 "Registry Mirrors"  # 应显示配置的镜像源

    二、解决内核警告(网络功能关键)

    docker info 警告

    vbnet 复制代码
    docker info | grep "Registry Mirrors"
    WARNING: bridge-nf-call-iptables is disabled
    WARNING: bridge-nf-call-ip6tables is disabled
     
    1. 启用内核参数
    bash 复制代码
    # 永久生效
    cat <<EOF | sudo tee -a /etc/sysctl.conf
    net.bridge.bridge-nf-call-iptables=1
    net.bridge.bridge-nf-call-ip6tables=1
    EOF
    sudo sysctl -p
    2. 加载内核模块
    bash 复制代码
    sudo modprobe br_netfilter
    echo "br_netfilter" | sudo tee /etc/modules-load.d/br_netfilter.conf

    Docker架构

2. Docker版本

Docker-CE和Docker-EE

  • Docker-CE指Docker社区版,由社区维护和提供技术支持,为免费版本,适合个人开发人员和小团队使用。
  • Docker-EE指Docker企业版,为收费版本,由售后团队和技术团队提供技术支持,专为企业开发和IT团队而设计。
  • 相比Docker-EE,增加一些额外功能,更重要的是提供了更安全的保障。
  • 此外,Docker的发布版本分为Stable版和Edge版,区别在于前者是按季度发布的稳定版(发布慢),后者是按月发布的边缘版(发布快)。
  • 通常情况下,Docker-CE足以满足我们的需求。后面学习主要针对Docker-CE进行学习

8. 镜像

  • Docker 把应用程序及其依赖,打包在 image 文件里面。只有通过这个文件,才能生成 Docker 容器

  • image 文件可以看作是容器的模板

  • Docker 根据 image 文件生成容器的实例

  • 同一个 image 文件,可以生成多个同时运行的容器实例

  • 镜像不是一个单一的文件,而是有多层

  • 容器其实就是在镜像的最上面加了一层读写层,在运行容器里做的任何文件改动,都会写到这个读写层里。如果容器删除了,最上面的读写层也就删除了,改动也就丢失了

  • 我们可以通过docker history <ID/NAME> 查看镜像中各层内容及大小,

  • 用户既可以使用 docker load 来导入镜像存储文件到本地镜像库,也可以使用 docker import 来导入一个容器快照到本地镜像库

  • 这两者的区别在于容器(import)快照文件将丢弃所有的历史记录和元数据信息(即仅保存容器当时的快照状态),而镜像(load)存储文件将保存完整记录,体积也要大

    命令 含义 语法 案例
    ls 查看全部镜像 docker image ls
    search 查找镜像 docker search [imageName]
    history 查看镜像历史 docker history [imageName]
    inspect 显示一个或多个镜像详细信息 docker inspect [imageName]
    pull 拉取镜像 docker pull [imageName]
    push 推送一个镜像到镜像仓库 docker push [imageName]
    rmi 删除镜像 docker rmi [imageName] docker image rmi 2
    prune 移除未使用的镜像,没有标记或补任何容器引用 docker image prune docker image prune
    tag 标记本地镜像,将其归入某一仓库 docker tag [OPTIONS] IMAGE[:TAG] [REGISTRYHOST/](#命令 含义 语法 案例 ls 查看全部镜像 docker image ls search 查找镜像 docker search [imageName] history 查看镜像历史 docker history [imageName] inspect 显示一个或多个镜像详细信息 docker inspect [imageName] pull 拉取镜像 docker pull [imageName] push 推送一个镜像到镜像仓库 docker push [imageName] rmi 删除镜像 docker rmi [imageName] docker image rmi 2 prune 移除未使用的镜像,没有标记或补任何容器引用 docker image prune docker image prune tag 标记本地镜像,将其归入某一仓库 docker tag [OPTIONS] IMAGE[:TAG] REGISTRYHOST/NAME[:TAG] docker tag centos:7 zhangrenyang/centos:v1 export 将容器文件系统作为一个tar归档文件导出到STDOUT docker export [OPTIONS] CONTAINER docker export -o hello-world.tar b2712f1067a3 import 导入容器快照文件系统tar归档文件并创建镜像 docker import [OPTIONS] file/URL/- [REPOSITORY[:TAG]] docker import hello-world.tar save 将指定镜像保存成tar文件 docker save [OPTIONS] IMAGE [IMAGE...] docker save -o hello-world.tar hello-world:latest load 加载tar文件并创建镜像 docker load -i hello-world.tar build 根据Dockerfile构建镜像 docker build [OPTIONS] PATH / URL / - docker build -t zf/ubuntu:v1 . "#")NAME[:TAG] docker tag centos:7 zhangrenyang/centos:v1
    export 将容器文件系统作为一个tar归档文件导出到STDOUT docker export [OPTIONS] CONTAINER docker export -o hello-world.tar b2712f1067a3
    import 导入容器快照文件系统tar归档文件并创建镜像 docker import [OPTIONS] file/URL/- [REPOSITORY[:TAG]] docker import hello-world.tar
    save 将指定镜像保存成tar文件 docker save [OPTIONS] IMAGE [IMAGE...] docker save -o hello-world.tar hello-world:latest
    load 加载tar文件并创建镜像 docker load -i hello-world.tar
    build 根据Dockerfile构建镜像 docker build [OPTIONS] PATH / URL / - docker build -t zf/ubuntu:v1 .
  • 作用:搜索Docker Hub(镜像仓库)上的镜像。

  • 命令格式:docker search [OPTIONS] TERM

  • 命令参数(OPTIONS):

    • --filter filter 根据提供的格式筛选结果
    • --format string 利用GO语言的format格式化输出结果
    • -- limit int 展示最大的结果数,默认25个
    • --not-trunc 内容全部显示
bash 复制代码
# 搜索 centos
docker search  centos
# 搜索 hello-world
 docker search  hello-world

2. 镜像查看 - docker images/docker image ls

  • 作用:列出本地镜像

  • 命令格式:docker image ls [OPTIONS] [REPOSITORY[:TAG]]

  • 命令参数(OPTIONS)

    • -a, --all 展示所有镜像(默认隐藏底层的镜像)
    • --no-trunc 不缩率显示
    • -q , --quiet 只显示镜像ID
bash 复制代码
# 查看所有本地存储的镜像。
docker images
REPOSITORY      TAG       IMAGE ID       CREATED         SIZE
mongo           6.0       4f3dbc8f2775   5 weeks ago     747MB
bitnami/redis   latest    f7f358889b53   2 months ago    145MB
mysql           8.3.0     6f343283ab56   14 months ago   632MB
​
# 查看指定
docker images mysql
​
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
mysql        8.3.0     6f343283ab56   14 months ago   632MB
​

3. 镜像下载 - docker pull

  • 作用:下载远程仓库(如Docker Hub)中的镜像

  • 命令格式:docker pull [OPTIONS] NAME[:TAG|@DIGEST]

  • 命令参数(OPTIONS)

    • -a, --all-tags 下载所有符合给定tag的镜像
bash 复制代码
# 下载 centos
docker  pull centos
​
# 下载 hello-world
 docker pull  hello-world

4. 镜像删除 - docker rmi/docker image rm

  • 作用:将本地的一个或多个镜像删除

  • 命令格式:docker rmi [OPTIONS] IMAGE [IMAGE...]

  • 命令参数(OPTIONS)

    • -f, --force 强制删除
makefile 复制代码
# 删除 hello-world
 docker rmi  hello-world
​
Untagged: hello-world:latest
 
# 如果有多个版本hello-world 会删除 最新的hello-world
# docker rmi  hello-world 等价 docker rmi  hello-world:last

5. 镜像保存备份 -- docker save

  • 作用:将本地的一个或多个镜像打包保存成本地tar文件(输出到STDOUT)

  • 命令格式:docker save [OPTIONS] IMAGE [IMAGE...]

  • 命令参数(OPTIONS)

    • -o, --output string 指定写入的文件名和路径
bash 复制代码
# 语法 备份    mysql (redis_image.tar文件名称)
docker save -o redis_image.tar mysql
​
​

6. 镜像备份导入 - docker load

  • 作用:将save命令打包的镜像导入本地镜像库中

  • 命令格式:docker load [OPTIONS]

  • 命令参数(OPTIONS)

    • -i, --input string 指定要打入的文件
    • -q, --quiet 不打印导入过程信息
arduino 复制代码
#
docker load -i redis_image.tar

7. 镜像重命名 -- docker tag

  • 作用:对本地镜像的NAME、TAG进行重命名,并新产生一个命名后镜像
  • 命令格式:docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
bash 复制代码
# 重命名
# 如果centos名称有,就把原有的镜像指向新名称,如果原有名称none 就会覆盖
docker tag centos  centos:7.4

8. 镜像详细信息 -- docker image inspect/docker inspect

  • 作用:查看本地一个或多个镜像的详细信息

  • 命令格式:docker image inspect [OPTIONS] IMAGE [IMAGE...]

  • 命令参数(OPTIONS)

    • -f, --format string 利用特定Go语言的format格式输出结果
    • -q, --quiet 不打印导入过程信息
arduino 复制代码
​
docker image inspect centos

9. 容器

什么是容器

容器(Container):容器是一种轻量级、可移植、并将应用程序进行的打包的技术,使应用程序可以在几乎任何地方以相同的方式运行.

  • docker run 命令会从 image 文件,生成一个正在运行的容器实例。
  • docker container run命令具有自动抓取 image 文件的功能。如果发现本地没有指定的 image 文件,就会从仓库自动抓取
  • image 文件生成的容器实例,本身也是一个文件,称为容器文件.
  • 关闭容器并不会删除容器文件,只是容器停止运行
命令 含义 案例
run 从镜像运行一个容器 docker run ubuntu /bin/echo 'hello-world'
ls 列出容器 docker container ls
inspect 显示一个或多个容器详细信息 docker inspect
attach 要attach上去的容器必须正在运行,可以同时连接上同一个container来共享屏幕 docker attach [OPTIONS] CONTAINER docker attach 6d1a25f95132
stats 显示容器资源使用统计 docker container stats
top 显示一个容器运行的进程 docker container top
update 更新一个或多个容器配置 docker update -m 500m --memory-swap -1 6d1a25f95132
port 列出指定的容器的端口映射 docker run -d -p 8080:80 nginx docker container port containerID
ps 查看当前运行的容器 docker ps -a -l
kill [containerId] 终止容器(发送SIGKILL ) docker kill [containerId]
rm [containerId] 删除容器 docker rm [containerId]
start [containerId] 启动已经生成、已经停止运行的容器文件 docker start [containerId]
stop [containerId] 终止容器运行 (发送 SIGTERM ) docker stop [containerId] docker container stop $(docker container ps -aq)
logs [containerId] 查看 docker 容器的输出 docker logs [containerId]
exec [containerId] 进入一个正在运行的 docker 容器执行命令 docker container exec -it f6a53629488b /bin/bash
cp [containerId] 从正在运行的 Docker 容器里面,将文件拷贝到本机 docker container cp f6a53629488b:/root/root.txt .
commit [containerId] 根据一个现有容器创建一个新的镜像 docker commit -a "zhufeng" -m "mynginx" a404c6c174a2 mynginx:v1

cloud.tencent.com.cn/developer/a...

1. 容器创建 -- docker create

  • 作用:利用镜像创建出一个Created 状态的待启动容器

  • 命令格式:docker create [OPTIONS] IMAGE [COMMAND] [ARG...]

  • 命令参数(OPTIONS)

    • -t, --tty 分配一个伪TTY,也就是分配虚拟终端
    • -i, --interactive 即使没有连接,也要保持STDIN打开
    • --name 为容器起名,如果没有指定将会随机产生一个名称
  • 命令参数(COMMAND\ARG):

    • COMMAND 表示容器启动后,需要在容器中执行的命令,如ps、ls 等命令
    • RG 表示执行 COMMAND 时需要提供的一些参数,如ps 命令的 aux、ls命令的-a等等
lua 复制代码
# 创建容器名为wo-mysql, 表示容器启动后执行ls命令 参数 -a
 docker  create  --name wo-mysql  mysql:8.3.0  ls -a
 
# docker-entrypoint.sh 是 Docker 容器启动时执行的脚本,通常用于初始化容器的环境设置 
    NAMES         IMAGE               COMMAND                           STATUS
  mysql:8.3.0   mysql:8.3.0         "docker-entrypoint.sh ls -a"        Created
  
  
  
 #-t(--tty)表示为容器分配一个伪终端(TTY),通常用于与容器进行交互式会话。
 #(--interactive)表示以交互模式启动容器,允许你在容器内执行命令。如果你在命令行启动 MySQL 容器时加上 -ti,它意味着你可以在容器内交互
 docker create -ti --name wo-mysql2 mysql:8.3.0

2. 容器启动 -- docker start

  • 作用:将一个或多个处于创建状态或关闭状态的容器启动起来

  • 命令格式:docker start [OPTIONS] CONTAINER [CONTAINER...]

  • 命令参数(OPTIONS)

    • -a, --attach 将当前shell的 STDOUT/STDERR 连接到容器上
    • -i, --interactive 将当前shell的 STDIN连接到容器上
ini 复制代码
​
# 容器启动 wo-mysql
docker start wo-mysql
​
# STATUS(容器状态) 从 Created(创建)到很快Exited(退出)状态,是因为ls -a 命令很快执行完了
   IMAGE           COMMAND                           STATUS                          NAMES
  mysql:8.3.0     "docker-entrypoint.s..."      Exited (0) 24 seconds ago             wo-mysql
  
  # 容器启动 -a 把容器输出结果,展示到当前shell
 C:\Users\sunmeng>docker start -a wo-mysql
.
..
.dockerenv
bin
boot
dev
docker-entrypoint-initdb.d
etc
home
lib
lib64
media
​
#执行容器wo-mysql2 通过创建时候传入  -ti,允许你在容器内执行命令mysql
docker start -a  wo-mysql2
2025-05-27 02:21:04+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.3.0-1.el8 started.
2025-05-27 02:21:05+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2025-05-27 02:21:05+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.3.0-1.el8 started.
2025-05-27 02:21:05+00:00 [ERROR] [Entrypoint]: Database is uninitialized and password option is not specified
    You need to specify one of the following as an environment variable:
    # 指定一个密码来初始化 root 用户(推荐)
    - MYSQL_ROOT_PASSWORD
    # 允许使用空密码(不推荐,除非你知道自己在做什么)
    - MYSQL_ALLOW_EMPTY_PASSWORD
    - MYSQL_RANDOM_ROOT_PASSWORD
​
​

3. 容器创建并启动 -- docker run

  • 作用:利用镜像创建并启动一个容器

  • 命令格式:docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

  • 命令参数(OPTIONS)

    • -t, --tty 分配一个伪TTY,也就是分配虚拟终端
    • -i, --interactive 即使没有连接,也要保持STDIN打开
    • --name 为容器起名,如果没有指定将会随机产生一个名称
    • --rm 当容器退出运行后,自动删除容器
  • 命令参数(COMMAND\ARG):

    • COMMAND 表示容器启动后,需要在容器中执行的命令,如ps、ls 等命令
    • RG 表示执行 COMMAND 时需要提供的一些参数,如ps 命令的 aux、ls命令的-a等等
ini 复制代码
​
# docker run  ==  docker create + docker start -a   前台模式
# docker run -d  ===  docker create + docker start  后台模式
# 创建并启动 mysql:8.3.0
docker run mysql:8.3.0
2025-05-27 02:39:07+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.3.0-1.el8 started.
2025-05-27 02:39:07+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2025-05-27 02:39:07+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.3.0-1.el8 started.
2025-05-27 02:39:07+00:00 [ERROR] [Entrypoint]: Database is uninitialized and password option is not specified
    You need to specify one of the following as an environment variable:
    - MYSQL_ROOT_PASSWORD
    - MYSQL_ALLOW_EMPTY_PASSWORD
    - MYSQL_RANDOM_ROOT_PASSWORD
# 创建时候没有传名称,所以docker随机生成名称 vibrant_hawking
docker ps -a
  IMAGE           COMMAND                   CREATED             STATUS                       NAMES
  mysql:8.3.0     "docker-entrypoint.s..."   8 seconds ago       Exited (1) 6 seconds ago    vibrant_hawking
​

4. 容器关闭 -- docker stop

  • 作用:关闭一个或多个处于暂停状态或者运行状态的容器

  • 命令格式:docker stop [OPTIONS] CONTAINER [CONTAINER...]

  • 命令参数(OPTIONS)

    • -t, --time int 关闭前,等待的时间,单位秒(默认 10s)
bash 复制代码
 # 现在后台运行 b-express-mysql-1容器  端口3306  
  IMAGE         COMMAND                  STATUS             PORTS                               NAMES
mysql:8.3.0  "docker-entrypoint.s..."   Up 21 seconds  0.0.0.0:3306->3306/tcp, 33060/tcp   b-express-mysql-1
​
# 关闭 b-express-mysql-1
docker stop  b-express-mysql-1

5. 容器终止 -- docker kill

  • 作用:强制并立即关闭一个或多个处于暂停状态或者运行状态的容器

  • 命令格式:docker kill [OPTIONS] CONTAINER [CONTAINER...]

  • 命令参数(OPTIONS)

    • -s, --signal string 指定发送给容器的关闭信号 (默认"KILL"信号)
bash 复制代码
# 常用场景:当容器无法响应 SIGTERM,或者在某些情况下需要立即停止容器时使用
docker kill <container_name_or_id>
特性 docker stop docker kill
停止方式 向容器发送 SIGTERM 信号,允许容器优雅停止 向容器发送 SIGKILL 信号,立即强制停止容器
容器响应 容器可以捕获并处理 SIGTERM 信号,有时间进行清理 容器无法捕获 SIGKILL 信号,立即终止容器
使用场景 优雅关闭容器,常用于生产环境 强制停止容器,常用于容器无法正常停止时
默认超时 默认 10 秒(可以通过 -t 参数调整) 无超时,立即强制停止容器

6. 容器暂停 -- docker pause

  • 作用:暂停一个或多个处于运行状态的容器
  • 命令格式:docker pause CONTAINER [CONTAINER...]
bash 复制代码
# 运行容器 b-express-mysql-1
docker start b-express-mysql-1
# 查看运行容器 
docker  ps
# 状态运行
 IMAGE         COMMAND                        STATUS                      NAMES
 mysql:8.3.0   "docker-entrypoint.s..."      Up 10 seconds        b-express-mysql-1
# 容器暂停 
docker pause b-express-mysql-1
# 状态暂停
docker  ps
   IMAGE         COMMAND                      STATUS                    NAMES
 mysql:8.3.0   "docker-entrypoint.s..."     Up 36 seconds (Paused)    b-express-mysql-1

7. 容器取消暂停 -- docker unpause

  • 作用:取消一个或多个处于暂停状态的容器,恢复运行
  • 命令格式:docker unpause CONTAINER [CONTAINER...]
bash 复制代码
​
# 取消暂停
docker unpause  <container_name_or_id>

8 . 容器删除 -- docker container rm

  • 作用:删除一个或多个容器

  • 命令格式:docker container rm [OPTIONS] CONTAINER [CONTAINER...]

  • 命令参数(OPTIONS)

    • -f, --force 强行删除容器(会使用 SIGKILL信号)
    • -v, --volumes 同时删除绑定在容器上的数据卷
    bash 复制代码
    # 删除
    docker rm <container_name_or_id>
    #强制删除 
    docker rm -f <container_name_or_id>

9 .容器重启 -- docker restart

  • 作用:重启一个或多个处于运行状态、暂停状态、关闭状态或者新建状态的容器 该命令相当于stop和start命令的结合

  • 命令格式:docker restart [OPTIONS] CONTAINER [CONTAINER...]

  • 命令参数(OPTIONS)

    • -t, --time int 重启前,等待的时间,单位秒(默认 10s
    bash 复制代码
    #基本语法
    docker restart <container_name_or_id>

10 .容器日志信息 -- docker logs

  • 作用:查看容器的日志信息

  • 命令格式:docker logs [OPTIONS] CONTAINER

  • 命令参数(OPTIONS)

    • --details 显示日志的额外信息
    • -f, --follow 动态跟踪显示日志信息
    • --since string 只显示某事时间节点之后的
    • -t, --timestamps 显示timestamps时间
    • --until string 只显示某事时间节点之前的
  • 注意: 容器日志中记录的是容器主进程的输出STDOUT\STDERR

11. 容器连接 -- docker attach

  • 作用:将当前终端的STDIN、STDOUT、STDERR绑定到正在运行的容器的主进程上实现连接

  • 命令格式:docker attach [OPTIONS] CONTAINER

  • 命令参数(OPTIONS)

    • --no-stdin 不绑定STDIN
bash 复制代码
# 基本语法
docker attach <container_name_or_id>
# 1. 连接到标准输入输出:连接后,你会看到容器内正在运行的应用程序的输出,并且你可以通过输入来与容器进行交互(如果容器内有交互式命令)
# 2. 退出连接:如果你希望退出容器的连接,你可以按 Ctrl + C 或 Ctrl + P 然后 Ctrl + Q,以便返回到主机终端,但不会停止容器

13. 容器中执行新命令 -- docker exec

  • 作用:在容器中运行一个命令

  • 命令格式:docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

  • 命令参数(OPTIONS)

    • -d, --detach 后台运行命令
    • -i, --interactive 即使没连接容器,也将当前的STDIN绑定上
    • -t, --tty 即使没连接容器,也将当前的STDIN绑定上
    • -w, --workdir string 指定在容器中的工作目录
    • -e, --env list 设置容器中运行时的环境变量
bash 复制代码
# 进入 MySQL 容器的命令行(b-express-mysql-1 容器名称)
docker exec -it b-express-mysql-1 bash

10. 容器和镜像

1. 容器和镜像关系

特性 镜像 (Images) 容器 (Containers)
状态 静态,只读 动态,可写
存储 分层存储 镜像层+可写层
生命周期 持久存在 运行(临时)/停止(保留状态)
变更 不可变更 可修改文件系统和配置
类比 软件的安装程序 软件正在运行
创建方式 构建、提交、拉取 基于镜像运行
占用资源 磁盘空间 CPU、内存、磁盘
数量关系 一个镜像可以创建多个容器 多个容器可共享同一镜像

2. 容器提交 -- docker commit

  • 作用:根据容器生成一个新的镜像

  • 命令格式:docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

  • 命令参数(OPTIONS)

    • -a, --author string 作者
    • -c, --change list 为创建的镜像加入Dockerfile命令
    • -m, --message string 提交信息,类似git commit -m
    • --p, --pause 提交时暂停容器 (default true)
python 复制代码
​
# 运行容器 centos
 docker run  -dti  centos  bash
# 查看容器
 docker   ps -a
# 查看结果
CONTAINER ID   IMAGE     COMMAND   CREATED          STATUS          PORTS     NAMES
aa562037700b   centos    "bash"    26 seconds ago   Up 25 seconds             sweet_stonebraker
#在容器centos 安装net-tools工具包
[root@lavm-zo7f3xq5c6 ~]# docker exec aa56 yum install -y net-tools
​
# 查看容器centos  ifconfig
 docker exec aa56   ifconfig
 # 输出结果
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
        RX packets 11333  bytes 17635289 (16.8 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 7759  bytes 474305 (463.1 KiB)
# 容器提交
 docker commit -m 'install net-tools' aa56  coentos-net:v1.0
sha256:b46656d01be91ced0fbc7154dac16e7f25af906be00adb044d1af087b8a811f5
​
# 查看镜像
 docker images
 # 查看结果
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
coentos-net   v1.0      b46656d01be9   6 minutes ago   342MB
nginx         latest    be69f2940aaf   6 weeks ago     192MB
centos        latest    9f38484d220f   6 years ago     202MB
# coentos-net 生成的镜像
​
​
 

3. 容器导出 -- docker export

  • 作用:将容器当前的文件系统导出成一个tar文件

  • 命令格式:docker export [OPTIONS] CONTAINER

  • 命令参数(OPTIONS)

    • -o, --output string 指定写入的文件,默认是STDOUT
bash 复制代码
# 查看容器
 docker ps -a
# 查看容器结果
CONTAINER ID   IMAGE     COMMAND   CREATED          STATUS          PORTS     NAMES
aa562037700b   centos    "bash"    44 minutes ago   Up 44 minutes             sweet_stonebraker
# 容器导出
 docker  export -o net-tools-image.tar  aa56
 # 查看目录
 ls
# 查看目录结果
anaconda-ks.cfg  net-tools-image.tar
​
​

4. 容器打包的导入 -- docker import

  • 作用:从一个tar文件中导入内容创建一个镜像

  • 命令格式:ddocker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]

  • 命令参数(OPTIONS)

    • -c, --change list 为创建的镜像加入Dockerfile命令
    • -m, --message string 导入时,添加提交信息
arduino 复制代码
#导入
docker  import -m  '(import) install net-tools' net-tools-image.tar  centos-netv2:1.0
​
[root@lavm-zo7f3xq5c6 ~]# docker images
REPOSITORY     TAG       IMAGE ID       CREATED          SIZE
centos-netv2   1.0       6d0baed20aad   6 seconds ago    319MB
coentos-net    v1.0      b46656d01be9   50 minutes ago   342MB
nginx          latest    be69f2940aaf   6 weeks ago      192MB
centos         latest    9f38484d220f   6 years ago      202MB
​

5.commit和import对比

核心对比

特性 docker commit docker import
输入源 正在运行的容器 文件系统压缩包(.tar 等)
输出 带历史层的新镜像 单层基础镜像
保留元数据 ✅ (CMD, ENV, EXPOSE 等) ❌ (需手动指定)
分层结构 ✅ (新增层叠加在原镜像之上) ❌ (整个文件系统作为单一层)

如何选择?

  • 需要保留完整构建历史或团队协作时,优先使用 docker commit
  • 仅需迁移文件系统或快速生成轻量镜像时,使用 docker import

6. 深入理解Docker容器与镜像

1. 镜像的Layer

Docker 镜像采用分层存储结构,每个层(Layer)都是只读的文件系统快照。这种设计是 Docker 的核心优化之一。

关键特性

  • 写时复制(Copy-on-Write) 当容器修改文件时,Docker 从镜像层复制文件到容器层(读写层),原始镜像层保持不变。
  • 层堆叠结构 镜像由多个层堆叠而成,底层是基础镜像(如 Alpine)
ini 复制代码
# 查看镜像分层
docker image inspect nginx:alpine --format='{{.RootFS.Layers}}'
  • 共享复用 多个镜像可共享基础层(如 alpine 层),节省磁盘空间。

分层示例 (以 python:3.9 镜像为例):

yaml 复制代码
​
Layer 4: pip install -r requirements.txt  # 应用依赖层(只读)
Layer 3: COPY app.py /app/              # 代码层(只读)
Layer 2: RUN apt-get install gcc        # 编译工具层(只读)
Layer 1: FROM debian:buster-slim        # 基础操作系统层(只读)
2.容器的Layer

容器在运行时依赖于镜像的分层结构,但添加了独有的可写层,这是容器动态性的核心

1. 容器分层结构

一个运行中的容器由两部分组成:

scss 复制代码
┌───────────────────────────────┐
│        容器实例 (Container)      │
├───────────────────────────────┤
│   ╔═════════════════════════╗  │
│   ║   可写层 (容器层)        ║  │ ← 容器运行时创建,存储所有修改
│   ║   (Container Layer)     ║  │
│   ╚═════════════════════════╝  │
│   ┌──────────────────────────┐ │
│   │      镜像层 (只读)        │ │ 
│   │   (Image Layers)         │ │ ← 来自基础镜像和应用镜像
│   └──────────────────────────┘ │
└───────────────────────────────┘
2. 容器层的核心特性
特性 说明
位置 位于所有镜像层之上(堆叠结构的最顶层)
读写权限 唯一可写层,所有文件修改(增删改)均发生在此层
生命周期 随容器创建而生成,随容器删除而销毁(docker rm 会删除此层)
存储驱动 由 Docker 配置的存储驱动管理(如 Overlay2、AUFS、Btrfs)
写时复制 (CoW) 首次修改文件时,从镜像层复制文件到容器层,原始镜像层保持不变
数据隔离 每个容器拥有独立的容器层,互不影响
3. 容器层的工作机制

文件修改场景(写时复制示例)

  1. 读取文件

    • 容器直接读取镜像层中的文件(无需复制)。
  2. 修改文件

    • 若修改镜像层中的文件 A,Docker 先将 A 复制到容器层,再修改容器层中的副本。
    • 原始镜像层的 A 保持不变。
  3. 删除文件

    • 在容器层创建 白障文件(whiteout file)标记删除,隐藏镜像层中的文件。
  4. 创建文件

    • 直接在容器层生成新文件。
4. 容器与镜像的底层关系

关键技术:联合文件系统(UnionFS) Docker 使用 Overlay2/AUFS 等联合文件系统将多层文件合并为单一视图:

  • 镜像层(Lower Dir) 只读的基础层,来自镜像。
  • 容器层(Upper Dir) 可写层,存储容器修改。
  • 合并视图(Merged Dir) 呈现给容器的统一文件系统(/ 目录)
bash 复制代码
# 1. 创建容器
docker run -d --name test nginx:alpine
​
# 2. 查看联合挂载点
docker inspect test --format='{{.GraphDriver.Data}}'
​
# 输出示例:
{
  "LowerDir": "/var/lib/docker/overlay2/xx...xx/diff",
  "MergedDir": "/var/lib/docker/overlay2/xx...xx/merged",
  "UpperDir": "/var/lib/docker/overlay2/xx...xx/diff",
  "WorkDir": "/var/lib/docker/overlay2/xx...xx/work"
}
5. 容器的运行机制

当执行 docker run 时发生的过程:

步骤 1:文件系统准备
  1. 从镜像加载所有只读层
  2. 创建容器专属读写层(Upper Dir)
  3. 通过 UnionFS 挂载合并视图(Merged Dir)
步骤 2:运行时配置
  • 命名空间隔离(Namespace) 创建独立的进程、网络、文件系统等视图。
  • 控制组资源限制(Cgroups) 分配 CPU/内存等资源配额。
  • 虚拟网络接口 创建 veth pair 连接容器与宿主机。
步骤 3:启动进程
  • 执行镜像中定义的 ENTRYPOINT/CMD(如 /docker-entrypoint.sh nginx
  • 进程成为容器的 PID 1(init 进程)
步骤 4:运行时交互
  • 所有文件写入操作发生在读写层(Upper Dir)
  • 日志输出到 STDERR/STDOUT(可通过 docker logs 捕获)
相关推荐
愚润求学6 分钟前
【Linux】POSIX信号量
linux·运维
局外人LZ13 分钟前
Docker轻松搭建Neo4j+APOC环境
docker·容器·neo4j
进阶的DW18 分钟前
新手小白使用VMware创建虚拟机安装Linux
java·linux·运维
jz_ddk23 分钟前
[zynq] Zynq Linux 环境下 AXI BRAM 控制器驱动方法详解(代码示例)
linux·运维·c语言·网络·嵌入式硬件
ZStack开发者社区37 分钟前
全球化2.0|云轴科技ZStack助力香港服务机构VMware替代
运维·云计算·政务
小黄人软件1 小时前
jenkins脚本查看及备份
运维·servlet·jenkins
字节高级特工1 小时前
【Linux篇】0基础之学习操作系统进程
linux·运维·服务器·数据结构·windows·学习·list
文牧之2 小时前
PostgreSQL 的扩展pg_prewarm
运维·数据库·postgresql
s_little_monster2 小时前
【Linux】网络--数据链路层--以太网
linux·运维·网络·经验分享·笔记·学习·计算机网络
belldeep5 小时前
WSL 安装 Debian 12 后,Linux 如何安装 curl , quickjs ?
linux·运维·debian·curl·quickjs