问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Docker入门教程:从基本概念到实践操作

创作时间:
2025-01-22 03:33:07
作者:
@小白创作中心

Docker入门教程:从基本概念到实践操作

Docker 是目前非常流行的容器化技术,可以帮助开发者轻松地打包、部署和运行应用程序。本文将从Docker的基本概念入手,通过具体的操作示例,帮助读者掌握Docker的基本使用方法。

Docker 安装

其他操作系统的安装方法可以在Docker官网找到,这里就不详细介绍了。需要注意的是,本文的所有示例都是在Ubuntu系统上完成的。

安装完成后,如果想要让普通用户也能使用docker命令,可以将当前用户添加到docker组中:

sudo usermod -aG docker your-user

请将your-user替换为你的用户名,并在执行完成后重新登录以使更改生效。

要检查Docker是否安装成功,可以使用以下命令查看版本信息:

docker --version

或者执行以下两个命令进行测试:

docker version
docker info

Docker 基本组成

Docker的主要组成部分包括:

  • image:这是一个只读模板,用于创建container。可以将其类比为面向对象编程中的类(class)。
  • container:这是Docker的核心组件,一个独立、隔离的运行环境,包含了执行应用程序所需的所有组件。
  • Docker registry:类似于GitHub,用于存储和分发images。公开的registry如Docker Hub,也可以创建私有registry。

Docker 指令:启动容器

在正确安装Docker后,可以使用以下指令启动一个容器:

docker container run -it node:20 /bin/bash

解释一下这个命令的各个部分:

  • docker container run:启动一个新的容器。
  • -i--interactive:保持标准输入打开,以便与容器内的进程进行交互。
  • -t--tty:分配一个伪终端,并将其绑定到容器的标准输出。
  • node:20:用于启动容器的image名称。
  • /bin/bash:容器启动后要执行的命令。

执行完这行指令后,你会看到类似下图的画面:

其中4c9bee8fef4b是容器ID,用于区分不同的容器实例。此时你已经进入了容器的环境中,在这里执行node -v指令,会发现这个环境中已经安装了node,且版本是20.5.1。

在容器中执行ps aux会看到PID为1的进程就是我们刚刚指定的/bin/bash,这个信息非常重要,但我们在后面再详细讨论。

这里让我们做一个小测试:

  1. 在刚刚创建的容器中,创建一个文件,例如touch AAA.txt,建议完成后用ls确认一下。
  2. 开启另外一个命令窗口,同样再执行一次docker container run -it node:20 /bin/bash,然后进入了一个容器,执行ls看看,应该会看不到AAA.txt这个文件。

这个测试说明了container是一个独立的、隔离的环境,即使是从同一个image启动的多个容器,它们之间也是相互隔离的。

要查看当前正在运行的容器,可以使用以下指令:

docker container ls

Docker Image

在更深入讨论容器的其他操作之前,我们先来看看node:20这个image是从哪里来的。

当你第一次启动容器时,如果本地没有找到指定的image,Docker会自动从Docker Hub(默认的registry)拉取所需的image。例如,node:20这个image就是从Docker Hub的node仓库拉取的。

Docker Hub上有各种各样的image,非常实用。例如,如果你想启动一个MySQL服务,但又不想直接安装在自己的电脑上,就可以从Docker Hub上拉取一个MySQL的image。建议尽量使用官方提供的image,以确保安全性和可靠性。

在启动容器之前,也可以先用以下指令把image拉取好:

docker image pull node:18

这里补充一下tag的概念。在Docker image的命名中,冒号(:)前面的是名称,后面的是tag(image_name:tag_name)。Tag通常用来表示版本信息,但也可以用于其他用途。如果没有指定tag,Docker会默认使用latest作为tag。

要查看当前环境中已有的images,可以使用以下指令:

docker image ls

Image Layer

当我们从image启动一个container时,Docker会加载这个image作为只读层,并在其上添加一个可写层。所有在容器中的操作实际上都是在这个可写层中进行的。这就是为什么在第一个container中创建的AAA.txt文件在第二个container中看不到的原因。

Docker提供了一个指令,可以将容器的状态保存为一个新的image:

docker container commit CONTAINER_ID [Repository:[Tag]]

例如:

docker container commit 4c9bee8fef4b node:20-updated

这个新image会在原有image的基础上再加上一层,包含对容器所做的修改。当使用这个新image创建新的container时,就会包含这些修改。

Docker的智能之处在于,它不会重复存储相同的layer,这样可以节省大量磁盘空间。这也是为什么image需要设计为只读的原因,只读可以实现共享而不会互相影响。

要查看image的历史记录,可以使用以下指令:

docker image history node:20

其他Docker生命周期指令

node:20-updated创建出来的container中执行exit退出这个container,这时候如果执行docker container ls会发现,只剩下两个container,而刚刚退出的那个container已经看不到了:

