Docker入门及基本概念

让我们从最基础的概念开始逐步理解。假设你已经准备好了docker 环境。

第一步,让我们先通过实际操作来看看当前系统中的镜像(images)和容器(containers)状态:

bash 复制代码
docker images    # 查看所有镜像
docker ps -a     # 查看所有容器(包括未运行的)

输出结果:

bash 复制代码
REPOSITORY                 TAG       IMAGE ID       CREATED       SIZE
linqiu1199/trae2api        v1.0.1    0d72ae59193b   4 days ago    20.4MB
rustdesk/rustdesk-server   latest    9227b43758be   4 weeks ago   12.8MB
mysql                      latest    3e34946bc4c4   4 weeks ago   797MB
hello-world                latest    74cc54e27dc4   4 weeks ago   10.1kB
redis                      latest    fa310398637f   6 weeks ago   117MB
[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE                             COMMAND                   CREATED        STATUS                    PORTS                                                  NAMES
4fa63eb76d16   linqiu1199/trae2api:v1.0.1        "./main"                  16 hours ago   Up 3 hours                0.0.0.0:17080->17080/tcp, :::17080->17080/tcp          trae2api
25e6b341f3cb   rustdesk/rustdesk-server:latest   "hbbs"                    10 days ago    Exited (0) 18 hours ago                                                          hbbs
239edf233492   rustdesk/rustdesk-server:latest   "hbbr"                    10 days ago    Exited (0) 18 hours ago                                                          hbbr
84fbae57a78c   redis                             "docker-entrypoint.s..."   12 days ago    Up 3 hours                0.0.0.0:6379->6379/tcp, :::6379->6379/tcp              redis
48b0ee678e43   mysql                             "docker-entrypoint.s..."   12 days ago    Up 3 hours                0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   mysql
[root@localhost ~]# 

镜像(Images)和容器(Containers)的关系:

举一个很好的例子 - redis:

txt 复制代码
镜像:您系统中有一个 redis (latest) 镜像,大小为 117MB
容器:基于这个镜像运行了一个容器(ID: 84fbae57a78c),正在运行中(Status: Up 3 hours)

让我们通过一个实际操作来理解这个关系。我建议执行以下命令来创建另一个 redis 容器:

bash 复制代码
docker run --name redis-test -d redis

执行这个命令,然后再次运行:

bash 复制代码
docker ps -a
  • 同一个镜像可以创建多个容器
  • 每个容器都是镜像的运行实例

有点类似与JavaSE 中的 类和对象,让我用面向对象的概念来进一步解释:

镜像(Image) => 类(Class)

  • 是一个模板
  • 包含了所有必要的代码和依赖
  • 是只读的
  • 可以被多次使用来创建不同的容器
  • 不能直接运行,需要实例化成容器

容器(Container) => 对象(Object)

  • 是镜像的运行实例
  • 有自己的状态和数据
  • 可以启动、停止、删除
  • 多个容器可以基于同一个镜像创建
  • 每个容器都是独立的运行环境

让我们通过实际操作来验证这个概念:

bash 复制代码
# 基于同一个 redis 镜像再创建一个容器,但使用不同的名字和端口
docker run --name redis-test2 -d -p 6380:6379 redis
  • 执行这个命令的时候,你是否会有这样的疑惑呢?由于之前在Docker装过了redis,在主机端口,设置了6380, 这样避开了6379 端口。是考虑到的,但是 容器端口 还是 6379 这样合理吗?

答: 这里的关键点是:

  1. 容器是完全隔离 的环境,每个容器都有自己的网络空间
  2. 不同容器 可以使用相同的内部端口(6379)
  3. 宿主机的端口不能重复

然后查看结果:

bash 复制代码
docker ps -a | grep redis
txt 复制代码
oot@localhost ~]# docker ps -a | grep redis
a31ec1598cf9   redis                             "docker-entrypoint.s..."   9 seconds ago   Up 8 seconds              0.0.0.0:6380->6379/tcp, :::6380->6379/tcp              redis-test2
84fbae57a78c   redis                             "docker-entrypoint.s..."   12 days ago     Up 4 hours                0.0.0.0:6379->6379/tcp, :::6379->6379/tcp              redis
[root@localhost ~]# 

执行后,应该能看到多个 redis 容器(对象),但它们都是基于同一个 redis 镜像(类)创建的。

docker run & docker start

  1. 先查看当前系统中所有的容器状态,包括已停止的容器。请执行以下命令:
bash 复制代码
docker ps -a 
bash 复制代码
[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE                             COMMAND                   CREATED         STATUS                    PORTS                                                  NAMES
a31ec1598cf9   redis                             "docker-entrypoint.s..."   5 minutes ago   Up 5 minutes              0.0.0.0:6380->6379/tcp, :::6380->6379/tcp              redis-test2
4fa63eb76d16   linqiu1199/trae2api:v1.0.1        "./main"                  16 hours ago    Up 4 hours                0.0.0.0:17080->17080/tcp, :::17080->17080/tcp          trae2api
25e6b341f3cb   rustdesk/rustdesk-server:latest   "hbbs"                    10 days ago     Exited (0) 18 hours ago                                                          hbbs
239edf233492   rustdesk/rustdesk-server:latest   "hbbr"                    10 days ago     Exited (0) 18 hours ago                                                          hbbr
84fbae57a78c   redis                             "docker-entrypoint.s..."   12 days ago     Up 4 hours                0.0.0.0:6379->6379/tcp, :::6379->6379/tcp              redis
48b0ee678e43   mysql                             "docker-entrypoint.s..."   12 days ago     Up 4 hours                0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   mysql
[root@localhost ~]#
  1. 下一步,我们将使用 docker run 命令来创建一个新的容器。请执行以下命令:
bash 复制代码
docker run --name new-redis -d -p 6381:6379 redis

这个命令会基于 redis 镜像创建并启动一个新的容器。

执行完后,请再次运行 docker ps -a,是否看到了一个名为 "new-redis" 的新容器,以及它的状态如何。

bash 复制代码
AINER ID   IMAGE                             COMMAND                   CREATED         STATUS                    PORTS                                                  NAMES
751466ad80a1   redis                             "docker-entrypoint.s..."   3 seconds ago   Up 2 seconds              0.0.0.0:6381->6379/tcp, :::6381->6379/tcp              new-redis
a31ec1598cf9   redis                             "docker-entrypoint.s..."   7 minutes ago   Up 7 minutes              0.0.0.0:6380->6379/tcp, :::6380->6379/tcp              redis-test2
4fa63eb76d16   linqiu1199/trae2api:v1.0.1        "./main"                  16 hours ago    Up 4 hours                0.0.0.0:17080->17080/tcp, :::17080->17080/tcp          trae2api
25e6b341f3cb   rustdesk/rustdesk-server:latest   "hbbs"                    10 days ago     Up About a minute                                                                hbbs
239edf233492   rustdesk/rustdesk-server:latest   "hbbr"                    10 days ago     Exited (0) 18 hours ago                                                          hbbr
84fbae57a78c   redis                             "docker-entrypoint.s..."   12 days ago     Up 4 hours                0.0.0.0:6379->6379/tcp, :::6379->6379/tcp              redis
48b0ee678e43   mysql                             "docker-entrypoint.s..."   12 days ago     Up 4 hours                0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   mysql
[root@localhost ~]# 

总结一下关键点:

  1. docker start (我们用在 hbbs 容器上):

    1. 启动了一个已存在但停止的容器
    2. 没有创建新的容器
    3. 容器 ID 和名称保持不变

  1. docker run (我们用来创建 new-redis):

    1. 创建了一个全新的容器 (ID: 751466ad80a1)
    2. 自动启动了这个新容器
    3. 使用了我们指定的名称 (new-redis)
    4. 映射了新的端口 (6381)

下一步,让我们更深入地理解这两个命令的使用场景。请尝试以下操作:

  1. 停止 new-redis 容器:
bash 复制代码
docker stop new-redis
  1. 然后尝试使用 docker run 再次创建一个同名的容器:
bash 复制代码
docker run --name new-redis -d -p 6381:6379 redis
bash 复制代码
[root@localhost ~]# docker run --name new-redis -d -p 6381:6379 redis
docker: Error response from daemon: Conflict. The container name "/new-redis" is already in use by container "751466ad80a1e95003b7df5370ec4657c95e6dab87b927e7ea01104ed8aa2081". You have to remove (or rename) that container to be able to reuse that name.
See 'docker run --help'.
[root@localhost ~]#
  • docker run 尝试创建一个新容器,但失败了。
  • 错误原因是容器名 "new-redis" 已经被使用。
  • Docker建议我们要么移除旧容器,要么重命名,才能重用这个名字。

这个结果进一步说明了 docker rundocker start 的区别:

  • docker run 总是尝试创建新容器,即使容器已停止。
  • docker start 则用于启动已存在的容器。

下一步,让我们尝试使用 docker start 来启动已停止的 new-redis 容器:

bash 复制代码
docker start new-redis


成功运行!!

相关推荐
yuxb736 分钟前
Docker学习笔记(二):镜像与容器管理
笔记·学习·docker
xuxie1339 分钟前
SpringBoot文件下载(多文件以zip形式,单文件格式不变)
java·spring boot·后端
星期天要睡觉44 分钟前
Linux 综合练习
linux·运维·服务器
重生成为编程大王1 小时前
Java中的多态有什么用?
java·后端
666和7771 小时前
Struts2 工作总结
java·数据库
saynaihe1 小时前
proxmox8升级到proxmox9
linux·运维·服务器
中草药z1 小时前
【Stream API】高效简化集合处理
java·前端·javascript·stream·parallelstream·并行流
Delphi菜鸟1 小时前
docker 部署RustDesk服务
运维·docker·容器
野犬寒鸦1 小时前
力扣hot100:搜索二维矩阵 II(常见误区与高效解法详解)(240)
java·数据结构·算法·leetcode·面试
Orchestrator_me1 小时前
CentOS交换区处理
linux·运维·centos