但是,如果加上-a参数,就可以查看所有的container:

这是因为我们刚刚在启动container时,要它执行的命令是/bin/bash(且PID为1),而当我们下了exit指令时,是在退出这个bash,也就是退出了PID为1的这个process,既然主要的process已经停止执行了,这个container自然也就关闭了,我们之后再来讨论怎么让container持续执行。从这里也可以从Status这个栏位看到container已经退出多久。

这时候如果想要回到这个container里,可以通过docker container start CONTAINER_ID来回到这个container里:

docker container start只是重新启动这个container,执行后我们还是在本机中,如果要进入container中,可以通过exec来进入container中,基本上这个指令常用的参数,例如-it,跟docker container run的时候差不多,我们就先不讨论了。

docker container exec -it CONTAINER_ID /bin/bash

这时候我们一样再执行exit,然后再下docker container ls来检查,却会发现这个container还是活着的、跟刚刚不一样,我们通过docker container exec再进去一次,这次在里面执行一下ps aux

这时候我们可以看到有两个/bin/bash的process在运行,我们通过docker container exec所执行的/bin/bash其实是PID为26的这一个,所以当我们执行exit时,退出的是这一个bash,而PID为1的这个/bin/bash仍在执行中,所以这个container会持续存活。

docker container exec有一个用起来很像的指令docker container attach CONTINER_ID

attach这个指令一样会进入container中,用起来跟刚刚的docker container exec -it CONTAINER_ID效果很像,但如果进去后执行ps aux会发现只有一个/bin/bashprocess。你应该可以猜到,如果这时候执行了exit,会退出的是PID为1的/bin/bashprocess,进而退出这个container。此时再通过docker container ls或是docker container ls -a来确认,会发现这个container已经关闭了。所以,虽然attach也能进入这个container中,但我自己很少用,以免一不小心把container给关掉…

移除image和container

如果电脑中存有太多的image,会占用硬盘空间,因此建议定期清除用不到的image。要移除image,可以使用以下指令:

docker image rm IMAGE_ID

但是,如果image正在被某个container使用,那么在移除container之前,你是无法删除这个image的。要移除container,可以使用以下指令:

docker container rm CONTAINER_ID

结语

本次记录了Docker的基本组件与操作,主要讨论了Docker container的执行与一些基本操作。也许在做过这些练习与测试之后,你心里会有一大堆疑问,有的话是很棒的事情,但如一开始所说的,我想先记录一些基本的操作,先会基本的运用,有点感觉后,然后再慢慢深入讨论。

下次仍旧会是基础篇,让我们来讨论怎么让container间可以彼此沟通,然后再来讨论我最喜欢的Dockerfile,这可是我个人认为docker可以如此成功的重要因素之一。

指令整理

这里把本文讨论过的指令都整理起来,方便大家复习与查找,另外也会列出旧版的指令对照,推荐使用新版的指令,虽然较长,但具有一致的结构,非常好学!

# 查看docker版本
docker --version
docker version

# 查看docker系统信息
docker info

# 从node:20 image启动一个docker container并开启输出入
docker container run -it node:20 /bin/bash
# 旧版指令
# docker run -it node:20 /bin/bash

# 查看目前正在运行中的container
docker container ls
# 旧版指令
# docker ps

# 查看全部的container,包括已经停止的。 (a -> all)
docker container ls -a
# 旧版指令
# docker ps -a

# 从DockerHub上拉下版本为18的node image
docker image pull node:18
# 旧版指令
# docker pull node:18

# 查看目前环境中的docker images
docker image ls
# 旧版指令
# docker images

# 用container id为4c9bee8fef4b的container
# 创建一个叫做node:20-updated的image
docker container commit 4c9bee8fef4b node:20-updated
# 旧版指令
# docker commit 4c9bee8fef4b node:20-updated

# 查看node:20这个image的历史
docker image history node:20
# 旧版指令
# docker history node:20

# 停止4c9bee8fef4b这个container
docker container stop 4c9bee8fef4b
# 旧版指令
# docker stop 4c9bee8fef4b

# 启动4c9bee8fef4b这个container
docker container start 4c9bee8fef4b
# 旧版指令
# docker start 4c9bee8fef4b

# 在4c9bee8fef4b这个container中执行/bin/bash这个命令,并且开启输出入
# 因为是执行/bin/bash又开启了输出入,所以就像是「进入」了这个container中
docker container exec -it 4c9bee8fef4b /bin/bash
# 旧版指令
# docker exec -it 4c9bee8fef4b /bin/bash

# 移除4c9bee8fef4b这个container
docker container rm 4c9bee8fef4b
# docker rm 4c9bee8fef4b

# 移除所有停止的containers
docker container prune -f

# 移除node:18这个image
# 移除image前要先移除用这个image启动的containers
docker image rm node:18
# 旧版指令
# docker rmi node:18
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号